diff options
Diffstat (limited to 'drivers/net')
116 files changed, 2051 insertions, 1117 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index e19ca4bb7510..b2f71f79baaf 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -975,7 +975,7 @@ config ENC28J60_WRITEVERIFY config ETHOC tristate "OpenCores 10/100 Mbps Ethernet MAC support" - depends on NET_ETHERNET && HAS_IOMEM + depends on NET_ETHERNET && HAS_IOMEM && HAS_DMA select MII select PHYLIB select CRC32 diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index 2be49c817995..b25467ac895c 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c @@ -628,15 +628,6 @@ static int ep93xx_open(struct net_device *dev) if (ep93xx_alloc_buffers(ep)) return -ENOMEM; - if (is_zero_ether_addr(dev->dev_addr)) { - random_ether_addr(dev->dev_addr); - printk(KERN_INFO "%s: generated random MAC address " - "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x.\n", dev->name, - dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5]); - } - napi_enable(&ep->napi); if (ep93xx_start_hw(dev)) { @@ -877,6 +868,9 @@ static int ep93xx_eth_probe(struct platform_device *pdev) ep->mii.mdio_write = ep93xx_mdio_write; ep->mdc_divisor = 40; /* Max HCLK 100 MHz, min MDIO clk 2.5 MHz. */ + if (is_zero_ether_addr(dev->dev_addr)) + random_ether_addr(dev->dev_addr); + err = register_netdev(dev); if (err) { dev_err(&pdev->dev, "Failed to register netdev\n"); diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 04f63c77071d..3f4b4300f533 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -34,6 +34,7 @@ * * */ +#include <linux/capability.h> #include <linux/dma-mapping.h> #include <linux/module.h> #include <linux/kernel.h> @@ -1087,7 +1088,14 @@ static struct net_device * au1000_probe(int port_num) return NULL; } - if ((err = register_netdev(dev)) != 0) { + dev->base_addr = base; + dev->irq = irq; + dev->netdev_ops = &au1000_netdev_ops; + SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); + dev->watchdog_timeo = ETH_TX_TIMEOUT; + + err = register_netdev(dev); + if (err != 0) { printk(KERN_ERR "%s: Cannot register net device, error %d\n", DRV_NAME, err); free_netdev(dev); @@ -1208,12 +1216,6 @@ static struct net_device * au1000_probe(int port_num) aup->tx_db_inuse[i] = pDB; } - dev->base_addr = base; - dev->irq = irq; - dev->netdev_ops = &au1000_netdev_ops; - SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); - dev->watchdog_timeo = ETH_TX_TIMEOUT; - /* * The boot code uses the ethernet controller, so reset it to start * fresh. au1000_init() expects that the device is in reset state. diff --git a/drivers/net/b44.c b/drivers/net/b44.c index e046943ef29d..2a9132343b66 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -912,9 +912,6 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id) bp->istat = istat; __b44_disable_ints(bp); __napi_schedule(&bp->napi); - } else { - printk(KERN_ERR PFX "%s: Error, poll already scheduled\n", - dev->name); } irq_ack: diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index a80da0e14a52..3b79a225628a 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -259,6 +259,8 @@ struct be_adapter { u32 port_num; bool promiscuous; u32 cap; + u32 rx_fc; /* Rx flow control */ + u32 tx_fc; /* Tx flow control */ }; extern const struct ethtool_ops be_ethtool_ops; diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 89876ade5e33..28a0eda92680 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -243,15 +243,26 @@ static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage) int be_cmd_POST(struct be_adapter *adapter) { - u16 stage, error; + u16 stage; + int status, timeout = 0; - error = be_POST_stage_get(adapter, &stage); - if (error || stage != POST_STAGE_ARMFW_RDY) { - dev_err(&adapter->pdev->dev, "POST failed.\n"); - return -1; - } + do { + status = be_POST_stage_get(adapter, &stage); + if (status) { + dev_err(&adapter->pdev->dev, "POST error; stage=0x%x\n", + stage); + return -1; + } else if (stage != POST_STAGE_ARMFW_RDY) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(2 * HZ); + timeout += 2; + } else { + return 0; + } + } while (timeout < 20); - return 0; + dev_err(&adapter->pdev->dev, "POST timeout; stage=0x%x\n", stage); + return -1; } static inline void *embedded_payload(struct be_mcc_wrb *wrb) @@ -729,8 +740,8 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, /* Create an rx filtering policy configuration on an i/f * Uses mbox */ -int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac, - bool pmac_invalid, u32 *if_handle, u32 *pmac_id) +int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, + u8 *mac, bool pmac_invalid, u32 *if_handle, u32 *pmac_id) { struct be_mcc_wrb *wrb; struct be_cmd_req_if_create *req; @@ -746,8 +757,8 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac, be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req)); - req->capability_flags = cpu_to_le32(flags); - req->enable_flags = cpu_to_le32(flags); + req->capability_flags = cpu_to_le32(cap_flags); + req->enable_flags = cpu_to_le32(en_flags); req->pmac_invalid = pmac_invalid; if (!pmac_invalid) memcpy(req->mac_addr, mac, ETH_ALEN); diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index a86f917f85f4..e5f9676cf1bc 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -68,7 +68,7 @@ enum { #define CQE_STATUS_COMPL_MASK 0xFFFF #define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */ #define CQE_STATUS_EXTD_MASK 0xFFFF -#define CQE_STATUS_EXTD_SHIFT 0 /* bits 0 - 15 */ +#define CQE_STATUS_EXTD_SHIFT 16 /* bits 16 - 31 */ struct be_mcc_compl { u32 status; /* dword 0 */ @@ -720,8 +720,9 @@ extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, u32 if_id, u32 *pmac_id); extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id); -extern int be_cmd_if_create(struct be_adapter *adapter, u32 if_flags, u8 *mac, - bool pmac_invalid, u32 *if_handle, u32 *pmac_id); +extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, + u32 en_flags, u8 *mac, bool pmac_invalid, + u32 *if_handle, u32 *pmac_id); extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle); extern int be_cmd_eq_create(struct be_adapter *adapter, struct be_queue_info *eq, int eq_delay); diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index cda5bf2fc50a..f0fd95b43c07 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -323,10 +323,12 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) if (ecmd->autoneg != 0) return -EINVAL; + adapter->tx_fc = ecmd->tx_pause; + adapter->rx_fc = ecmd->rx_pause; - status = be_cmd_set_flow_control(adapter, ecmd->tx_pause, - ecmd->rx_pause); - if (!status) + status = be_cmd_set_flow_control(adapter, + adapter->tx_fc, adapter->rx_fc); + if (status) dev_warn(&adapter->pdev->dev, "Pause param set failed.\n"); return status; diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 6d5e81f7046f..876b357101fa 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1610,29 +1610,42 @@ static int be_open(struct net_device *netdev) status = be_cmd_link_status_query(adapter, &link_up); if (status) - return status; + goto ret_sts; be_link_status_update(adapter, link_up); + status = be_vid_config(adapter); + if (status) + goto ret_sts; + + status = be_cmd_set_flow_control(adapter, + adapter->tx_fc, adapter->rx_fc); + if (status) + goto ret_sts; + schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); - return 0; +ret_sts: + return status; } static int be_setup(struct be_adapter *adapter) { struct net_device *netdev = adapter->netdev; - u32 if_flags; + u32 cap_flags, en_flags; int status; - if_flags = BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_PROMISCUOUS | - BE_IF_FLAGS_MCAST_PROMISCUOUS | BE_IF_FLAGS_UNTAGGED | - BE_IF_FLAGS_PASS_L3L4_ERRORS; - status = be_cmd_if_create(adapter, if_flags, netdev->dev_addr, - false/* pmac_invalid */, &adapter->if_handle, - &adapter->pmac_id); + cap_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | + BE_IF_FLAGS_MCAST_PROMISCUOUS | + BE_IF_FLAGS_PROMISCUOUS | + BE_IF_FLAGS_PASS_L3L4_ERRORS; + en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | + BE_IF_FLAGS_PASS_L3L4_ERRORS; + + status = be_cmd_if_create(adapter, cap_flags, en_flags, + netdev->dev_addr, false/* pmac_invalid */, + &adapter->if_handle, &adapter->pmac_id); if (status != 0) goto do_none; - status = be_tx_queues_create(adapter); if (status != 0) goto if_destroy; @@ -1645,17 +1658,8 @@ static int be_setup(struct be_adapter *adapter) if (status != 0) goto rx_qs_destroy; - status = be_vid_config(adapter); - if (status != 0) - goto mccqs_destroy; - - status = be_cmd_set_flow_control(adapter, true, true); - if (status != 0) - goto mccqs_destroy; return 0; -mccqs_destroy: - be_mcc_queues_destroy(adapter); rx_qs_destroy: be_rx_queues_destroy(adapter); tx_qs_destroy: @@ -1906,6 +1910,10 @@ static void be_netdev_init(struct net_device *netdev) adapter->rx_csum = true; + /* Default settings for Rx and Tx flow control */ + adapter->rx_fc = true; + adapter->tx_fc = true; + netif_set_gso_max_size(netdev, 65535); BE_SET_NETDEV_OPS(netdev, &be_netdev_ops); @@ -2055,6 +2063,10 @@ static int be_hw_up(struct be_adapter *adapter) if (status) return status; + status = be_cmd_reset_function(adapter); + if (status) + return status; + status = be_cmd_get_fw_ver(adapter, adapter->fw_ver); if (status) return status; @@ -2108,10 +2120,6 @@ static int __devinit be_probe(struct pci_dev *pdev, if (status) goto free_netdev; - status = be_cmd_reset_function(adapter); - if (status) - goto ctrl_clean; - status = be_stats_init(adapter); if (status) goto ctrl_clean; @@ -2168,6 +2176,7 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state) be_close(netdev); rtnl_unlock(); } + be_cmd_get_flow_control(adapter, &adapter->tx_fc, &adapter->rx_fc); be_clear(adapter); pci_save_state(pdev); diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 6c7f795d12de..a4d83409f205 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -361,9 +361,12 @@ struct l2_fhdr { #define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE (1<<28) #define BNX2_L2CTX_HOST_BDIDX 0x00000004 -#define BNX2_L2CTX_STATUSB_NUM_SHIFT 16 -#define BNX2_L2CTX_STATUSB_NUM(sb_id) \ - (((sb_id) > 0) ? (((sb_id) + 7) << BNX2_L2CTX_STATUSB_NUM_SHIFT) : 0) +#define BNX2_L2CTX_L5_STATUSB_NUM_SHIFT 16 +#define BNX2_L2CTX_L2_STATUSB_NUM_SHIFT 24 +#define BNX2_L2CTX_L5_STATUSB_NUM(sb_id) \ + (((sb_id) > 0) ? (((sb_id) + 7) << BNX2_L2CTX_L5_STATUSB_NUM_SHIFT) : 0) +#define BNX2_L2CTX_L2_STATUSB_NUM(sb_id) \ + (((sb_id) > 0) ? (((sb_id) + 7) << BNX2_L2CTX_L2_STATUSB_NUM_SHIFT) : 0) #define BNX2_L2CTX_HOST_BSEQ 0x00000008 #define BNX2_L2CTX_NX_BSEQ 0x0000000c #define BNX2_L2CTX_NX_BDHADDR_HI 0x00000010 diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 69c5b15e22da..40fb5eefc72e 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -691,7 +691,7 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_dev, int reporting) { const struct net_device_ops *slave_ops = slave_dev->netdev_ops; - static int (*ioctl)(struct net_device *, struct ifreq *, int); + int (*ioctl)(struct net_device *, struct ifreq *, int); struct ifreq ifr; struct mii_ioctl_data *mii; @@ -3665,10 +3665,10 @@ static int bond_xmit_hash_policy_l23(struct sk_buff *skb, if (skb->protocol == htons(ETH_P_IP)) { return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^ - (data->h_dest[5] ^ bond_dev->dev_addr[5])) % count; + (data->h_dest[5] ^ data->h_source[5])) % count; } - return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count; + return (data->h_dest[5] ^ data->h_source[5]) % count; } /* @@ -3695,7 +3695,7 @@ static int bond_xmit_hash_policy_l34(struct sk_buff *skb, } - return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count; + return (data->h_dest[5] ^ data->h_source[5]) % count; } /* @@ -3706,7 +3706,7 @@ static int bond_xmit_hash_policy_l2(struct sk_buff *skb, { struct ethhdr *data = (struct ethhdr *)skb->data; - return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count; + return (data->h_dest[5] ^ data->h_source[5]) % count; } /*-------------------------- Device entry points ----------------------------*/ diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index df32c109b7ac..772f6d2489ce 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -35,66 +35,16 @@ config CAN_CALC_BITTIMING arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw". If unsure, say Y. -config CAN_SJA1000 - depends on CAN_DEV && HAS_IOMEM - tristate "Philips SJA1000" - ---help--- - Driver for the SJA1000 CAN controllers from Philips or NXP - -config CAN_SJA1000_ISA - depends on CAN_SJA1000 && ISA - tristate "ISA Bus based legacy SJA1000 driver" - ---help--- - This driver adds legacy support for SJA1000 chips connected to - the ISA bus using I/O port, memory mapped or indirect access. - -config CAN_SJA1000_PLATFORM - depends on CAN_SJA1000 - tristate "Generic Platform Bus based SJA1000 driver" - ---help--- - This driver adds support for the SJA1000 chips connected to - the "platform bus" (Linux abstraction for directly to the - processor attached devices). Which can be found on various - boards from Phytec (http://www.phytec.de) like the PCM027, - PCM038. - -config CAN_SJA1000_OF_PLATFORM - depends on CAN_SJA1000 && PPC_OF - tristate "Generic OF Platform Bus based SJA1000 driver" - ---help--- - This driver adds support for the SJA1000 chips connected to - the OpenFirmware "platform bus" found on embedded systems with - OpenFirmware bindings, e.g. if you have a PowerPC based system - you may want to enable this option. - -config CAN_EMS_PCI - tristate "EMS CPC-PCI, CPC-PCIe and CPC-104P Card" - depends on PCI && CAN_SJA1000 - ---help--- - This driver is for the one, two or four channel CPC-PCI, - CPC-PCIe and CPC-104P cards from EMS Dr. Thomas Wuensche - (http://www.ems-wuensche.de). - -config CAN_EMS_USB - tristate "EMS CPC-USB/ARM7 CAN/USB interface" - depends on USB && CAN_DEV - ---help--- - This driver is for the one channel CPC-USB/ARM7 CAN/USB interface - from from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de). - -config CAN_KVASER_PCI - tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards" - depends on PCI && CAN_SJA1000 - ---help--- - This driver is for the the PCIcanx and PCIcan cards (1, 2 or - 4 channel) from Kvaser (http://www.kvaser.com). - config CAN_AT91 tristate "Atmel AT91 onchip CAN controller" - depends on CAN && CAN_DEV && ARCH_AT91SAM9263 + depends on CAN_DEV && ARCH_AT91SAM9263 ---help--- This is a driver for the SoC CAN controller in Atmel's AT91SAM9263. +source "drivers/net/can/sja1000/Kconfig" + +source "drivers/net/can/usb/Kconfig" + config CAN_DEBUG_DEVICES bool "CAN devices debugging messages" depends on CAN diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index f0b9a1e1db46..2868fe842a41 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -589,6 +589,22 @@ static int can_changelink(struct net_device *dev, return 0; } +static size_t can_get_size(const struct net_device *dev) +{ + struct can_priv *priv = netdev_priv(dev); + size_t size; + + size = nla_total_size(sizeof(u32)); /* IFLA_CAN_STATE */ + size += sizeof(struct can_ctrlmode); /* IFLA_CAN_CTRLMODE */ + size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */ + size += sizeof(struct can_bittiming); /* IFLA_CAN_BITTIMING */ + size += sizeof(struct can_clock); /* IFLA_CAN_CLOCK */ + if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */ + size += sizeof(struct can_bittiming_const); + + return size; +} + static int can_fill_info(struct sk_buff *skb, const struct net_device *dev) { struct can_priv *priv = netdev_priv(dev); @@ -613,6 +629,11 @@ nla_put_failure: return -EMSGSIZE; } +static size_t can_get_xstats_size(const struct net_device *dev) +{ + return sizeof(struct can_device_stats); +} + static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev) { struct can_priv *priv = netdev_priv(dev); @@ -639,7 +660,9 @@ static struct rtnl_link_ops can_link_ops __read_mostly = { .setup = can_setup, .newlink = can_newlink, .changelink = can_changelink, + .get_size = can_get_size, .fill_info = can_fill_info, + .get_xstats_size = can_get_xstats_size, .fill_xstats = can_fill_xstats, }; diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig new file mode 100644 index 000000000000..4c674927f247 --- /dev/null +++ b/drivers/net/can/sja1000/Kconfig @@ -0,0 +1,47 @@ +menuconfig CAN_SJA1000 + tristate "Philips/NXP SJA1000 devices" + depends on CAN_DEV && HAS_IOMEM + +if CAN_SJA1000 + +config CAN_SJA1000_ISA + tristate "ISA Bus based legacy SJA1000 driver" + depends on ISA + ---help--- + This driver adds legacy support for SJA1000 chips connected to + the ISA bus using I/O port, memory mapped or indirect access. + +config CAN_SJA1000_PLATFORM + tristate "Generic Platform Bus based SJA1000 driver" + ---help--- + This driver adds support for the SJA1000 chips connected to + the "platform bus" (Linux abstraction for directly to the + processor attached devices). Which can be found on various + boards from Phytec (http://www.phytec.de) like the PCM027, + PCM038. + +config CAN_SJA1000_OF_PLATFORM + tristate "Generic OF Platform Bus based SJA1000 driver" + depends on PPC_OF + ---help--- + This driver adds support for the SJA1000 chips connected to + the OpenFirmware "platform bus" found on embedded systems with + OpenFirmware bindings, e.g. if you have a PowerPC based system + you may want to enable this option. + +config CAN_EMS_PCI + tristate "EMS CPC-PCI, CPC-PCIe and CPC-104P Card" + depends on PCI + ---help--- + This driver is for the one, two or four channel CPC-PCI, + CPC-PCIe and CPC-104P cards from EMS Dr. Thomas Wuensche + (http://www.ems-wuensche.de). + +config CAN_KVASER_PCI + tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards" + depends on PCI + ---help--- + This driver is for the the PCIcanx and PCIcan cards (1, 2 or + 4 channel) from Kvaser (http://www.kvaser.com). + +endif diff --git a/drivers/net/can/usb/Kconfig b/drivers/net/can/usb/Kconfig new file mode 100644 index 000000000000..bbc78e0b8a15 --- /dev/null +++ b/drivers/net/can/usb/Kconfig @@ -0,0 +1,10 @@ +menu "CAN USB interfaces" + depends on USB && CAN_DEV + +config CAN_EMS_USB + tristate "EMS CPC-USB/ARM7 CAN/USB interface" + ---help--- + This driver is for the one channel CPC-USB/ARM7 CAN/USB interface + from from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de). + +endmenu diff --git a/drivers/net/can/usb/Makefile b/drivers/net/can/usb/Makefile index c3f75ba701b1..0afd51d4c7a5 100644 --- a/drivers/net/can/usb/Makefile +++ b/drivers/net/can/usb/Makefile @@ -3,3 +3,5 @@ # obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o + +ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 9012e0abc626..abdbd9c2b788 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -319,7 +319,7 @@ static void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg) cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame)); - cf->can_id = msg->msg.can_msg.id; + cf->can_id = le32_to_cpu(msg->msg.can_msg.id); cf->can_dlc = min_t(u8, msg->msg.can_msg.length, 8); if (msg->type == CPC_MSG_TYPE_EXT_CAN_FRAME @@ -813,6 +813,9 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne msg->length = CPC_CAN_MSG_MIN_SIZE + cf->can_dlc; } + /* Respect byte order */ + msg->msg.can_msg.id = cpu_to_le32(msg->msg.can_msg.id); + for (i = 0; i < MAX_TX_URBS; i++) { if (dev->tx_contexts[i].echo_index == MAX_TX_URBS) { context = &dev->tx_contexts[i]; diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 05916aafa4f1..f857afe8e488 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -4342,11 +4342,11 @@ static int cas_open(struct net_device *dev) cas_unlock_all_restore(cp, flags); } + err = -ENOMEM; if (cas_tx_tiny_alloc(cp) < 0) - return -ENOMEM; + goto err_unlock; /* alloc rx descriptors */ - err = -ENOMEM; if (cas_alloc_rxds(cp) < 0) goto err_tx_tiny; @@ -4386,6 +4386,7 @@ err_spare: cas_free_rxds(cp); err_tx_tiny: cas_tx_tiny_free(cp); +err_unlock: mutex_unlock(&cp->pm_mutex); return err; } diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 46c87ec7960c..3bf1b04f2cab 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -2264,9 +2264,9 @@ static void cnic_init_bnx2_rx_ring(struct cnic_dev *dev) cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_CTX_TYPE, val); if (sb_id == 0) - val = 2 << BNX2_L2CTX_STATUSB_NUM_SHIFT; + val = 2 << BNX2_L2CTX_L2_STATUSB_NUM_SHIFT; else - val = BNX2_L2CTX_STATUSB_NUM(sb_id); + val = BNX2_L2CTX_L2_STATUSB_NUM(sb_id); cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_HOST_BDIDX, val); rxbd = (struct rx_bd *) (cp->l2_ring + BCM_PAGE_SIZE); @@ -2423,7 +2423,7 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev) cp->int_num = 0; if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) { u32 sb_id = cp->status_blk_num; - u32 sb = BNX2_L2CTX_STATUSB_NUM(sb_id); + u32 sb = BNX2_L2CTX_L5_STATUSB_NUM(sb_id); cp->int_num = sb_id << BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT; cnic_ctx_wr(dev, cp->kwq_cid_addr, L5_KRNLQ_HOST_QIDX, sb); diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index f86612857a73..6366061712f4 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -879,7 +879,7 @@ recycle: pci_dma_sync_single_for_cpu(adap->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); (*sd->pg_chunk.p_cnt)--; - if (!*sd->pg_chunk.p_cnt) + if (!*sd->pg_chunk.p_cnt && sd->pg_chunk.page != fl->pg_chunk.page) pci_unmap_page(adap->pdev, sd->pg_chunk.mapping, fl->alloc_size, @@ -2088,7 +2088,7 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, PCI_DMA_FROMDEVICE); (*sd->pg_chunk.p_cnt)--; - if (!*sd->pg_chunk.p_cnt) + if (!*sd->pg_chunk.p_cnt && sd->pg_chunk.page != fl->pg_chunk.page) pci_unmap_page(adap->pdev, sd->pg_chunk.mapping, fl->alloc_size, diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index f72c56dec33c..e3478314c002 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -164,16 +164,14 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; # define EMAC_MBP_MCASTCHAN(ch) ((ch) & 0x7) /* EMAC mac_control register */ -#define EMAC_MACCONTROL_TXPTYPE (0x200) -#define EMAC_MACCONTROL_TXPACEEN (0x40) -#define EMAC_MACCONTROL_MIIEN (0x20) -#define EMAC_MACCONTROL_GIGABITEN (0x80) -#define EMAC_MACCONTROL_GIGABITEN_SHIFT (7) -#define EMAC_MACCONTROL_FULLDUPLEXEN (0x1) +#define EMAC_MACCONTROL_TXPTYPE BIT(9) +#define EMAC_MACCONTROL_TXPACEEN BIT(6) +#define EMAC_MACCONTROL_GMIIEN BIT(5) +#define EMAC_MACCONTROL_GIGABITEN BIT(7) +#define EMAC_MACCONTROL_FULLDUPLEXEN BIT(0) #define EMAC_MACCONTROL_RMIISPEED_MASK BIT(15) /* GIGABIT MODE related bits */ -#define EMAC_DM646X_MACCONTORL_GMIIEN BIT(5) #define EMAC_DM646X_MACCONTORL_GIG BIT(7) #define EMAC_DM646X_MACCONTORL_GIGFORCE BIT(17) @@ -192,10 +190,10 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; #define EMAC_RX_BUFFER_OFFSET_MASK (0xFFFF) /* MAC_IN_VECTOR (0x180) register bit fields */ -#define EMAC_DM644X_MAC_IN_VECTOR_HOST_INT (0x20000) -#define EMAC_DM644X_MAC_IN_VECTOR_STATPEND_INT (0x10000) -#define EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC (0x0100) -#define EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC (0x01) +#define EMAC_DM644X_MAC_IN_VECTOR_HOST_INT BIT(17) +#define EMAC_DM644X_MAC_IN_VECTOR_STATPEND_INT BIT(16) +#define EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC BIT(8) +#define EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC BIT(0) /** NOTE:: For DM646x the IN_VECTOR has changed */ #define EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC BIT(EMAC_DEF_RX_CH) @@ -203,7 +201,6 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; #define EMAC_DM646X_MAC_IN_VECTOR_HOST_INT BIT(26) #define EMAC_DM646X_MAC_IN_VECTOR_STATPEND_INT BIT(27) - /* CPPI bit positions */ #define EMAC_CPPI_SOP_BIT BIT(31) #define EMAC_CPPI_EOP_BIT BIT(30) @@ -750,8 +747,7 @@ static void emac_update_phystatus(struct emac_priv *priv) if (priv->speed == SPEED_1000 && (priv->version == EMAC_VERSION_2)) { mac_control = emac_read(EMAC_MACCONTROL); - mac_control |= (EMAC_DM646X_MACCONTORL_GMIIEN | - EMAC_DM646X_MACCONTORL_GIG | + mac_control |= (EMAC_DM646X_MACCONTORL_GIG | EMAC_DM646X_MACCONTORL_GIGFORCE); } else { /* Clear the GIG bit and GIGFORCE bit */ @@ -2108,7 +2104,7 @@ static int emac_hw_enable(struct emac_priv *priv) /* Enable MII */ val = emac_read(EMAC_MACCONTROL); - val |= (EMAC_MACCONTROL_MIIEN); + val |= (EMAC_MACCONTROL_GMIIEN); emac_write(EMAC_MACCONTROL, val); /* Enable NAPI and interrupts */ @@ -2140,9 +2136,6 @@ static int emac_poll(struct napi_struct *napi, int budget) u32 status = 0; u32 num_pkts = 0; - if (!netif_running(ndev)) - return 0; - /* Check interrupt vectors and call packet processing */ status = emac_read(EMAC_MACINVECTOR); @@ -2221,7 +2214,7 @@ void emac_poll_controller(struct net_device *ndev) struct emac_priv *priv = netdev_priv(ndev); emac_int_disable(priv); - emac_irq(ndev->irq, priv); + emac_irq(ndev->irq, ndev); emac_int_enable(priv); } #endif diff --git a/drivers/net/dm9000.h b/drivers/net/dm9000.h index 80817c2edfb3..fb1c924d79b4 100644 --- a/drivers/net/dm9000.h +++ b/drivers/net/dm9000.h @@ -50,7 +50,7 @@ #define DM9000_RCSR 0x32 #define CHIPR_DM9000A 0x19 -#define CHIPR_DM9000B 0x1B +#define CHIPR_DM9000B 0x1A #define DM9000_MRCMDX 0xF0 #define DM9000_MRCMD 0xF2 diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 5d2f48f02251..d269a68ce354 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -157,6 +157,7 @@ #include <linux/init.h> #include <linux/pci.h> #include <linux/dma-mapping.h> +#include <linux/dmapool.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/mii.h> @@ -602,6 +603,7 @@ struct nic { struct mem *mem; dma_addr_t dma_addr; + struct pci_pool *cbs_pool; dma_addr_t cbs_dma_addr; u8 adaptive_ifs; u8 tx_threshold; @@ -1427,19 +1429,31 @@ static int e100_phy_init(struct nic *nic) } else DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id); - /* Isolate all the PHY ids */ - for (addr = 0; addr < 32; addr++) - mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE); - /* Select the discovered PHY */ - bmcr &= ~BMCR_ISOLATE; - mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr); - /* Get phy ID */ id_lo = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID1); id_hi = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID2); nic->phy = (u32)id_hi << 16 | (u32)id_lo; DPRINTK(HW, DEBUG, "phy ID = 0x%08X\n", nic->phy); + /* Select the phy and isolate the rest */ + for (addr = 0; addr < 32; addr++) { + if (addr != nic->mii.phy_id) { + mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE); + } else if (nic->phy != phy_82552_v) { + bmcr = mdio_read(netdev, addr, MII_BMCR); + mdio_write(netdev, addr, MII_BMCR, + bmcr & ~BMCR_ISOLATE); + } + } + /* + * Workaround for 82552: + * Clear the ISOLATE bit on selected phy_id last (mirrored on all + * other phy_id's) using bmcr value from addr discovery loop above. + */ + if (nic->phy == phy_82552_v) + mdio_write(netdev, nic->mii.phy_id, MII_BMCR, + bmcr & ~BMCR_ISOLATE); + /* Handle National tx phys */ #define NCS_PHY_MODEL_MASK 0xFFF0FFFF if ((nic->phy & NCS_PHY_MODEL_MASK) == phy_nsc_tx) { @@ -1781,9 +1795,7 @@ static void e100_clean_cbs(struct nic *nic) nic->cb_to_clean = nic->cb_to_clean->next; nic->cbs_avail++; } - pci_free_consistent(nic->pdev, - sizeof(struct cb) * nic->params.cbs.count, - nic->cbs, nic->cbs_dma_addr); + pci_pool_free(nic->cbs_pool, nic->cbs, nic->cbs_dma_addr); nic->cbs = NULL; nic->cbs_avail = 0; } @@ -1801,8 +1813,8 @@ static int e100_alloc_cbs(struct nic *nic) nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL; nic->cbs_avail = 0; - nic->cbs = pci_alloc_consistent(nic->pdev, - sizeof(struct cb) * count, &nic->cbs_dma_addr); + nic->cbs = pci_pool_alloc(nic->cbs_pool, GFP_KERNEL, + &nic->cbs_dma_addr); if (!nic->cbs) return -ENOMEM; @@ -2829,7 +2841,11 @@ static int __devinit e100_probe(struct pci_dev *pdev, DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n"); goto err_out_free; } - + nic->cbs_pool = pci_pool_create(netdev->name, + nic->pdev, + nic->params.cbs.count * sizeof(struct cb), + sizeof(u32), + 0); DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n", (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0), pdev->irq, netdev->dev_addr); @@ -2859,6 +2875,7 @@ static void __devexit e100_remove(struct pci_dev *pdev) unregister_netdev(netdev); e100_free(nic); pci_iounmap(pdev, nic->csr); + pci_pool_destroy(nic->cbs_pool); free_netdev(netdev); pci_release_regions(pdev); pci_disable_device(pdev); diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index c0f185beb8bc..1190167a8b3d 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h @@ -76,6 +76,7 @@ /* Extended Device Control */ #define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */ #define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */ +#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */ #define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */ #define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clock Gating */ #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000 @@ -347,6 +348,7 @@ /* Extended Configuration Control and Size */ #define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020 #define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001 +#define E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE 0x00000008 #define E1000_EXTCNF_CTRL_SWFLAG 0x00000020 #define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK 0x00FF0000 #define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT 16 diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 981936c1fb46..3e187b0e4203 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -141,6 +141,22 @@ struct e1000_info; #define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */ #define HV_TNCRS_LOWER PHY_REG(778, 30) +#define E1000_FCRTV_PCH 0x05F40 /* PCH Flow Control Refresh Timer Value */ + +/* BM PHY Copper Specific Status */ +#define BM_CS_STATUS 17 +#define BM_CS_STATUS_LINK_UP 0x0400 +#define BM_CS_STATUS_RESOLVED 0x0800 +#define BM_CS_STATUS_SPEED_MASK 0xC000 +#define BM_CS_STATUS_SPEED_1000 0x8000 + +/* 82577 Mobile Phy Status Register */ +#define HV_M_STATUS 26 +#define HV_M_STATUS_AUTONEG_COMPLETE 0x1000 +#define HV_M_STATUS_SPEED_MASK 0x0300 +#define HV_M_STATUS_SPEED_1000 0x0200 +#define HV_M_STATUS_LINK_UP 0x0040 + enum e1000_boards { board_82571, board_82572, @@ -519,9 +535,13 @@ extern s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw); extern s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw); extern s32 e1000e_get_phy_info_igp(struct e1000_hw *hw); extern s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data); +extern s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, + u16 *data); extern s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw); extern s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active); extern s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data); +extern s32 e1000e_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, + u16 data); extern s32 e1000e_phy_sw_reset(struct e1000_hw *hw); extern s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw); extern s32 e1000e_get_cfg_done(struct e1000_hw *hw); @@ -538,7 +558,11 @@ extern s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data); extern s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data); extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl); extern s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data); +extern s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, + u16 data); extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data); +extern s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, + u16 *data); extern s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, u32 usec_interval, bool *success); extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw); @@ -546,7 +570,11 @@ extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data); extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data); extern s32 e1000e_check_downshift(struct e1000_hw *hw); extern s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data); +extern s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, + u16 *data); extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data); +extern s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, + u16 data); extern s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow); extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw); extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw); diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 1bf4d2a5d34f..e82638ecae88 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -327,10 +327,18 @@ static int e1000_set_pauseparam(struct net_device *netdev, hw->fc.current_mode = hw->fc.requested_mode; - retval = ((hw->phy.media_type == e1000_media_type_fiber) ? - hw->mac.ops.setup_link(hw) : e1000e_force_mac_fc(hw)); + if (hw->phy.media_type == e1000_media_type_fiber) { + retval = hw->mac.ops.setup_link(hw); + /* implicit goto out */ + } else { + retval = e1000e_force_mac_fc(hw); + if (retval) + goto out; + e1000e_set_fc_watermarks(hw); + } } +out: clear_bit(__E1000_RESETTING, &adapter->state); return retval; } diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index fd44d9f90769..aaea41ef794d 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h @@ -764,11 +764,13 @@ struct e1000_phy_operations { s32 (*get_cable_length)(struct e1000_hw *); s32 (*get_phy_info)(struct e1000_hw *); s32 (*read_phy_reg)(struct e1000_hw *, u32, u16 *); + s32 (*read_phy_reg_locked)(struct e1000_hw *, u32, u16 *); void (*release_phy)(struct e1000_hw *); s32 (*reset_phy)(struct e1000_hw *); s32 (*set_d0_lplu_state)(struct e1000_hw *, bool); s32 (*set_d3_lplu_state)(struct e1000_hw *, bool); s32 (*write_phy_reg)(struct e1000_hw *, u32, u16); + s32 (*write_phy_reg_locked)(struct e1000_hw *, u32, u16); s32 (*cfg_on_link_up)(struct e1000_hw *); }; @@ -901,6 +903,7 @@ struct e1000_shadow_ram { struct e1000_dev_spec_ich8lan { bool kmrn_lock_loss_workaround_enabled; struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS]; + bool nvm_k1_enabled; }; struct e1000_hw { diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 99df2abf82a9..eff3f4783655 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -122,6 +122,27 @@ #define HV_LED_CONFIG PHY_REG(768, 30) /* LED Configuration */ +#define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in milliseconds */ + +/* SMBus Address Phy Register */ +#define HV_SMB_ADDR PHY_REG(768, 26) +#define HV_SMB_ADDR_PEC_EN 0x0200 +#define HV_SMB_ADDR_VALID 0x0080 + +/* Strapping Option Register - RO */ +#define E1000_STRAP 0x0000C +#define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000 +#define E1000_STRAP_SMBUS_ADDRESS_SHIFT 17 + +/* OEM Bits Phy Register */ +#define HV_OEM_BITS PHY_REG(768, 25) +#define HV_OEM_BITS_LPLU 0x0004 /* Low Power Link Up */ +#define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */ +#define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */ + +#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */ +#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */ + /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ /* Offset 04h HSFSTS */ union ich8_hws_flash_status { @@ -200,6 +221,10 @@ static s32 e1000_setup_led_pchlan(struct e1000_hw *hw); static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw); static s32 e1000_led_on_pchlan(struct e1000_hw *hw); static s32 e1000_led_off_pchlan(struct e1000_hw *hw); +static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active); +static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw); +static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link); +static s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable); static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) { @@ -242,7 +267,11 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) phy->ops.check_polarity = e1000_check_polarity_ife_ich8lan; phy->ops.read_phy_reg = e1000_read_phy_reg_hv; + phy->ops.read_phy_reg_locked = e1000_read_phy_reg_hv_locked; + phy->ops.set_d0_lplu_state = e1000_set_lplu_state_pchlan; + phy->ops.set_d3_lplu_state = e1000_set_lplu_state_pchlan; phy->ops.write_phy_reg = e1000_write_phy_reg_hv; + phy->ops.write_phy_reg_locked = e1000_write_phy_reg_hv_locked; phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; phy->id = e1000_phy_unknown; @@ -303,6 +332,8 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) case IGP03E1000_E_PHY_ID: phy->type = e1000_phy_igp_3; phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; + phy->ops.read_phy_reg_locked = e1000e_read_phy_reg_igp_locked; + phy->ops.write_phy_reg_locked = e1000e_write_phy_reg_igp_locked; break; case IFE_E_PHY_ID: case IFE_PLUS_E_PHY_ID: @@ -469,14 +500,6 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) goto out; } - if (hw->mac.type == e1000_pchlan) { - ret_val = e1000e_write_kmrn_reg(hw, - E1000_KMRNCTRLSTA_K1_CONFIG, - E1000_KMRNCTRLSTA_K1_ENABLE); - if (ret_val) - goto out; - } - /* * First we want to see if the MII Status Register reports * link. If so, then we want to get the current speed/duplex @@ -486,6 +509,12 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) if (ret_val) goto out; + if (hw->mac.type == e1000_pchlan) { + ret_val = e1000_k1_gig_workaround_hv(hw, link); + if (ret_val) + goto out; + } + if (!link) goto out; /* No link detected */ @@ -568,12 +597,39 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) static DEFINE_MUTEX(nvm_mutex); /** + * e1000_acquire_nvm_ich8lan - Acquire NVM mutex + * @hw: pointer to the HW structure + * + * Acquires the mutex for performing NVM operations. + **/ +static s32 e1000_acquire_nvm_ich8lan(struct e1000_hw *hw) +{ + mutex_lock(&nvm_mutex); + + return 0; +} + +/** + * e1000_release_nvm_ich8lan - Release NVM mutex + * @hw: pointer to the HW structure + * + * Releases the mutex used while performing NVM operations. + **/ +static void e1000_release_nvm_ich8lan(struct e1000_hw *hw) +{ + mutex_unlock(&nvm_mutex); + + return; +} + +static DEFINE_MUTEX(swflag_mutex); + +/** * e1000_acquire_swflag_ich8lan - Acquire software control flag * @hw: pointer to the HW structure * - * Acquires the software control flag for performing NVM and PHY - * operations. This is a function pointer entry point only called by - * read/write routines for the PHY and NVM parts. + * Acquires the software control flag for performing PHY and select + * MAC CSR accesses. **/ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) { @@ -582,7 +638,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) might_sleep(); - mutex_lock(&nvm_mutex); + mutex_lock(&swflag_mutex); while (timeout) { extcnf_ctrl = er32(EXTCNF_CTRL); @@ -599,7 +655,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) goto out; } - timeout = PHY_CFG_TIMEOUT * 2; + timeout = SW_FLAG_TIMEOUT; extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; ew32(EXTCNF_CTRL, extcnf_ctrl); @@ -623,7 +679,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) out: if (ret_val) - mutex_unlock(&nvm_mutex); + mutex_unlock(&swflag_mutex); return ret_val; } @@ -632,9 +688,8 @@ out: * e1000_release_swflag_ich8lan - Release software control flag * @hw: pointer to the HW structure * - * Releases the software control flag for performing NVM and PHY operations. - * This is a function pointer entry point only called by read/write - * routines for the PHY and NVM parts. + * Releases the software control flag for performing PHY and select + * MAC CSR accesses. **/ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) { @@ -644,7 +699,9 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; ew32(EXTCNF_CTRL, extcnf_ctrl); - mutex_unlock(&nvm_mutex); + mutex_unlock(&swflag_mutex); + + return; } /** @@ -752,6 +809,327 @@ static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw) } /** + * e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration + * @hw: pointer to the HW structure + * + * SW should configure the LCD from the NVM extended configuration region + * as a workaround for certain parts. + **/ +static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask; + s32 ret_val; + u16 word_addr, reg_data, reg_addr, phy_page = 0; + + ret_val = hw->phy.ops.acquire_phy(hw); + if (ret_val) + return ret_val; + + /* + * Initialize the PHY from the NVM on ICH platforms. This + * is needed due to an issue where the NVM configuration is + * not properly autoloaded after power transitions. + * Therefore, after each PHY reset, we will load the + * configuration data out of the NVM manually. + */ + if ((hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) || + (hw->mac.type == e1000_pchlan)) { + struct e1000_adapter *adapter = hw->adapter; + + /* Check if SW needs to configure the PHY */ + if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) || + (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M) || + (hw->mac.type == e1000_pchlan)) + sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; + else + sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; + + data = er32(FEXTNVM); + if (!(data & sw_cfg_mask)) + goto out; + + /* Wait for basic configuration completes before proceeding */ + e1000_lan_init_done_ich8lan(hw); + + /* + * Make sure HW does not configure LCD from PHY + * extended configuration before SW configuration + */ + data = er32(EXTCNF_CTRL); + if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) + goto out; + + cnf_size = er32(EXTCNF_SIZE); + cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK; + cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT; + if (!cnf_size) + goto out; + + cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; + cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; + + if (!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) && + (hw->mac.type == e1000_pchlan)) { + /* + * HW configures the SMBus address and LEDs when the + * OEM and LCD Write Enable bits are set in the NVM. + * When both NVM bits are cleared, SW will configure + * them instead. + */ + data = er32(STRAP); + data &= E1000_STRAP_SMBUS_ADDRESS_MASK; + reg_data = data >> E1000_STRAP_SMBUS_ADDRESS_SHIFT; + reg_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID; + ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, + reg_data); + if (ret_val) + goto out; + + data = er32(LEDCTL); + ret_val = e1000_write_phy_reg_hv_locked(hw, + HV_LED_CONFIG, + (u16)data); + if (ret_val) + goto out; + } + /* Configure LCD from extended configuration region. */ + + /* cnf_base_addr is in DWORD */ + word_addr = (u16)(cnf_base_addr << 1); + + for (i = 0; i < cnf_size; i++) { + ret_val = e1000_read_nvm(hw, (word_addr + i * 2), 1, + ®_data); + if (ret_val) + goto out; + + ret_val = e1000_read_nvm(hw, (word_addr + i * 2 + 1), + 1, ®_addr); + if (ret_val) + goto out; + + /* Save off the PHY page for future writes. */ + if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) { + phy_page = reg_data; + continue; + } + + reg_addr &= PHY_REG_MASK; + reg_addr |= phy_page; + + ret_val = phy->ops.write_phy_reg_locked(hw, + (u32)reg_addr, + reg_data); + if (ret_val) + goto out; + } + } + +out: + hw->phy.ops.release_phy(hw); + return ret_val; +} + +/** + * e1000_k1_gig_workaround_hv - K1 Si workaround + * @hw: pointer to the HW structure + * @link: link up bool flag + * + * If K1 is enabled for 1Gbps, the MAC might stall when transitioning + * from a lower speed. This workaround disables K1 whenever link is at 1Gig + * If link is down, the function will restore the default K1 setting located + * in the NVM. + **/ +static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link) +{ + s32 ret_val = 0; + u16 status_reg = 0; + bool k1_enable = hw->dev_spec.ich8lan.nvm_k1_enabled; + + if (hw->mac.type != e1000_pchlan) + goto out; + + /* Wrap the whole flow with the sw flag */ + ret_val = hw->phy.ops.acquire_phy(hw); + if (ret_val) + goto out; + + /* Disable K1 when link is 1Gbps, otherwise use the NVM setting */ + if (link) { + if (hw->phy.type == e1000_phy_82578) { + ret_val = hw->phy.ops.read_phy_reg_locked(hw, + BM_CS_STATUS, + &status_reg); + if (ret_val) + goto release; + + status_reg &= BM_CS_STATUS_LINK_UP | + BM_CS_STATUS_RESOLVED | + BM_CS_STATUS_SPEED_MASK; + + if (status_reg == (BM_CS_STATUS_LINK_UP | + BM_CS_STATUS_RESOLVED | + BM_CS_STATUS_SPEED_1000)) + k1_enable = false; + } + + if (hw->phy.type == e1000_phy_82577) { + ret_val = hw->phy.ops.read_phy_reg_locked(hw, + HV_M_STATUS, + &status_reg); + if (ret_val) + goto release; + + status_reg &= HV_M_STATUS_LINK_UP | + HV_M_STATUS_AUTONEG_COMPLETE | + HV_M_STATUS_SPEED_MASK; + + if (status_reg == (HV_M_STATUS_LINK_UP | + HV_M_STATUS_AUTONEG_COMPLETE | + HV_M_STATUS_SPEED_1000)) + k1_enable = false; + } + + /* Link stall fix for link up */ + ret_val = hw->phy.ops.write_phy_reg_locked(hw, PHY_REG(770, 19), + 0x0100); + if (ret_val) + goto release; + + } else { + /* Link stall fix for link down */ + ret_val = hw->phy.ops.write_phy_reg_locked(hw, PHY_REG(770, 19), + 0x4100); + if (ret_val) + goto release; + } + + ret_val = e1000_configure_k1_ich8lan(hw, k1_enable); + +release: + hw->phy.ops.release_phy(hw); +out: + return ret_val; +} + +/** + * e1000_configure_k1_ich8lan - Configure K1 power state + * @hw: pointer to the HW structure + * @enable: K1 state to configure + * + * Configure the K1 power state based on the provided parameter. + * Assumes semaphore already acquired. + * + * Success returns 0, Failure returns -E1000_ERR_PHY (-2) + **/ +static s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable) +{ + s32 ret_val = 0; + u32 ctrl_reg = 0; + u32 ctrl_ext = 0; + u32 reg = 0; + u16 kmrn_reg = 0; + + ret_val = e1000e_read_kmrn_reg_locked(hw, + E1000_KMRNCTRLSTA_K1_CONFIG, + &kmrn_reg); + if (ret_val) + goto out; + + if (k1_enable) + kmrn_reg |= E1000_KMRNCTRLSTA_K1_ENABLE; + else + kmrn_reg &= ~E1000_KMRNCTRLSTA_K1_ENABLE; + + ret_val = e1000e_write_kmrn_reg_locked(hw, + E1000_KMRNCTRLSTA_K1_CONFIG, + kmrn_reg); + if (ret_val) + goto out; + + udelay(20); + ctrl_ext = er32(CTRL_EXT); + ctrl_reg = er32(CTRL); + + reg = ctrl_reg & ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100); + reg |= E1000_CTRL_FRCSPD; + ew32(CTRL, reg); + + ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_SPD_BYPS); + udelay(20); + ew32(CTRL, ctrl_reg); + ew32(CTRL_EXT, ctrl_ext); + udelay(20); + +out: + return ret_val; +} + +/** + * e1000_oem_bits_config_ich8lan - SW-based LCD Configuration + * @hw: pointer to the HW structure + * @d0_state: boolean if entering d0 or d3 device state + * + * SW will configure Gbe Disable and LPLU based on the NVM. The four bits are + * collectively called OEM bits. The OEM Write Enable bit and SW Config bit + * in NVM determines whether HW should configure LPLU and Gbe Disable. + **/ +static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state) +{ + s32 ret_val = 0; + u32 mac_reg; + u16 oem_reg; + + if (hw->mac.type != e1000_pchlan) + return ret_val; + + ret_val = hw->phy.ops.acquire_phy(hw); + if (ret_val) + return ret_val; + + mac_reg = er32(EXTCNF_CTRL); + if (mac_reg & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) + goto out; + + mac_reg = er32(FEXTNVM); + if (!(mac_reg & E1000_FEXTNVM_SW_CONFIG_ICH8M)) + goto out; + + mac_reg = er32(PHY_CTRL); + + ret_val = hw->phy.ops.read_phy_reg_locked(hw, HV_OEM_BITS, &oem_reg); + if (ret_val) + goto out; + + oem_reg &= ~(HV_OEM_BITS_GBE_DIS | HV_OEM_BITS_LPLU); + + if (d0_state) { + if (mac_reg & E1000_PHY_CTRL_GBE_DISABLE) + oem_reg |= HV_OEM_BITS_GBE_DIS; + + if (mac_reg & E1000_PHY_CTRL_D0A_LPLU) + oem_reg |= HV_OEM_BITS_LPLU; + } else { + if (mac_reg & E1000_PHY_CTRL_NOND0A_GBE_DISABLE) + oem_reg |= HV_OEM_BITS_GBE_DIS; + + if (mac_reg & E1000_PHY_CTRL_NOND0A_LPLU) + oem_reg |= HV_OEM_BITS_LPLU; + } + /* Restart auto-neg to activate the bits */ + if (!e1000_check_reset_block(hw)) + oem_reg |= HV_OEM_BITS_RESTART_AN; + ret_val = hw->phy.ops.write_phy_reg_locked(hw, HV_OEM_BITS, oem_reg); + +out: + hw->phy.ops.release_phy(hw); + + return ret_val; +} + + +/** * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be * done after every PHY reset. **/ @@ -791,10 +1169,20 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) ret_val = hw->phy.ops.acquire_phy(hw); if (ret_val) return ret_val; + hw->phy.addr = 1; - e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); + ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); + if (ret_val) + goto out; hw->phy.ops.release_phy(hw); + /* + * Configure the K1 Si workaround during phy reset assuming there is + * link so that it disables K1 if link is in 1Gbps. + */ + ret_val = e1000_k1_gig_workaround_hv(hw, true); + +out: return ret_val; } @@ -840,11 +1228,8 @@ static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw) **/ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) { - struct e1000_phy_info *phy = &hw->phy; - u32 i; - u32 data, cnf_size, cnf_base_addr, sw_cfg_mask; - s32 ret_val; - u16 word_addr, reg_data, reg_addr, phy_page = 0; + s32 ret_val = 0; + u16 reg; ret_val = e1000e_phy_hw_reset_generic(hw); if (ret_val) @@ -859,81 +1244,20 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) return ret_val; } - /* - * Initialize the PHY from the NVM on ICH platforms. This - * is needed due to an issue where the NVM configuration is - * not properly autoloaded after power transitions. - * Therefore, after each PHY reset, we will load the - * configuration data out of the NVM manually. - */ - if (hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) { - struct e1000_adapter *adapter = hw->adapter; - - /* Check if SW needs configure the PHY */ - if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) || - (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M)) - sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; - else - sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; - - data = er32(FEXTNVM); - if (!(data & sw_cfg_mask)) - return 0; - - /* Wait for basic configuration completes before proceeding */ - e1000_lan_init_done_ich8lan(hw); - - /* - * Make sure HW does not configure LCD from PHY - * extended configuration before SW configuration - */ - data = er32(EXTCNF_CTRL); - if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) - return 0; - - cnf_size = er32(EXTCNF_SIZE); - cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK; - cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT; - if (!cnf_size) - return 0; - - cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; - cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; - - /* Configure LCD from extended configuration region. */ - - /* cnf_base_addr is in DWORD */ - word_addr = (u16)(cnf_base_addr << 1); - - for (i = 0; i < cnf_size; i++) { - ret_val = e1000_read_nvm(hw, - (word_addr + i * 2), - 1, - ®_data); - if (ret_val) - return ret_val; - - ret_val = e1000_read_nvm(hw, - (word_addr + i * 2 + 1), - 1, - ®_addr); - if (ret_val) - return ret_val; - - /* Save off the PHY page for future writes. */ - if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) { - phy_page = reg_data; - continue; - } + /* Dummy read to clear the phy wakeup bit after lcd reset */ + if (hw->mac.type == e1000_pchlan) + e1e_rphy(hw, BM_WUC, ®); - reg_addr |= phy_page; + /* Configure the LCD with the extended configuration region in NVM */ + ret_val = e1000_sw_lcd_config_ich8lan(hw); + if (ret_val) + goto out; - ret_val = e1e_wphy(hw, (u32)reg_addr, reg_data); - if (ret_val) - return ret_val; - } - } + /* Configure the LCD with the OEM bits in NVM */ + if (hw->mac.type == e1000_pchlan) + ret_val = e1000_oem_bits_config_ich8lan(hw, true); +out: return 0; } @@ -1054,6 +1378,38 @@ static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw) } /** + * e1000_set_lplu_state_pchlan - Set Low Power Link Up state + * @hw: pointer to the HW structure + * @active: true to enable LPLU, false to disable + * + * Sets the LPLU state according to the active flag. For PCH, if OEM write + * bit are disabled in the NVM, writing the LPLU bits in the MAC will not set + * the phy speed. This function will manually set the LPLU bit and restart + * auto-neg as hw would do. D3 and D0 LPLU will call the same function + * since it configures the same bit. + **/ +static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active) +{ + s32 ret_val = 0; + u16 oem_reg; + + ret_val = e1e_rphy(hw, HV_OEM_BITS, &oem_reg); + if (ret_val) + goto out; + + if (active) + oem_reg |= HV_OEM_BITS_LPLU; + else + oem_reg &= ~HV_OEM_BITS_LPLU; + + oem_reg |= HV_OEM_BITS_RESTART_AN; + ret_val = e1e_wphy(hw, HV_OEM_BITS, oem_reg); + +out: + return ret_val; +} + +/** * e1000_set_d0_lplu_state_ich8lan - Set Low Power Linkup D0 state * @hw: pointer to the HW structure * @active: TRUE to enable LPLU, FALSE to disable @@ -1314,12 +1670,11 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) || (words == 0)) { hw_dbg(hw, "nvm parameter(s) out of bounds\n"); - return -E1000_ERR_NVM; + ret_val = -E1000_ERR_NVM; + goto out; } - ret_val = e1000_acquire_swflag_ich8lan(hw); - if (ret_val) - goto out; + nvm->ops.acquire_nvm(hw); ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); if (ret_val) { @@ -1345,7 +1700,7 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, } } - e1000_release_swflag_ich8lan(hw); + nvm->ops.release_nvm(hw); out: if (ret_val) @@ -1603,11 +1958,15 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, return -E1000_ERR_NVM; } + nvm->ops.acquire_nvm(hw); + for (i = 0; i < words; i++) { dev_spec->shadow_ram[offset+i].modified = 1; dev_spec->shadow_ram[offset+i].value = data[i]; } + nvm->ops.release_nvm(hw); + return 0; } @@ -1637,9 +1996,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) if (nvm->type != e1000_nvm_flash_sw) goto out; - ret_val = e1000_acquire_swflag_ich8lan(hw); - if (ret_val) - goto out; + nvm->ops.acquire_nvm(hw); /* * We're writing to the opposite bank so if we're on bank 1, @@ -1657,7 +2014,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) old_bank_offset = 0; ret_val = e1000_erase_flash_bank_ich8lan(hw, 1); if (ret_val) { - e1000_release_swflag_ich8lan(hw); + nvm->ops.release_nvm(hw); goto out; } } else { @@ -1665,7 +2022,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) new_bank_offset = 0; ret_val = e1000_erase_flash_bank_ich8lan(hw, 0); if (ret_val) { - e1000_release_swflag_ich8lan(hw); + nvm->ops.release_nvm(hw); goto out; } } @@ -1723,7 +2080,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) if (ret_val) { /* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */ hw_dbg(hw, "Flash commit failed.\n"); - e1000_release_swflag_ich8lan(hw); + nvm->ops.release_nvm(hw); goto out; } @@ -1736,7 +2093,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD; ret_val = e1000_read_flash_word_ich8lan(hw, act_offset, &data); if (ret_val) { - e1000_release_swflag_ich8lan(hw); + nvm->ops.release_nvm(hw); goto out; } data &= 0xBFFF; @@ -1744,7 +2101,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) act_offset * 2 + 1, (u8)(data >> 8)); if (ret_val) { - e1000_release_swflag_ich8lan(hw); + nvm->ops.release_nvm(hw); goto out; } @@ -1757,7 +2114,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1; ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0); if (ret_val) { - e1000_release_swflag_ich8lan(hw); + nvm->ops.release_nvm(hw); goto out; } @@ -1767,7 +2124,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) dev_spec->shadow_ram[i].value = 0xFFFF; } - e1000_release_swflag_ich8lan(hw); + nvm->ops.release_nvm(hw); /* * Reload the EEPROM, or else modifications will not appear @@ -1831,14 +2188,12 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) **/ void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw) { + struct e1000_nvm_info *nvm = &hw->nvm; union ich8_flash_protected_range pr0; union ich8_hws_flash_status hsfsts; u32 gfpreg; - s32 ret_val; - ret_val = e1000_acquire_swflag_ich8lan(hw); - if (ret_val) - return; + nvm->ops.acquire_nvm(hw); gfpreg = er32flash(ICH_FLASH_GFPREG); @@ -1859,7 +2214,7 @@ void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw) hsfsts.hsf_status.flockdn = true; ew32flash(ICH_FLASH_HSFSTS, hsfsts.regval); - e1000_release_swflag_ich8lan(hw); + nvm->ops.release_nvm(hw); } /** @@ -2229,6 +2584,8 @@ static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw) **/ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) { + struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; + u16 reg; u32 ctrl, icr, kab; s32 ret_val; @@ -2263,6 +2620,18 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) ew32(PBS, E1000_PBS_16K); } + if (hw->mac.type == e1000_pchlan) { + /* Save the NVM K1 bit setting*/ + ret_val = e1000_read_nvm(hw, E1000_NVM_K1_CONFIG, 1, ®); + if (ret_val) + return ret_val; + + if (reg & E1000_NVM_K1_ENABLE) + dev_spec->nvm_k1_enabled = true; + else + dev_spec->nvm_k1_enabled = false; + } + ctrl = er32(CTRL); if (!e1000_check_reset_block(hw)) { @@ -2304,7 +2673,19 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) hw_dbg(hw, "Auto Read Done did not complete\n"); } } + /* Dummy read to clear the phy wakeup bit after lcd reset */ + if (hw->mac.type == e1000_pchlan) + e1e_rphy(hw, BM_WUC, ®); + ret_val = e1000_sw_lcd_config_ich8lan(hw); + if (ret_val) + goto out; + + if (hw->mac.type == e1000_pchlan) { + ret_val = e1000_oem_bits_config_ich8lan(hw, true); + if (ret_val) + goto out; + } /* * For PCH, this write will make sure that any noise * will be detected as a CRC error and be dropped rather than show up @@ -2323,6 +2704,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) if (hw->mac.type == e1000_pchlan) ret_val = e1000_hv_phy_workarounds_ich8lan(hw); +out: return ret_val; } @@ -2627,14 +3009,6 @@ static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed, if (ret_val) return ret_val; - if ((hw->mac.type == e1000_pchlan) && (*speed == SPEED_1000)) { - ret_val = e1000e_write_kmrn_reg(hw, - E1000_KMRNCTRLSTA_K1_CONFIG, - E1000_KMRNCTRLSTA_K1_DISABLE); - if (ret_val) - return ret_val; - } - if ((hw->mac.type == e1000_ich8lan) && (hw->phy.type == e1000_phy_igp_3) && (*speed == SPEED_1000)) { @@ -2843,9 +3217,8 @@ void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) E1000_PHY_CTRL_GBE_DISABLE; ew32(PHY_CTRL, phy_ctrl); - /* Workaround SWFLAG unexpectedly set during S0->Sx */ if (hw->mac.type == e1000_pchlan) - udelay(500); + e1000_phy_hw_reset_ich8lan(hw); default: break; } @@ -3113,9 +3486,9 @@ static struct e1000_phy_operations ich8_phy_ops = { }; static struct e1000_nvm_operations ich8_nvm_ops = { - .acquire_nvm = e1000_acquire_swflag_ich8lan, + .acquire_nvm = e1000_acquire_nvm_ich8lan, .read_nvm = e1000_read_nvm_ich8lan, - .release_nvm = e1000_release_swflag_ich8lan, + .release_nvm = e1000_release_nvm_ich8lan, .update_nvm = e1000_update_nvm_checksum_ich8lan, .valid_led_default = e1000_valid_led_default_ich8lan, .validate_nvm = e1000_validate_nvm_checksum_ich8lan, @@ -3186,6 +3559,7 @@ struct e1000_info e1000_pch_info = { | FLAG_HAS_AMT | FLAG_HAS_FLASH | FLAG_HAS_JUMBO_FRAMES + | FLAG_DISABLE_FC_PAUSE_TIME /* errata */ | FLAG_APME_IN_WUC, .pba = 26, .max_hw_frame_size = 4096, diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 0687c6aa4e46..fad8f9ea0043 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -2769,25 +2769,38 @@ void e1000e_reset(struct e1000_adapter *adapter) /* * flow control settings * - * The high water mark must be low enough to fit two full frame + * The high water mark must be low enough to fit one full frame * (or the size used for early receive) above it in the Rx FIFO. * Set it to the lower of: * - 90% of the Rx FIFO size, and * - the full Rx FIFO size minus the early receive size (for parts * with ERT support assuming ERT set to E1000_ERT_2048), or - * - the full Rx FIFO size minus two full frames + * - the full Rx FIFO size minus one full frame */ - if ((adapter->flags & FLAG_HAS_ERT) && - (adapter->netdev->mtu > ETH_DATA_LEN)) - hwm = min(((pba << 10) * 9 / 10), - ((pba << 10) - (E1000_ERT_2048 << 3))); - else - hwm = min(((pba << 10) * 9 / 10), - ((pba << 10) - (2 * adapter->max_frame_size))); + if (hw->mac.type == e1000_pchlan) { + /* + * Workaround PCH LOM adapter hangs with certain network + * loads. If hangs persist, try disabling Tx flow control. + */ + if (adapter->netdev->mtu > ETH_DATA_LEN) { + fc->high_water = 0x3500; + fc->low_water = 0x1500; + } else { + fc->high_water = 0x5000; + fc->low_water = 0x3000; + } + } else { + if ((adapter->flags & FLAG_HAS_ERT) && + (adapter->netdev->mtu > ETH_DATA_LEN)) + hwm = min(((pba << 10) * 9 / 10), + ((pba << 10) - (E1000_ERT_2048 << 3))); + else + hwm = min(((pba << 10) * 9 / 10), + ((pba << 10) - adapter->max_frame_size)); - fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */ - fc->low_water = (fc->high_water - (2 * adapter->max_frame_size)); - fc->low_water &= E1000_FCRTL_RTL; /* 8-byte granularity */ + fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */ + fc->low_water = fc->high_water - 8; + } if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME) fc->pause_time = 0xFFFF; @@ -2813,6 +2826,10 @@ void e1000e_reset(struct e1000_adapter *adapter) if (mac->ops.init_hw(hw)) e_err("Hardware Error\n"); + /* additional part of the flow-control workaround above */ + if (hw->mac.type == e1000_pchlan) + ew32(FCRTV_PCH, 0x1000); + e1000_update_mng_vlan(adapter); /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ @@ -3610,7 +3627,7 @@ static void e1000_watchdog_task(struct work_struct *work) case SPEED_100: txb2b = 0; netdev->tx_queue_len = 100; - /* maybe add some timeout factor ? */ + adapter->tx_timeout_factor = 10; break; } @@ -4288,8 +4305,10 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) msleep(1); - /* e1000e_down has a dependency on max_frame_size */ + /* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */ adapter->max_frame_size = max_frame; + e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu); + netdev->mtu = new_mtu; if (netif_running(netdev)) e1000e_down(adapter); @@ -4319,9 +4338,6 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN; - e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu); - netdev->mtu = new_mtu; - if (netif_running(netdev)) e1000e_up(adapter); else diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 994401fd0664..85f955f70417 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -71,7 +71,6 @@ static const u16 e1000_igp_2_cable_length_table[] = #define I82577_CFG_ASSERT_CRS_ON_TX (1 << 15) #define I82577_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift 100/10 */ #define I82577_CTRL_REG 23 -#define I82577_CTRL_DOWNSHIFT_MASK (7 << 10) /* 82577 specific PHY registers */ #define I82577_PHY_CTRL_2 18 @@ -95,13 +94,6 @@ static const u16 e1000_igp_2_cable_length_table[] = /* BM PHY Copper Specific Control 1 */ #define BM_CS_CTRL1 16 -/* BM PHY Copper Specific Status */ -#define BM_CS_STATUS 17 -#define BM_CS_STATUS_LINK_UP 0x0400 -#define BM_CS_STATUS_RESOLVED 0x0800 -#define BM_CS_STATUS_SPEED_MASK 0xC000 -#define BM_CS_STATUS_SPEED_1000 0x8000 - #define HV_MUX_DATA_CTRL PHY_REG(776, 16) #define HV_MUX_DATA_CTRL_GEN_TO_MAC 0x0400 #define HV_MUX_DATA_CTRL_FORCE_SPEED 0x0004 @@ -164,16 +156,25 @@ s32 e1000e_get_phy_id(struct e1000_hw *hw) * MDIC mode. No harm in trying again in this case since * the PHY ID is unknown at this point anyway */ + ret_val = phy->ops.acquire_phy(hw); + if (ret_val) + goto out; ret_val = e1000_set_mdio_slow_mode_hv(hw, true); if (ret_val) goto out; + phy->ops.release_phy(hw); retry_count++; } out: /* Revert to MDIO fast mode, if applicable */ - if (retry_count) + if (retry_count) { + ret_val = phy->ops.acquire_phy(hw); + if (ret_val) + return ret_val; ret_val = e1000_set_mdio_slow_mode_hv(hw, false); + phy->ops.release_phy(hw); + } return ret_val; } @@ -354,94 +355,173 @@ s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data) } /** - * e1000e_read_phy_reg_igp - Read igp PHY register + * __e1000e_read_phy_reg_igp - Read igp PHY register * @hw: pointer to the HW structure * @offset: register offset to be read * @data: pointer to the read data + * @locked: semaphore has already been acquired or not * * Acquires semaphore, if necessary, then reads the PHY register at offset - * and storing the retrieved information in data. Release any acquired + * and stores the retrieved information in data. Release any acquired * semaphores before exiting. **/ -s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data) +static s32 __e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data, + bool locked) { - s32 ret_val; + s32 ret_val = 0; - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - return ret_val; + if (!locked) { + if (!(hw->phy.ops.acquire_phy)) + goto out; + + ret_val = hw->phy.ops.acquire_phy(hw); + if (ret_val) + goto out; + } if (offset > MAX_PHY_MULTI_PAGE_REG) { ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, (u16)offset); - if (ret_val) { - hw->phy.ops.release_phy(hw); - return ret_val; - } + if (ret_val) + goto release; } ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); - - hw->phy.ops.release_phy(hw); + data); +release: + if (!locked) + hw->phy.ops.release_phy(hw); +out: return ret_val; } /** + * e1000e_read_phy_reg_igp - Read igp PHY register + * @hw: pointer to the HW structure + * @offset: register offset to be read + * @data: pointer to the read data + * + * Acquires semaphore then reads the PHY register at offset and stores the + * retrieved information in data. + * Release the acquired semaphore before exiting. + **/ +s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data) +{ + return __e1000e_read_phy_reg_igp(hw, offset, data, false); +} + +/** + * e1000e_read_phy_reg_igp_locked - Read igp PHY register + * @hw: pointer to the HW structure + * @offset: register offset to be read + * @data: pointer to the read data + * + * Reads the PHY register at offset and stores the retrieved information + * in data. Assumes semaphore already acquired. + **/ +s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data) +{ + return __e1000e_read_phy_reg_igp(hw, offset, data, true); +} + +/** * e1000e_write_phy_reg_igp - Write igp PHY register * @hw: pointer to the HW structure * @offset: register offset to write to * @data: data to write at register offset + * @locked: semaphore has already been acquired or not * * Acquires semaphore, if necessary, then writes the data to PHY register * at the offset. Release any acquired semaphores before exiting. **/ -s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data) +static s32 __e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data, + bool locked) { - s32 ret_val; + s32 ret_val = 0; - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - return ret_val; + if (!locked) { + if (!(hw->phy.ops.acquire_phy)) + goto out; + + ret_val = hw->phy.ops.acquire_phy(hw); + if (ret_val) + goto out; + } if (offset > MAX_PHY_MULTI_PAGE_REG) { ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, (u16)offset); - if (ret_val) { - hw->phy.ops.release_phy(hw); - return ret_val; - } + if (ret_val) + goto release; } ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, data); - hw->phy.ops.release_phy(hw); +release: + if (!locked) + hw->phy.ops.release_phy(hw); +out: return ret_val; } /** - * e1000e_read_kmrn_reg - Read kumeran register + * e1000e_write_phy_reg_igp - Write igp PHY register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Acquires semaphore then writes the data to PHY register + * at the offset. Release any acquired semaphores before exiting. + **/ +s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data) +{ + return __e1000e_write_phy_reg_igp(hw, offset, data, false); +} + +/** + * e1000e_write_phy_reg_igp_locked - Write igp PHY register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Writes the data to PHY register at the offset. + * Assumes semaphore already acquired. + **/ +s32 e1000e_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data) +{ + return __e1000e_write_phy_reg_igp(hw, offset, data, true); +} + +/** + * __e1000_read_kmrn_reg - Read kumeran register * @hw: pointer to the HW structure * @offset: register offset to be read * @data: pointer to the read data + * @locked: semaphore has already been acquired or not * * Acquires semaphore, if necessary. Then reads the PHY register at offset * using the kumeran interface. The information retrieved is stored in data. * Release any acquired semaphores before exiting. **/ -s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data) +static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data, + bool locked) { u32 kmrnctrlsta; - s32 ret_val; + s32 ret_val = 0; - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - return ret_val; + if (!locked) { + if (!(hw->phy.ops.acquire_phy)) + goto out; + + ret_val = hw->phy.ops.acquire_phy(hw); + if (ret_val) + goto out; + } kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; @@ -452,41 +532,111 @@ s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data) kmrnctrlsta = er32(KMRNCTRLSTA); *data = (u16)kmrnctrlsta; - hw->phy.ops.release_phy(hw); + if (!locked) + hw->phy.ops.release_phy(hw); +out: return ret_val; } /** - * e1000e_write_kmrn_reg - Write kumeran register + * e1000e_read_kmrn_reg - Read kumeran register + * @hw: pointer to the HW structure + * @offset: register offset to be read + * @data: pointer to the read data + * + * Acquires semaphore then reads the PHY register at offset using the + * kumeran interface. The information retrieved is stored in data. + * Release the acquired semaphore before exiting. + **/ +s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data) +{ + return __e1000_read_kmrn_reg(hw, offset, data, false); +} + +/** + * e1000e_read_kmrn_reg_locked - Read kumeran register + * @hw: pointer to the HW structure + * @offset: register offset to be read + * @data: pointer to the read data + * + * Reads the PHY register at offset using the kumeran interface. The + * information retrieved is stored in data. + * Assumes semaphore already acquired. + **/ +s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data) +{ + return __e1000_read_kmrn_reg(hw, offset, data, true); +} + +/** + * __e1000_write_kmrn_reg - Write kumeran register * @hw: pointer to the HW structure * @offset: register offset to write to * @data: data to write at register offset + * @locked: semaphore has already been acquired or not * * Acquires semaphore, if necessary. Then write the data to PHY register * at the offset using the kumeran interface. Release any acquired semaphores * before exiting. **/ -s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data) +static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data, + bool locked) { u32 kmrnctrlsta; - s32 ret_val; + s32 ret_val = 0; - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - return ret_val; + if (!locked) { + if (!(hw->phy.ops.acquire_phy)) + goto out; + + ret_val = hw->phy.ops.acquire_phy(hw); + if (ret_val) + goto out; + } kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & E1000_KMRNCTRLSTA_OFFSET) | data; ew32(KMRNCTRLSTA, kmrnctrlsta); udelay(2); - hw->phy.ops.release_phy(hw); + if (!locked) + hw->phy.ops.release_phy(hw); + +out: return ret_val; } /** + * e1000e_write_kmrn_reg - Write kumeran register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Acquires semaphore then writes the data to the PHY register at the offset + * using the kumeran interface. Release the acquired semaphore before exiting. + **/ +s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data) +{ + return __e1000_write_kmrn_reg(hw, offset, data, false); +} + +/** + * e1000e_write_kmrn_reg_locked - Write kumeran register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Write the data to PHY register at the offset using the kumeran interface. + * Assumes semaphore already acquired. + **/ +s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data) +{ + return __e1000_write_kmrn_reg(hw, offset, data, true); +} + +/** * e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link * @hw: pointer to the HW structure * @@ -509,15 +659,6 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw) phy_data |= I82577_CFG_ENABLE_DOWNSHIFT; ret_val = phy->ops.write_phy_reg(hw, I82577_CFG_REG, phy_data); - if (ret_val) - goto out; - - /* Set number of link attempts before downshift */ - ret_val = phy->ops.read_phy_reg(hw, I82577_CTRL_REG, &phy_data); - if (ret_val) - goto out; - phy_data &= ~I82577_CTRL_DOWNSHIFT_MASK; - ret_val = phy->ops.write_phy_reg(hw, I82577_CTRL_REG, phy_data); out: return ret_val; @@ -2105,6 +2246,10 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) u32 page = offset >> IGP_PAGE_SHIFT; u32 page_shift = 0; + ret_val = hw->phy.ops.acquire_phy(hw); + if (ret_val) + return ret_val; + /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, @@ -2112,10 +2257,6 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) goto out; } - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - goto out; - hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset); if (offset > MAX_PHY_MULTI_PAGE_REG) { @@ -2135,18 +2276,15 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) /* Page is shifted left, PHY expects (page x 32) */ ret_val = e1000e_write_phy_reg_mdic(hw, page_select, (page << page_shift)); - if (ret_val) { - hw->phy.ops.release_phy(hw); + if (ret_val) goto out; - } } ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, data); - hw->phy.ops.release_phy(hw); - out: + hw->phy.ops.release_phy(hw); return ret_val; } @@ -2167,6 +2305,10 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) u32 page = offset >> IGP_PAGE_SHIFT; u32 page_shift = 0; + ret_val = hw->phy.ops.acquire_phy(hw); + if (ret_val) + return ret_val; + /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, @@ -2174,10 +2316,6 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) goto out; } - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - goto out; - hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset); if (offset > MAX_PHY_MULTI_PAGE_REG) { @@ -2197,17 +2335,14 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) /* Page is shifted left, PHY expects (page x 32) */ ret_val = e1000e_write_phy_reg_mdic(hw, page_select, (page << page_shift)); - if (ret_val) { - hw->phy.ops.release_phy(hw); + if (ret_val) goto out; - } } ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, data); - hw->phy.ops.release_phy(hw); - out: + hw->phy.ops.release_phy(hw); return ret_val; } @@ -2226,17 +2361,17 @@ s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data) s32 ret_val; u16 page = (u16)(offset >> IGP_PAGE_SHIFT); + ret_val = hw->phy.ops.acquire_phy(hw); + if (ret_val) + return ret_val; + /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, true); - return ret_val; + goto out; } - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - return ret_val; - hw->phy.addr = 1; if (offset > MAX_PHY_MULTI_PAGE_REG) { @@ -2245,16 +2380,14 @@ s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data) ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT, page); - if (ret_val) { - hw->phy.ops.release_phy(hw); - return ret_val; - } + if (ret_val) + goto out; } ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, data); +out: hw->phy.ops.release_phy(hw); - return ret_val; } @@ -2272,17 +2405,17 @@ s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data) s32 ret_val; u16 page = (u16)(offset >> IGP_PAGE_SHIFT); + ret_val = hw->phy.ops.acquire_phy(hw); + if (ret_val) + return ret_val; + /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, false); - return ret_val; + goto out; } - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - return ret_val; - hw->phy.addr = 1; if (offset > MAX_PHY_MULTI_PAGE_REG) { @@ -2290,17 +2423,15 @@ s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data) ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT, page); - if (ret_val) { - hw->phy.ops.release_phy(hw); - return ret_val; - } + if (ret_val) + goto out; } ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, data); +out: hw->phy.ops.release_phy(hw); - return ret_val; } @@ -2320,6 +2451,8 @@ s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data) * 3) Write the address using the address opcode (0x11) * 4) Read or write the data using the data opcode (0x12) * 5) Restore 769_17.2 to its original value + * + * Assumes semaphore already acquired. **/ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data, bool read) @@ -2327,20 +2460,12 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, s32 ret_val; u16 reg = BM_PHY_REG_NUM(offset); u16 phy_reg = 0; - u8 phy_acquired = 1; - /* Gig must be disabled for MDIO accesses to page 800 */ if ((hw->mac.type == e1000_pchlan) && (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE))) hw_dbg(hw, "Attempting to access page 800 while gig enabled\n"); - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) { - phy_acquired = 0; - goto out; - } - /* All operations in this function are phy address 1 */ hw->phy.addr = 1; @@ -2397,8 +2522,6 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); out: - if (phy_acquired == 1) - hw->phy.ops.release_phy(hw); return ret_val; } @@ -2439,52 +2562,63 @@ static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) return 0; } +/** + * e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode + * @hw: pointer to the HW structure + * @slow: true for slow mode, false for normal mode + * + * Assumes semaphore already acquired. + **/ s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow) { s32 ret_val = 0; u16 data = 0; - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - return ret_val; - /* Set MDIO mode - page 769, register 16: 0x2580==slow, 0x2180==fast */ hw->phy.addr = 1; ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT)); - if (ret_val) { - hw->phy.ops.release_phy(hw); - return ret_val; - } + if (ret_val) + goto out; + ret_val = e1000e_write_phy_reg_mdic(hw, BM_CS_CTRL1, (0x2180 | (slow << 10))); + if (ret_val) + goto out; /* dummy read when reverting to fast mode - throw away result */ if (!slow) - e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data); - - hw->phy.ops.release_phy(hw); + ret_val = e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data); +out: return ret_val; } /** - * e1000_read_phy_reg_hv - Read HV PHY register + * __e1000_read_phy_reg_hv - Read HV PHY register * @hw: pointer to the HW structure * @offset: register offset to be read * @data: pointer to the read data + * @locked: semaphore has already been acquired or not * * Acquires semaphore, if necessary, then reads the PHY register at offset - * and storing the retrieved information in data. Release any acquired + * and stores the retrieved information in data. Release any acquired * semaphore before exiting. **/ -s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data) +static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, + bool locked) { s32 ret_val; u16 page = BM_PHY_REG_PAGE(offset); u16 reg = BM_PHY_REG_NUM(offset); bool in_slow_mode = false; + if (!locked) { + ret_val = hw->phy.ops.acquire_phy(hw); + if (ret_val) + return ret_val; + } + /* Workaround failure in MDIO access while cable is disconnected */ if ((hw->phy.type == e1000_phy_82577) && !(er32(STATUS) & E1000_STATUS_LU)) { @@ -2508,63 +2642,92 @@ s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data) goto out; } - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - goto out; - hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); if (page == HV_INTC_FC_PAGE_START) page = 0; if (reg > MAX_PHY_MULTI_PAGE_REG) { - if ((hw->phy.type != e1000_phy_82578) || - ((reg != I82578_ADDR_REG) && - (reg != I82578_ADDR_REG + 1))) { - u32 phy_addr = hw->phy.addr; - - hw->phy.addr = 1; - - /* Page is shifted left, PHY expects (page x 32) */ - ret_val = e1000e_write_phy_reg_mdic(hw, - IGP01E1000_PHY_PAGE_SELECT, - (page << IGP_PAGE_SHIFT)); - if (ret_val) { - hw->phy.ops.release_phy(hw); - goto out; - } - hw->phy.addr = phy_addr; - } + u32 phy_addr = hw->phy.addr; + + hw->phy.addr = 1; + + /* Page is shifted left, PHY expects (page x 32) */ + ret_val = e1000e_write_phy_reg_mdic(hw, + IGP01E1000_PHY_PAGE_SELECT, + (page << IGP_PAGE_SHIFT)); + hw->phy.addr = phy_addr; + + if (ret_val) + goto out; } ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, data); - hw->phy.ops.release_phy(hw); - out: /* Revert to MDIO fast mode, if applicable */ if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) - ret_val = e1000_set_mdio_slow_mode_hv(hw, false); + ret_val |= e1000_set_mdio_slow_mode_hv(hw, false); + + if (!locked) + hw->phy.ops.release_phy(hw); return ret_val; } /** - * e1000_write_phy_reg_hv - Write HV PHY register + * e1000_read_phy_reg_hv - Read HV PHY register + * @hw: pointer to the HW structure + * @offset: register offset to be read + * @data: pointer to the read data + * + * Acquires semaphore then reads the PHY register at offset and stores + * the retrieved information in data. Release the acquired semaphore + * before exiting. + **/ +s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data) +{ + return __e1000_read_phy_reg_hv(hw, offset, data, false); +} + +/** + * e1000_read_phy_reg_hv_locked - Read HV PHY register + * @hw: pointer to the HW structure + * @offset: register offset to be read + * @data: pointer to the read data + * + * Reads the PHY register at offset and stores the retrieved information + * in data. Assumes semaphore already acquired. + **/ +s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data) +{ + return __e1000_read_phy_reg_hv(hw, offset, data, true); +} + +/** + * __e1000_write_phy_reg_hv - Write HV PHY register * @hw: pointer to the HW structure * @offset: register offset to write to * @data: data to write at register offset + * @locked: semaphore has already been acquired or not * * Acquires semaphore, if necessary, then writes the data to PHY register * at the offset. Release any acquired semaphores before exiting. **/ -s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data) +static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, + bool locked) { s32 ret_val; u16 page = BM_PHY_REG_PAGE(offset); u16 reg = BM_PHY_REG_NUM(offset); bool in_slow_mode = false; + if (!locked) { + ret_val = hw->phy.ops.acquire_phy(hw); + if (ret_val) + return ret_val; + } + /* Workaround failure in MDIO access while cable is disconnected */ if ((hw->phy.type == e1000_phy_82577) && !(er32(STATUS) & E1000_STATUS_LU)) { @@ -2588,10 +2751,6 @@ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data) goto out; } - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - goto out; - hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); if (page == HV_INTC_FC_PAGE_START) @@ -2607,50 +2766,70 @@ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data) ((MAX_PHY_REG_ADDRESS & reg) == 0) && (data & (1 << 11))) { u16 data2 = 0x7EFF; - hw->phy.ops.release_phy(hw); ret_val = e1000_access_phy_debug_regs_hv(hw, (1 << 6) | 0x3, &data2, false); if (ret_val) goto out; - - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - goto out; } if (reg > MAX_PHY_MULTI_PAGE_REG) { - if ((hw->phy.type != e1000_phy_82578) || - ((reg != I82578_ADDR_REG) && - (reg != I82578_ADDR_REG + 1))) { - u32 phy_addr = hw->phy.addr; - - hw->phy.addr = 1; - - /* Page is shifted left, PHY expects (page x 32) */ - ret_val = e1000e_write_phy_reg_mdic(hw, - IGP01E1000_PHY_PAGE_SELECT, - (page << IGP_PAGE_SHIFT)); - if (ret_val) { - hw->phy.ops.release_phy(hw); - goto out; - } - hw->phy.addr = phy_addr; - } + u32 phy_addr = hw->phy.addr; + + hw->phy.addr = 1; + + /* Page is shifted left, PHY expects (page x 32) */ + ret_val = e1000e_write_phy_reg_mdic(hw, + IGP01E1000_PHY_PAGE_SELECT, + (page << IGP_PAGE_SHIFT)); + hw->phy.addr = phy_addr; + + if (ret_val) + goto out; } ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, data); - hw->phy.ops.release_phy(hw); out: /* Revert to MDIO fast mode, if applicable */ if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) - ret_val = e1000_set_mdio_slow_mode_hv(hw, false); + ret_val |= e1000_set_mdio_slow_mode_hv(hw, false); + + if (!locked) + hw->phy.ops.release_phy(hw); return ret_val; } /** + * e1000_write_phy_reg_hv - Write HV PHY register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Acquires semaphore then writes the data to PHY register at the offset. + * Release the acquired semaphores before exiting. + **/ +s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data) +{ + return __e1000_write_phy_reg_hv(hw, offset, data, false); +} + +/** + * e1000_write_phy_reg_hv_locked - Write HV PHY register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Writes the data to PHY register at the offset. Assumes semaphore + * already acquired. + **/ +s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data) +{ + return __e1000_write_phy_reg_hv(hw, offset, data, true); +} + +/** * e1000_get_phy_addr_for_hv_page - Get PHY adrress based on page * @page: page to be accessed **/ @@ -2671,10 +2850,9 @@ static u32 e1000_get_phy_addr_for_hv_page(u32 page) * @data: pointer to the data to be read or written * @read: determines if operation is read or written * - * Acquires semaphore, if necessary, then reads the PHY register at offset - * and storing the retreived information in data. Release any acquired - * semaphores before exiting. Note that the procedure to read these regs - * uses the address port and data port to read/write. + * Reads the PHY register at offset and stores the retreived information + * in data. Assumes semaphore already acquired. Note that the procedure + * to read these regs uses the address port and data port to read/write. **/ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, u16 *data, bool read) @@ -2682,20 +2860,12 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, s32 ret_val; u32 addr_reg = 0; u32 data_reg = 0; - u8 phy_acquired = 1; /* This takes care of the difference with desktop vs mobile phy */ addr_reg = (hw->phy.type == e1000_phy_82578) ? I82578_ADDR_REG : I82577_ADDR_REG; data_reg = addr_reg + 1; - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) { - hw_dbg(hw, "Could not acquire PHY\n"); - phy_acquired = 0; - goto out; - } - /* All operations in this function are phy address 2 */ hw->phy.addr = 2; @@ -2718,8 +2888,6 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, } out: - if (phy_acquired == 1) - hw->phy.ops.release_phy(hw); return ret_val; } diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index 9c950bb5e90c..f7d9ac8324cb 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -223,24 +223,25 @@ struct ethoc_bd { u32 addr; }; -static u32 ethoc_read(struct ethoc *dev, loff_t offset) +static inline u32 ethoc_read(struct ethoc *dev, loff_t offset) { return ioread32(dev->iobase + offset); } -static void ethoc_write(struct ethoc *dev, loff_t offset, u32 data) +static inline void ethoc_write(struct ethoc *dev, loff_t offset, u32 data) { iowrite32(data, dev->iobase + offset); } -static void ethoc_read_bd(struct ethoc *dev, int index, struct ethoc_bd *bd) +static inline void ethoc_read_bd(struct ethoc *dev, int index, + struct ethoc_bd *bd) { loff_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd)); bd->stat = ethoc_read(dev, offset + 0); bd->addr = ethoc_read(dev, offset + 4); } -static void ethoc_write_bd(struct ethoc *dev, int index, +static inline void ethoc_write_bd(struct ethoc *dev, int index, const struct ethoc_bd *bd) { loff_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd)); @@ -248,33 +249,33 @@ static void ethoc_write_bd(struct ethoc *dev, int index, ethoc_write(dev, offset + 4, bd->addr); } -static void ethoc_enable_irq(struct ethoc *dev, u32 mask) +static inline void ethoc_enable_irq(struct ethoc *dev, u32 mask) { u32 imask = ethoc_read(dev, INT_MASK); imask |= mask; ethoc_write(dev, INT_MASK, imask); } -static void ethoc_disable_irq(struct ethoc *dev, u32 mask) +static inline void ethoc_disable_irq(struct ethoc *dev, u32 mask) { u32 imask = ethoc_read(dev, INT_MASK); imask &= ~mask; ethoc_write(dev, INT_MASK, imask); } -static void ethoc_ack_irq(struct ethoc *dev, u32 mask) +static inline void ethoc_ack_irq(struct ethoc *dev, u32 mask) { ethoc_write(dev, INT_SOURCE, mask); } -static void ethoc_enable_rx_and_tx(struct ethoc *dev) +static inline void ethoc_enable_rx_and_tx(struct ethoc *dev) { u32 mode = ethoc_read(dev, MODER); mode |= MODER_RXEN | MODER_TXEN; ethoc_write(dev, MODER, mode); } -static void ethoc_disable_rx_and_tx(struct ethoc *dev) +static inline void ethoc_disable_rx_and_tx(struct ethoc *dev) { u32 mode = ethoc_read(dev, MODER); mode &= ~(MODER_RXEN | MODER_TXEN); @@ -508,7 +509,7 @@ static irqreturn_t ethoc_interrupt(int irq, void *dev_id) return IRQ_NONE; } - ethoc_ack_irq(priv, INT_MASK_ALL); + ethoc_ack_irq(priv, pending); if (pending & INT_MASK_BUSY) { dev_err(&dev->dev, "packet dropped\n"); diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 29234380e6c6..16a1d58419d9 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1654,7 +1654,7 @@ static const struct net_device_ops fec_netdev_ops = { * * index is only used in legacy code */ -int __init fec_enet_init(struct net_device *dev, int index) +static int fec_enet_init(struct net_device *dev, int index) { struct fec_enet_private *fep = netdev_priv(dev); struct bufdesc *cbd_base; diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index e1da4666f204..3116601dbfea 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -5821,10 +5821,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i dev->dev_addr); dev_printk(KERN_ERR, &pci_dev->dev, "Please complain to your hardware vendor. Switching to a random MAC.\n"); - dev->dev_addr[0] = 0x00; - dev->dev_addr[1] = 0x00; - dev->dev_addr[2] = 0x6c; - get_random_bytes(&dev->dev_addr[3], 3); + random_ether_addr(dev->dev_addr); } dprintk(KERN_DEBUG "%s: MAC Address %pM\n", diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index 6ac464866972..efbf67689eca 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -427,3 +427,4 @@ void fsl_pq_mdio_exit(void) of_unregister_platform_driver(&fsl_pq_mdio_driver); } module_exit(fsl_pq_mdio_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/ibm_newemac/emac.h b/drivers/net/ibm_newemac/emac.h index d34adf99fc6a..8a61b597a169 100644 --- a/drivers/net/ibm_newemac/emac.h +++ b/drivers/net/ibm_newemac/emac.h @@ -263,8 +263,8 @@ struct emac_regs { /* EMACx_TRTR */ -#define EMAC_TRTR_SHIFT_EMAC4 27 -#define EMAC_TRTR_SHIFT 24 +#define EMAC_TRTR_SHIFT_EMAC4 24 +#define EMAC_TRTR_SHIFT 27 /* EMAC specific TX descriptor control fields (write access) */ #define EMAC_TX_CTRL_GFCS 0x0200 diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 801f088c134f..030913f8bd26 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -98,12 +98,13 @@ static void ri_tasklet(unsigned long dev) stats->tx_packets++; stats->tx_bytes +=skb->len; - skb->dev = __dev_get_by_index(&init_net, skb->iif); + skb->dev = dev_get_by_index(&init_net, skb->iif); if (!skb->dev) { dev_kfree_skb(skb); stats->tx_dropped++; break; } + dev_put(skb->dev); skb->iif = _dev->ifindex; if (from & AT_EGRESS) { diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index deaea8fa1032..b243ed3b0c36 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -732,7 +732,7 @@ static int igb_set_ringparam(struct net_device *netdev, { struct igb_adapter *adapter = netdev_priv(netdev); struct igb_ring *temp_ring; - int i, err; + int i, err = 0; u32 new_rx_count, new_tx_count; if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) @@ -752,18 +752,30 @@ static int igb_set_ringparam(struct net_device *netdev, return 0; } + while (test_and_set_bit(__IGB_RESETTING, &adapter->state)) + msleep(1); + + if (!netif_running(adapter->netdev)) { + for (i = 0; i < adapter->num_tx_queues; i++) + adapter->tx_ring[i].count = new_tx_count; + for (i = 0; i < adapter->num_rx_queues; i++) + adapter->rx_ring[i].count = new_rx_count; + adapter->tx_ring_count = new_tx_count; + adapter->rx_ring_count = new_rx_count; + goto clear_reset; + } + if (adapter->num_tx_queues > adapter->num_rx_queues) temp_ring = vmalloc(adapter->num_tx_queues * sizeof(struct igb_ring)); else temp_ring = vmalloc(adapter->num_rx_queues * sizeof(struct igb_ring)); - if (!temp_ring) - return -ENOMEM; - while (test_and_set_bit(__IGB_RESETTING, &adapter->state)) - msleep(1); + if (!temp_ring) { + err = -ENOMEM; + goto clear_reset; + } - if (netif_running(adapter->netdev)) - igb_down(adapter); + igb_down(adapter); /* * We can't just free everything and then setup again, @@ -820,14 +832,11 @@ static int igb_set_ringparam(struct net_device *netdev, adapter->rx_ring_count = new_rx_count; } - - err = 0; err_setup: - if (netif_running(adapter->netdev)) - igb_up(adapter); - - clear_bit(__IGB_RESETTING, &adapter->state); + igb_up(adapter); vfree(temp_ring); +clear_reset: + clear_bit(__IGB_RESETTING, &adapter->state); return err; } diff --git a/drivers/net/igbvf/ethtool.c b/drivers/net/igbvf/ethtool.c index ee17a097d1ca..c68265bd0d1a 100644 --- a/drivers/net/igbvf/ethtool.c +++ b/drivers/net/igbvf/ethtool.c @@ -279,7 +279,7 @@ static int igbvf_set_ringparam(struct net_device *netdev, { struct igbvf_adapter *adapter = netdev_priv(netdev); struct igbvf_ring *temp_ring; - int err; + int err = 0; u32 new_rx_count, new_tx_count; if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) @@ -299,15 +299,22 @@ static int igbvf_set_ringparam(struct net_device *netdev, return 0; } - temp_ring = vmalloc(sizeof(struct igbvf_ring)); - if (!temp_ring) - return -ENOMEM; - while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state)) msleep(1); - if (netif_running(adapter->netdev)) - igbvf_down(adapter); + if (!netif_running(adapter->netdev)) { + adapter->tx_ring->count = new_tx_count; + adapter->rx_ring->count = new_rx_count; + goto clear_reset; + } + + temp_ring = vmalloc(sizeof(struct igbvf_ring)); + if (!temp_ring) { + err = -ENOMEM; + goto clear_reset; + } + + igbvf_down(adapter); /* * We can't just free everything and then setup again, @@ -339,14 +346,11 @@ static int igbvf_set_ringparam(struct net_device *netdev, memcpy(adapter->rx_ring, temp_ring,sizeof(struct igbvf_ring)); } - - err = 0; err_setup: - if (netif_running(adapter->netdev)) - igbvf_up(adapter); - - clear_bit(__IGBVF_RESETTING, &adapter->state); + igbvf_up(adapter); vfree(temp_ring); +clear_reset: + clear_bit(__IGBVF_RESETTING, &adapter->state); return err; } diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index fa314cb005a4..856c18c207f3 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -798,7 +798,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev, { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_ring *temp_tx_ring, *temp_rx_ring; - int i, err; + int i, err = 0; u32 new_rx_count, new_tx_count; bool need_update = false; @@ -822,6 +822,16 @@ static int ixgbe_set_ringparam(struct net_device *netdev, while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) msleep(1); + if (!netif_running(adapter->netdev)) { + for (i = 0; i < adapter->num_tx_queues; i++) + adapter->tx_ring[i].count = new_tx_count; + for (i = 0; i < adapter->num_rx_queues; i++) + adapter->rx_ring[i].count = new_rx_count; + adapter->tx_ring_count = new_tx_count; + adapter->rx_ring_count = new_rx_count; + goto err_setup; + } + temp_tx_ring = kcalloc(adapter->num_tx_queues, sizeof(struct ixgbe_ring), GFP_KERNEL); if (!temp_tx_ring) { @@ -879,8 +889,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev, /* if rings need to be updated, here's the place to do it in one shot */ if (need_update) { - if (netif_running(netdev)) - ixgbe_down(adapter); + ixgbe_down(adapter); /* tx */ if (new_tx_count != adapter->tx_ring_count) { @@ -897,13 +906,8 @@ static int ixgbe_set_ringparam(struct net_device *netdev, temp_rx_ring = NULL; adapter->rx_ring_count = new_rx_count; } - } - - /* success! */ - err = 0; - if (netif_running(netdev)) ixgbe_up(adapter); - + } err_setup: clear_bit(__IXGBE_RESETTING, &adapter->state); return err; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index cbb143ca1eb8..a456578b8578 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -44,6 +44,7 @@ #include "ixgbe.h" #include "ixgbe_common.h" +#include "ixgbe_dcb_82599.h" char ixgbe_driver_name[] = "ixgbe"; static const char ixgbe_driver_string[] = @@ -226,6 +227,56 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter, /* tx_buffer_info must be completely set up in the transmit path */ } +/** + * ixgbe_tx_is_paused - check if the tx ring is paused + * @adapter: the ixgbe adapter + * @tx_ring: the corresponding tx_ring + * + * If not in DCB mode, checks TFCS.TXOFF, otherwise, find out the + * corresponding TC of this tx_ring when checking TFCS. + * + * Returns : true if paused + */ +static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter, + struct ixgbe_ring *tx_ring) +{ + u32 txoff = IXGBE_TFCS_TXOFF; + +#ifdef CONFIG_IXGBE_DCB + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { + int tc; + int reg_idx = tx_ring->reg_idx; + int dcb_i = adapter->ring_feature[RING_F_DCB].indices; + + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + tc = reg_idx >> 2; + txoff = IXGBE_TFCS_TXOFF0; + } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + tc = 0; + txoff = IXGBE_TFCS_TXOFF; + if (dcb_i == 8) { + /* TC0, TC1 */ + tc = reg_idx >> 5; + if (tc == 2) /* TC2, TC3 */ + tc += (reg_idx - 64) >> 4; + else if (tc == 3) /* TC4, TC5, TC6, TC7 */ + tc += 1 + ((reg_idx - 96) >> 3); + } else if (dcb_i == 4) { + /* TC0, TC1 */ + tc = reg_idx >> 6; + if (tc == 1) { + tc += (reg_idx - 64) >> 5; + if (tc == 2) /* TC2, TC3 */ + tc += (reg_idx - 96) >> 4; + } + } + } + txoff <<= tc; + } +#endif + return IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & txoff; +} + static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter, struct ixgbe_ring *tx_ring, unsigned int eop) @@ -237,7 +288,7 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter, adapter->detect_tx_hung = false; if (tx_ring->tx_buffer_info[eop].time_stamp && time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) && - !(IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF)) { + !ixgbe_tx_is_paused(adapter, tx_ring)) { /* detected Tx unit hang */ union ixgbe_adv_tx_desc *tx_desc; tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop); @@ -412,19 +463,23 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter, u32 txctrl; int cpu = get_cpu(); int q = tx_ring - adapter->tx_ring; + struct ixgbe_hw *hw = &adapter->hw; if (tx_ring->cpu != cpu) { - txctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q)); if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(q)); txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK; txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu); + txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN; + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(q), txctrl); } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(q)); txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599; txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) << - IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599); + IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599); + txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN; + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(q), txctrl); } - txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q), txctrl); tx_ring->cpu = cpu; } put_cpu(); @@ -1913,11 +1968,25 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter) break; } } + if (hw->mac.type == ixgbe_mac_82599EB) { + u32 rttdcs; + + /* disable the arbiter while setting MTQC */ + rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS); + rttdcs |= IXGBE_RTTDCS_ARBDIS; + IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); + /* We enable 8 traffic classes, DCB only */ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) IXGBE_WRITE_REG(hw, IXGBE_MTQC, (IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ)); + else + IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB); + + /* re-eable the arbiter */ + rttdcs &= ~IXGBE_RTTDCS_ARBDIS; + IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); } } @@ -2471,7 +2540,10 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter) ixgbe_restore_vlan(adapter); #ifdef CONFIG_IXGBE_DCB if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { - netif_set_gso_max_size(netdev, 32768); + if (hw->mac.type == ixgbe_mac_82598EB) + netif_set_gso_max_size(netdev, 32768); + else + netif_set_gso_max_size(netdev, 65536); ixgbe_configure_dcb(adapter); } else { netif_set_gso_max_size(netdev, 65536); @@ -5922,6 +5994,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev) } else { pci_set_master(pdev); pci_restore_state(pdev); + pci_save_state(pdev); pci_wake_from_d3(pdev, false); diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c index 237835864357..a23f739d222f 100644 --- a/drivers/net/ks8851.c +++ b/drivers/net/ks8851.c @@ -171,6 +171,36 @@ static void ks8851_wrreg16(struct ks8851_net *ks, unsigned reg, unsigned val) } /** + * ks8851_wrreg8 - write 8bit register value to chip + * @ks: The chip state + * @reg: The register address + * @val: The value to write + * + * Issue a write to put the value @val into the register specified in @reg. + */ +static void ks8851_wrreg8(struct ks8851_net *ks, unsigned reg, unsigned val) +{ + struct spi_transfer *xfer = &ks->spi_xfer1; + struct spi_message *msg = &ks->spi_msg1; + __le16 txb[2]; + int ret; + int bit; + + bit = 1 << (reg & 3); + + txb[0] = cpu_to_le16(MK_OP(bit, reg) | KS_SPIOP_WR); + txb[1] = val; + + xfer->tx_buf = txb; + xfer->rx_buf = NULL; + xfer->len = 3; + + ret = spi_sync(ks->spidev, msg); + if (ret < 0) + ks_err(ks, "spi_sync() failed\n"); +} + +/** * ks8851_rx_1msg - select whether to use one or two messages for spi read * @ks: The device structure * @@ -322,13 +352,12 @@ static void ks8851_soft_reset(struct ks8851_net *ks, unsigned op) static int ks8851_write_mac_addr(struct net_device *dev) { struct ks8851_net *ks = netdev_priv(dev); - u16 *mcp = (u16 *)dev->dev_addr; + int i; mutex_lock(&ks->lock); - ks8851_wrreg16(ks, KS_MARL, mcp[0]); - ks8851_wrreg16(ks, KS_MARM, mcp[1]); - ks8851_wrreg16(ks, KS_MARH, mcp[2]); + for (i = 0; i < ETH_ALEN; i++) + ks8851_wrreg8(ks, KS_MAR(i), dev->dev_addr[i]); mutex_unlock(&ks->lock); @@ -951,7 +980,7 @@ static void ks8851_set_rx_mode(struct net_device *dev) mcptr = mcptr->next; } - rxctrl.rxcr1 = RXCR1_RXME | RXCR1_RXAE | RXCR1_RXPAFMA; + rxctrl.rxcr1 = RXCR1_RXME | RXCR1_RXPAFMA; } else { /* just accept broadcast / unicast */ rxctrl.rxcr1 = RXCR1_RXPAFMA; @@ -1239,6 +1268,9 @@ static int __devinit ks8851_probe(struct spi_device *spi) ndev->netdev_ops = &ks8851_netdev_ops; ndev->irq = spi->irq; + /* issue a global soft reset to reset the device. */ + ks8851_soft_reset(ks, GRR_GSR); + /* simple check for a valid chip being connected to the bus */ if ((ks8851_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) { diff --git a/drivers/net/ks8851.h b/drivers/net/ks8851.h index 85abe147afbf..f52c312cc356 100644 --- a/drivers/net/ks8851.h +++ b/drivers/net/ks8851.h @@ -16,6 +16,7 @@ #define CCR_32PIN (1 << 0) /* MAC address registers */ +#define KS_MAR(_m) 0x15 - (_m) #define KS_MARL 0x10 #define KS_MARM 0x12 #define KS_MARH 0x14 diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c index 0be14d702beb..c146304d8d6c 100644 --- a/drivers/net/ks8851_mll.c +++ b/drivers/net/ks8851_mll.c @@ -568,6 +568,16 @@ static inline void ks_outblk(struct ks_net *ks, u16 *wptr, u32 len) iowrite16(*wptr++, ks->hw_addr); } +static void ks_disable_int(struct ks_net *ks) +{ + ks_wrreg16(ks, KS_IER, 0x0000); +} /* ks_disable_int */ + +static void ks_enable_int(struct ks_net *ks) +{ + ks_wrreg16(ks, KS_IER, ks->rc_ier); +} /* ks_enable_int */ + /** * ks_tx_fifo_space - return the available hardware buffer size. * @ks: The chip information @@ -681,6 +691,47 @@ static void ks_soft_reset(struct ks_net *ks, unsigned op) } +void ks_enable_qmu(struct ks_net *ks) +{ + u16 w; + + w = ks_rdreg16(ks, KS_TXCR); + /* Enables QMU Transmit (TXCR). */ + ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE); + + /* + * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame + * Enable + */ + + w = ks_rdreg16(ks, KS_RXQCR); + ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE); + + /* Enables QMU Receive (RXCR1). */ + w = ks_rdreg16(ks, KS_RXCR1); + ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE); + ks->enabled = true; +} /* ks_enable_qmu */ + +static void ks_disable_qmu(struct ks_net *ks) +{ + u16 w; + + w = ks_rdreg16(ks, KS_TXCR); + + /* Disables QMU Transmit (TXCR). */ + w &= ~TXCR_TXE; + ks_wrreg16(ks, KS_TXCR, w); + + /* Disables QMU Receive (RXCR1). */ + w = ks_rdreg16(ks, KS_RXCR1); + w &= ~RXCR1_RXE ; + ks_wrreg16(ks, KS_RXCR1, w); + + ks->enabled = false; + +} /* ks_disable_qmu */ + /** * ks_read_qmu - read 1 pkt data from the QMU. * @ks: The chip information @@ -752,7 +803,7 @@ static void ks_rcv(struct ks_net *ks, struct net_device *netdev) (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) { skb_reserve(skb, 2); /* read data block including CRC 4 bytes */ - ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len + 4); + ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len); skb_put(skb, frame_hdr->len); skb->dev = netdev; skb->protocol = eth_type_trans(skb, netdev); @@ -861,7 +912,7 @@ static int ks_net_open(struct net_device *netdev) ks_dbg(ks, "%s - entry\n", __func__); /* reset the HW */ - err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, ks); + err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, netdev); if (err) { printk(KERN_ERR "Failed to request IRQ: %d: %d\n", @@ -869,6 +920,15 @@ static int ks_net_open(struct net_device *netdev) return err; } + /* wake up powermode to normal mode */ + ks_set_powermode(ks, PMECR_PM_NORMAL); + mdelay(1); /* wait for normal mode to take effect */ + + ks_wrreg16(ks, KS_ISR, 0xffff); + ks_enable_int(ks); + ks_enable_qmu(ks); + netif_start_queue(ks->netdev); + if (netif_msg_ifup(ks)) ks_dbg(ks, "network device %s up\n", netdev->name); @@ -892,19 +952,14 @@ static int ks_net_stop(struct net_device *netdev) netif_stop_queue(netdev); - kfree(ks->frame_head_info); - mutex_lock(&ks->lock); /* turn off the IRQs and ack any outstanding */ ks_wrreg16(ks, KS_IER, 0x0000); ks_wrreg16(ks, KS_ISR, 0xffff); - /* shutdown RX process */ - ks_wrreg16(ks, KS_RXCR1, 0x0000); - - /* shutdown TX process */ - ks_wrreg16(ks, KS_TXCR, 0x0000); + /* shutdown RX/TX QMU */ + ks_disable_qmu(ks); /* set powermode to soft power down to save power */ ks_set_powermode(ks, PMECR_PM_SOFTDOWN); @@ -929,17 +984,8 @@ static int ks_net_stop(struct net_device *netdev) */ static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len) { - unsigned fid = ks->fid; - - fid = ks->fid; - ks->fid = (ks->fid + 1) & TXFR_TXFID_MASK; - - /* reduce the tx interrupt occurrances. */ - if (!fid) - fid |= TXFR_TXIC; /* irq on completion */ - /* start header at txb[0] to align txw entries */ - ks->txh.txw[0] = cpu_to_le16(fid); + ks->txh.txw[0] = 0; ks->txh.txw[1] = cpu_to_le16(len); /* 1. set sudo-DMA mode */ @@ -957,16 +1003,6 @@ static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len) ; } -static void ks_disable_int(struct ks_net *ks) -{ - ks_wrreg16(ks, KS_IER, 0x0000); -} /* ks_disable_int */ - -static void ks_enable_int(struct ks_net *ks) -{ - ks_wrreg16(ks, KS_IER, ks->rc_ier); -} /* ks_enable_int */ - /** * ks_start_xmit - transmit packet * @skb : The buffer to transmit @@ -1410,25 +1446,6 @@ static int ks_read_selftest(struct ks_net *ks) return ret; } -static void ks_disable(struct ks_net *ks) -{ - u16 w; - - w = ks_rdreg16(ks, KS_TXCR); - - /* Disables QMU Transmit (TXCR). */ - w &= ~TXCR_TXE; - ks_wrreg16(ks, KS_TXCR, w); - - /* Disables QMU Receive (RXCR1). */ - w = ks_rdreg16(ks, KS_RXCR1); - w &= ~RXCR1_RXE ; - ks_wrreg16(ks, KS_RXCR1, w); - - ks->enabled = false; - -} /* ks_disable */ - static void ks_setup(struct ks_net *ks) { u16 w; @@ -1463,7 +1480,7 @@ static void ks_setup(struct ks_net *ks) w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP; ks_wrreg16(ks, KS_TXCR, w); - w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE; + w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE | RXCR1_RXME | RXCR1_RXIPFCC; if (ks->promiscuous) /* bPromiscuous */ w |= (RXCR1_RXAE | RXCR1_RXINVF); @@ -1486,28 +1503,6 @@ static void ks_setup_int(struct ks_net *ks) ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI); } /* ks_setup_int */ -void ks_enable(struct ks_net *ks) -{ - u16 w; - - w = ks_rdreg16(ks, KS_TXCR); - /* Enables QMU Transmit (TXCR). */ - ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE); - - /* - * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame - * Enable - */ - - w = ks_rdreg16(ks, KS_RXQCR); - ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE); - - /* Enables QMU Receive (RXCR1). */ - w = ks_rdreg16(ks, KS_RXCR1); - ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE); - ks->enabled = true; -} /* ks_enable */ - static int ks_hw_init(struct ks_net *ks) { #define MHEADER_SIZE (sizeof(struct type_frame_head) * MAX_RECV_FRAMES) @@ -1612,11 +1607,9 @@ static int __devinit ks8851_probe(struct platform_device *pdev) ks_soft_reset(ks, GRR_GSR); ks_hw_init(ks); - ks_disable(ks); + ks_disable_qmu(ks); ks_setup(ks); ks_setup_int(ks); - ks_enable_int(ks); - ks_enable(ks); memcpy(netdev->dev_addr, ks->mac_addr, 6); data = ks_rdreg16(ks, KS_OBCR); @@ -1658,6 +1651,7 @@ static int __devexit ks8851_remove(struct platform_device *pdev) struct ks_net *ks = netdev_priv(netdev); struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + kfree(ks->frame_head_info); unregister_netdev(netdev); iounmap(ks->hw_addr); free_netdev(netdev); diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c index 61eabcac734c..b3d7d8d77f46 100644 --- a/drivers/net/macsonic.c +++ b/drivers/net/macsonic.c @@ -223,69 +223,73 @@ static int __devinit macsonic_init(struct net_device *dev) return 0; } -static int __devinit mac_onboard_sonic_ethernet_addr(struct net_device *dev) +#define INVALID_MAC(mac) (memcmp(mac, "\x08\x00\x07", 3) && \ + memcmp(mac, "\x00\xA0\x40", 3) && \ + memcmp(mac, "\x00\x80\x19", 3) && \ + memcmp(mac, "\x00\x05\x02", 3)) + +static void __devinit mac_onboard_sonic_ethernet_addr(struct net_device *dev) { struct sonic_local *lp = netdev_priv(dev); const int prom_addr = ONBOARD_SONIC_PROM_BASE; - int i; + unsigned short val; - /* On NuBus boards we can sometimes look in the ROM resources. - No such luck for comm-slot/onboard. */ - for(i = 0; i < 6; i++) - dev->dev_addr[i] = SONIC_READ_PROM(i); + /* + * On NuBus boards we can sometimes look in the ROM resources. + * No such luck for comm-slot/onboard. + * On the PowerBook 520, the PROM base address is a mystery. + */ + if (hwreg_present((void *)prom_addr)) { + int i; + + for (i = 0; i < 6; i++) + dev->dev_addr[i] = SONIC_READ_PROM(i); + if (!INVALID_MAC(dev->dev_addr)) + return; - /* Most of the time, the address is bit-reversed. The NetBSD - source has a rather long and detailed historical account of - why this is so. */ - if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && - memcmp(dev->dev_addr, "\x00\xA0\x40", 3) && - memcmp(dev->dev_addr, "\x00\x80\x19", 3) && - memcmp(dev->dev_addr, "\x00\x05\x02", 3)) + /* + * Most of the time, the address is bit-reversed. The NetBSD + * source has a rather long and detailed historical account of + * why this is so. + */ bit_reverse_addr(dev->dev_addr); - else - return 0; - - /* If we still have what seems to be a bogus address, we'll - look in the CAM. The top entry should be ours. */ - /* Danger! This only works if MacOS has already initialized - the card... */ - if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && - memcmp(dev->dev_addr, "\x00\xA0\x40", 3) && - memcmp(dev->dev_addr, "\x00\x80\x19", 3) && - memcmp(dev->dev_addr, "\x00\x05\x02", 3)) - { - unsigned short val; - - printk(KERN_INFO "macsonic: PROM seems to be wrong, trying CAM entry 15\n"); - - SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); - SONIC_WRITE(SONIC_CEP, 15); - - val = SONIC_READ(SONIC_CAP2); - dev->dev_addr[5] = val >> 8; - dev->dev_addr[4] = val & 0xff; - val = SONIC_READ(SONIC_CAP1); - dev->dev_addr[3] = val >> 8; - dev->dev_addr[2] = val & 0xff; - val = SONIC_READ(SONIC_CAP0); - dev->dev_addr[1] = val >> 8; - dev->dev_addr[0] = val & 0xff; - - printk(KERN_INFO "HW Address from CAM 15: %pM\n", - dev->dev_addr); - } else return 0; - - if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && - memcmp(dev->dev_addr, "\x00\xA0\x40", 3) && - memcmp(dev->dev_addr, "\x00\x80\x19", 3) && - memcmp(dev->dev_addr, "\x00\x05\x02", 3)) - { + if (!INVALID_MAC(dev->dev_addr)) + return; + /* - * Still nonsense ... messed up someplace! + * If we still have what seems to be a bogus address, we'll + * look in the CAM. The top entry should be ours. */ - printk(KERN_ERR "macsonic: ERROR (INVALID MAC)\n"); - return -EIO; - } else return 0; + printk(KERN_WARNING "macsonic: MAC address in PROM seems " + "to be invalid, trying CAM\n"); + } else { + printk(KERN_WARNING "macsonic: cannot read MAC address from " + "PROM, trying CAM\n"); + } + + /* This only works if MacOS has already initialized the card. */ + + SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); + SONIC_WRITE(SONIC_CEP, 15); + + val = SONIC_READ(SONIC_CAP2); + dev->dev_addr[5] = val >> 8; + dev->dev_addr[4] = val & 0xff; + val = SONIC_READ(SONIC_CAP1); + dev->dev_addr[3] = val >> 8; + dev->dev_addr[2] = val & 0xff; + val = SONIC_READ(SONIC_CAP0); + dev->dev_addr[1] = val >> 8; + dev->dev_addr[0] = val & 0xff; + + if (!INVALID_MAC(dev->dev_addr)) + return; + + /* Still nonsense ... messed up someplace! */ + + printk(KERN_WARNING "macsonic: MAC address in CAM entry 15 " + "seems invalid, will use a random MAC\n"); + random_ether_addr(dev->dev_addr); } static int __devinit mac_onboard_sonic_probe(struct net_device *dev) @@ -402,8 +406,7 @@ static int __devinit mac_onboard_sonic_probe(struct net_device *dev) SONIC_WRITE(SONIC_ISR, 0x7fff); /* Now look for the MAC address. */ - if (mac_onboard_sonic_ethernet_addr(dev) != 0) - return -ENODEV; + mac_onboard_sonic_ethernet_addr(dev); /* Shared init code */ return macsonic_init(dev); diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 3aabfd9dd212..2490aa39804c 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -360,6 +360,7 @@ static int macvlan_init(struct net_device *dev) dev->state = (dev->state & ~MACVLAN_STATE_MASK) | (lowerdev->state & MACVLAN_STATE_MASK); dev->features = lowerdev->features & MACVLAN_FEATURES; + dev->gso_max_size = lowerdev->gso_max_size; dev->iflink = lowerdev->ifindex; dev->hard_header_len = lowerdev->hard_header_len; @@ -596,6 +597,7 @@ static int macvlan_device_event(struct notifier_block *unused, case NETDEV_FEAT_CHANGE: list_for_each_entry(vlan, &port->vlans, list) { vlan->dev->features = dev->features & MACVLAN_FEATURES; + vlan->dev->gso_max_size = dev->gso_max_size; netdev_features_change(vlan->dev); } break; diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 5dd7225b178e..291a505fd4fc 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c @@ -1282,6 +1282,7 @@ static struct pci_device_id mlx4_pci_table[] = { { PCI_VDEVICE(MELLANOX, 0x6372) }, /* MT25458 ConnectX EN 10GBASE-T 10GigE */ { PCI_VDEVICE(MELLANOX, 0x675a) }, /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */ { PCI_VDEVICE(MELLANOX, 0x6764) }, /* MT26468 ConnectX EN 10GigE PCIe gen2*/ + { PCI_VDEVICE(MELLANOX, 0x6746) }, /* MT26438 ConnectX EN 40GigE PCIe gen2 5GT/s */ { PCI_VDEVICE(MELLANOX, 0x676e) }, /* MT26478 ConnectX2 40GigE PCIe gen2 */ { 0, } }; diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 6930c87f362e..f3624517cb0e 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -75,7 +75,7 @@ #include "myri10ge_mcp.h" #include "myri10ge_mcp_gen_header.h" -#define MYRI10GE_VERSION_STR "1.5.0-1.432" +#define MYRI10GE_VERSION_STR "1.5.1-1.451" MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); MODULE_AUTHOR("Maintainer: help@myri.com"); @@ -1624,10 +1624,21 @@ myri10ge_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) return 0; } } - if (*ptr == 'R' || *ptr == 'Q') { - /* We've found either an XFP or quad ribbon fiber */ + if (*ptr == '2') + ptr++; + if (*ptr == 'R' || *ptr == 'Q' || *ptr == 'S') { + /* We've found either an XFP, quad ribbon fiber, or SFP+ */ cmd->port = PORT_FIBRE; + cmd->supported |= SUPPORTED_FIBRE; + cmd->advertising |= ADVERTISED_FIBRE; + } else { + cmd->port = PORT_OTHER; } + if (*ptr == 'R' || *ptr == 'S') + cmd->transceiver = XCVR_EXTERNAL; + else + cmd->transceiver = XCVR_INTERNAL; + return 0; } diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 7384f59df615..e1237b802872 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -1163,6 +1163,8 @@ struct netxen_adapter { u32 int_vec_bit; u32 heartbit; + u8 mac_addr[ETH_ALEN]; + struct netxen_adapter_stats stats; struct netxen_recv_context recv_ctx; diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index 7a7177421d7c..17bb3818d84e 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h @@ -419,6 +419,7 @@ enum { #define NETXEN_CRB_ROMUSB \ NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_ROMUSB) #define NETXEN_CRB_I2Q NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_I2Q) +#define NETXEN_CRB_I2C0 NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_I2C0) #define NETXEN_CRB_SMB NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_SMB) #define NETXEN_CRB_MAX NETXEN_PCI_CRB_WINDOW(64) @@ -544,6 +545,8 @@ enum { #define NETXEN_NIU_TEST_MUX_CTL (NETXEN_CRB_NIU + 0x00094) #define NETXEN_NIU_XG_PAUSE_CTL (NETXEN_CRB_NIU + 0x00098) #define NETXEN_NIU_XG_PAUSE_LEVEL (NETXEN_CRB_NIU + 0x000dc) +#define NETXEN_NIU_FRAME_COUNT_SELECT (NETXEN_CRB_NIU + 0x000ac) +#define NETXEN_NIU_FRAME_COUNT (NETXEN_CRB_NIU + 0x000b0) #define NETXEN_NIU_XG_SEL (NETXEN_CRB_NIU + 0x00128) #define NETXEN_NIU_GB_PAUSE_CTL (NETXEN_CRB_NIU + 0x0030c) diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 32314000dfcd..52a3798d8d94 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -383,24 +383,51 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) { - __u32 reg; + u32 mac_cfg; + u32 cnt = 0; + __u32 reg = 0x0200; u32 port = adapter->physical_port; + u16 board_type = adapter->ahw.board_type; if (port > NETXEN_NIU_MAX_XG_PORTS) return -EINVAL; - reg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port)); - if (mode == NETXEN_NIU_PROMISC_MODE) - reg = (reg | 0x2000UL); - else - reg = (reg & ~0x2000UL); + mac_cfg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port)); + mac_cfg &= ~0x4; + NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg); - if (mode == NETXEN_NIU_ALLMULTI_MODE) - reg = (reg | 0x1000UL); - else - reg = (reg & ~0x1000UL); + if ((board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) || + (board_type == NETXEN_BRDTYPE_P2_SB31_10G_HMEZ)) + reg = (0x20 << port); + + NXWR32(adapter, NETXEN_NIU_FRAME_COUNT_SELECT, reg); + + mdelay(10); + + while (NXRD32(adapter, NETXEN_NIU_FRAME_COUNT) && ++cnt < 20) + mdelay(10); + + if (cnt < 20) { + + reg = NXRD32(adapter, + NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port)); - NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); + if (mode == NETXEN_NIU_PROMISC_MODE) + reg = (reg | 0x2000UL); + else + reg = (reg & ~0x2000UL); + + if (mode == NETXEN_NIU_ALLMULTI_MODE) + reg = (reg | 0x1000UL); + else + reg = (reg & ~0x1000UL); + + NXWR32(adapter, + NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); + } + + mac_cfg |= 0x4; + NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg); return 0; } @@ -436,7 +463,7 @@ netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter) { u32 val = 0; u16 port = adapter->physical_port; - u8 *addr = adapter->netdev->dev_addr; + u8 *addr = adapter->mac_addr; if (adapter->mc_enabled) return 0; @@ -465,7 +492,7 @@ netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter) { u32 val = 0; u16 port = adapter->physical_port; - u8 *addr = adapter->netdev->dev_addr; + u8 *addr = adapter->mac_addr; if (!adapter->mc_enabled) return 0; @@ -660,7 +687,7 @@ void netxen_p3_nic_set_multi(struct net_device *netdev) list_splice_tail_init(&adapter->mac_list, &del_list); - nx_p3_nic_add_mac(adapter, netdev->dev_addr, &del_list); + nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list); nx_p3_nic_add_mac(adapter, bcast_addr, &del_list); if (netdev->flags & IFF_PROMISC) { @@ -1901,22 +1928,16 @@ netxen_setup_hwops(struct netxen_adapter *adapter) int netxen_nic_get_board_info(struct netxen_adapter *adapter) { - int offset, board_type, magic, header_version; + int offset, board_type, magic; struct pci_dev *pdev = adapter->pdev; offset = NX_FW_MAGIC_OFFSET; if (netxen_rom_fast_read(adapter, offset, &magic)) return -EIO; - offset = NX_HDR_VERSION_OFFSET; - if (netxen_rom_fast_read(adapter, offset, &header_version)) - return -EIO; - - if (magic != NETXEN_BDINFO_MAGIC || - header_version != NETXEN_BDINFO_VERSION) { - dev_err(&pdev->dev, - "invalid board config, magic=%08x, version=%08x\n", - magic, header_version); + if (magic != NETXEN_BDINFO_MAGIC) { + dev_err(&pdev->dev, "invalid board config, magic=%08x\n", + magic); return -EIO; } diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 91c2bc61c8eb..8a0904368e08 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -531,6 +531,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) continue; if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { + if (off == (NETXEN_CRB_I2C0 + 0x1c)) + continue; /* do not reset PCI */ if (off == (ROMUSB_GLB + 0xbc)) continue; @@ -542,6 +544,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) continue; if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */ continue; + if ((off & 0x0ff00000) == NETXEN_CRB_DDR_NET) + continue; if (off == (NETXEN_CRB_PEG_NET_1 + 0x18)) buf[i].data = 0x1020; /* skip the function enable register */ @@ -553,12 +557,6 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) continue; } - if (off == NETXEN_ADDR_ERROR) { - printk(KERN_ERR "%s: Err: Unknown addr: 0x%08x\n", - netxen_nic_driver_name, buf[i].addr); - continue; - } - init_delay = 1; /* After writing this register, HW needs time for CRB */ /* to quiet down (else crb_window returns 0xffffffff) */ diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 7fc15e9e8adb..3bf78dbfbf0f 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -437,6 +437,7 @@ netxen_read_mac_addr(struct netxen_adapter *adapter) netdev->dev_addr[i] = *(p + 5 - i); memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); + memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len); /* set station address */ @@ -459,6 +460,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p) netxen_napi_disable(adapter); } + memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len); memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); adapter->macaddr_set(adapter, addr->sa_data); @@ -956,7 +958,7 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) return err; } if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) - adapter->macaddr_set(adapter, netdev->dev_addr); + adapter->macaddr_set(adapter, adapter->mac_addr); adapter->set_multi(netdev); adapter->set_mtu(adapter, netdev->mtu); @@ -1919,6 +1921,7 @@ static void netxen_tx_timeout_task(struct work_struct *work) request_reset: adapter->need_fw_reset = 1; + clear_bit(__NX_RESETTING, &adapter->state); } struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) diff --git a/drivers/net/niu.c b/drivers/net/niu.c index f9364d0678f2..d6c7ac68f6ea 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -3545,7 +3545,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, rp->rcr_index = index; skb_reserve(skb, NET_IP_ALIGN); - __pskb_pull_tail(skb, min(len, NIU_RXPULL_MAX)); + __pskb_pull_tail(skb, min(len, VLAN_ETH_HLEN)); rp->rx_packets++; rp->rx_bytes += skb->len; diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index bd3447f04902..94c9ad2746bc 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -1760,7 +1760,7 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"), - PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "PE-200.cis"), + PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "cis/tamarack.cis"), PCMCIA_DEVICE_PROD_ID12("Ethernet", "CF Size PC Card", 0x00b2e941, 0x43ac239b), PCMCIA_DEVICE_PROD_ID123("Fast Ethernet", "CF Size PC Card", "1.0", diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 8659d341e769..35897134a5dd 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -139,7 +139,7 @@ out: return NULL; } -static void __devinit mdio_gpio_bus_deinit(struct device *dev) +static void mdio_gpio_bus_deinit(struct device *dev) { struct mii_bus *bus = dev_get_drvdata(dev); struct mdio_gpio_info *bitbang = bus->priv; diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 9bf2a6be9031..965adb6174c3 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -1944,8 +1944,15 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) } /* Pull completed packets off the queue and receive them. */ - while ((skb = ppp_mp_reconstruct(ppp))) - ppp_receive_nonmp_frame(ppp, skb); + while ((skb = ppp_mp_reconstruct(ppp))) { + if (pskb_may_pull(skb, 2)) + ppp_receive_nonmp_frame(ppp, skb); + else { + ++ppp->dev->stats.rx_length_errors; + kfree_skb(skb); + ppp_receive_error(ppp); + } + } return; diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 7cbf6f9b51de..2559991eea6a 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -111,9 +111,6 @@ struct pppoe_net { rwlock_t hash_lock; }; -/* to eliminate a race btw pppoe_flush_dev and pppoe_release */ -static DEFINE_SPINLOCK(flush_lock); - /* * PPPoE could be in the following stages: * 1) Discovery stage (to obtain remote MAC and Session ID) @@ -303,45 +300,48 @@ static void pppoe_flush_dev(struct net_device *dev) write_lock_bh(&pn->hash_lock); for (i = 0; i < PPPOE_HASH_SIZE; i++) { struct pppox_sock *po = pn->hash_table[i]; + struct sock *sk; - while (po != NULL) { - struct sock *sk; - if (po->pppoe_dev != dev) { + while (po) { + while (po && po->pppoe_dev != dev) { po = po->next; - continue; } + + if (!po) + break; + sk = sk_pppox(po); - spin_lock(&flush_lock); - po->pppoe_dev = NULL; - spin_unlock(&flush_lock); - dev_put(dev); /* We always grab the socket lock, followed by the - * hash_lock, in that order. Since we should - * hold the sock lock while doing any unbinding, - * we need to release the lock we're holding. - * Hold a reference to the sock so it doesn't disappear - * as we're jumping between locks. + * hash_lock, in that order. Since we should hold the + * sock lock while doing any unbinding, we need to + * release the lock we're holding. Hold a reference to + * the sock so it doesn't disappear as we're jumping + * between locks. */ sock_hold(sk); - write_unlock_bh(&pn->hash_lock); lock_sock(sk); - if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) { + if (po->pppoe_dev == dev + && sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) { pppox_unbind_sock(sk); sk->sk_state = PPPOX_ZOMBIE; sk->sk_state_change(sk); + po->pppoe_dev = NULL; + dev_put(dev); } release_sock(sk); sock_put(sk); - /* Restart scan at the beginning of this hash chain. - * While the lock was dropped the chain contents may - * have changed. + /* Restart the process from the start of the current + * hash chain. We dropped locks so the world may have + * change from underneath us. */ + + BUG_ON(pppoe_pernet(dev_net(dev)) == NULL); write_lock_bh(&pn->hash_lock); po = pn->hash_table[i]; } @@ -388,11 +388,16 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb) struct pppox_sock *po = pppox_sk(sk); struct pppox_sock *relay_po; + /* Backlog receive. Semantics of backlog rcv preclude any code from + * executing in lock_sock()/release_sock() bounds; meaning sk->sk_state + * can't change. + */ + if (sk->sk_state & PPPOX_BOUND) { ppp_input(&po->chan, skb); } else if (sk->sk_state & PPPOX_RELAY) { - relay_po = get_item_by_addr(dev_net(po->pppoe_dev), - &po->pppoe_relay); + relay_po = get_item_by_addr(sock_net(sk), + &po->pppoe_relay); if (relay_po == NULL) goto abort_kfree; @@ -447,6 +452,10 @@ static int pppoe_rcv(struct sk_buff *skb, struct net_device *dev, goto drop; pn = pppoe_pernet(dev_net(dev)); + + /* Note that get_item does a sock_hold(), so sk_pppox(po) + * is known to be safe. + */ po = get_item(pn, ph->sid, eth_hdr(skb)->h_source, dev->ifindex); if (!po) goto drop; @@ -561,6 +570,7 @@ static int pppoe_release(struct socket *sock) struct sock *sk = sock->sk; struct pppox_sock *po; struct pppoe_net *pn; + struct net *net = NULL; if (!sk) return 0; @@ -571,44 +581,28 @@ static int pppoe_release(struct socket *sock) return -EBADF; } + po = pppox_sk(sk); + + if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) { + dev_put(po->pppoe_dev); + po->pppoe_dev = NULL; + } + pppox_unbind_sock(sk); /* Signal the death of the socket. */ sk->sk_state = PPPOX_DEAD; - /* - * pppoe_flush_dev could lead to a race with - * this routine so we use flush_lock to eliminate - * such a case (we only need per-net specific data) - */ - spin_lock(&flush_lock); - po = pppox_sk(sk); - if (!po->pppoe_dev) { - spin_unlock(&flush_lock); - goto out; - } - pn = pppoe_pernet(dev_net(po->pppoe_dev)); - spin_unlock(&flush_lock); + net = sock_net(sk); + pn = pppoe_pernet(net); /* * protect "po" from concurrent updates * on pppoe_flush_dev */ - write_lock_bh(&pn->hash_lock); + delete_item(pn, po->pppoe_pa.sid, po->pppoe_pa.remote, + po->pppoe_ifindex); - po = pppox_sk(sk); - if (stage_session(po->pppoe_pa.sid)) - __delete_item(pn, po->pppoe_pa.sid, po->pppoe_pa.remote, - po->pppoe_ifindex); - - if (po->pppoe_dev) { - dev_put(po->pppoe_dev); - po->pppoe_dev = NULL; - } - - write_unlock_bh(&pn->hash_lock); - -out: sock_orphan(sk); sock->sk = NULL; @@ -625,8 +619,9 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, struct sock *sk = sock->sk; struct sockaddr_pppox *sp = (struct sockaddr_pppox *)uservaddr; struct pppox_sock *po = pppox_sk(sk); - struct net_device *dev; + struct net_device *dev = NULL; struct pppoe_net *pn; + struct net *net = NULL; int error; lock_sock(sk); @@ -652,12 +647,14 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, /* Delete the old binding */ if (stage_session(po->pppoe_pa.sid)) { pppox_unbind_sock(sk); + pn = pppoe_pernet(sock_net(sk)); + delete_item(pn, po->pppoe_pa.sid, + po->pppoe_pa.remote, po->pppoe_ifindex); if (po->pppoe_dev) { - pn = pppoe_pernet(dev_net(po->pppoe_dev)); - delete_item(pn, po->pppoe_pa.sid, - po->pppoe_pa.remote, po->pppoe_ifindex); dev_put(po->pppoe_dev); + po->pppoe_dev = NULL; } + memset(sk_pppox(po) + 1, 0, sizeof(struct pppox_sock) - sizeof(struct sock)); sk->sk_state = PPPOX_NONE; @@ -666,16 +663,15 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, /* Re-bind in session stage only */ if (stage_session(sp->sa_addr.pppoe.sid)) { error = -ENODEV; - dev = dev_get_by_name(sock_net(sk), sp->sa_addr.pppoe.dev); + net = sock_net(sk); + dev = dev_get_by_name(net, sp->sa_addr.pppoe.dev); if (!dev) - goto end; + goto err_put; po->pppoe_dev = dev; po->pppoe_ifindex = dev->ifindex; - pn = pppoe_pernet(dev_net(dev)); - write_lock_bh(&pn->hash_lock); + pn = pppoe_pernet(net); if (!(dev->flags & IFF_UP)) { - write_unlock_bh(&pn->hash_lock); goto err_put; } @@ -683,6 +679,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, &sp->sa_addr.pppoe, sizeof(struct pppoe_addr)); + write_lock_bh(&pn->hash_lock); error = __set_item(pn, po); write_unlock_bh(&pn->hash_lock); if (error < 0) @@ -696,8 +693,11 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, po->chan.ops = &pppoe_chan_ops; error = ppp_register_net_channel(dev_net(dev), &po->chan); - if (error) + if (error) { + delete_item(pn, po->pppoe_pa.sid, + po->pppoe_pa.remote, po->pppoe_ifindex); goto err_put; + } sk->sk_state = PPPOX_CONNECTED; } @@ -915,6 +915,14 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb) struct pppoe_hdr *ph; int data_len = skb->len; + /* The higher-level PPP code (ppp_unregister_channel()) ensures the PPP + * xmit operations conclude prior to an unregistration call. Thus + * sk->sk_state cannot change, so we don't need to do lock_sock(). + * But, we also can't do a lock_sock since that introduces a potential + * deadlock as we'd reverse the lock ordering used when calling + * ppp_unregister_channel(). + */ + if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) goto abort; @@ -944,7 +952,6 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb) po->pppoe_pa.remote, NULL, data_len); dev_queue_xmit(skb); - return 1; abort: diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index e7285f01bd04..c2383adcd527 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -95,6 +95,7 @@ enum { /* Misc. stuff */ MAILBOX_COUNT = 16, + MAILBOX_TIMEOUT = 5, PROC_ADDR_RDY = (1 << 31), PROC_ADDR_R = (1 << 30), diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 48b45df85ec9..a2fc70a0d0cc 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -3916,6 +3916,9 @@ static int __devinit ql_init_device(struct pci_dev *pdev, goto err_out; } + /* Set PCIe reset type for EEH to fundamental. */ + pdev->needs_freset = 1; + pci_save_state(pdev); qdev->reg_base = ioremap_nocache(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1)); @@ -4070,6 +4073,33 @@ static void __devexit qlge_remove(struct pci_dev *pdev) free_netdev(ndev); } +/* Clean up resources without touching hardware. */ +static void ql_eeh_close(struct net_device *ndev) +{ + int i; + struct ql_adapter *qdev = netdev_priv(ndev); + + if (netif_carrier_ok(ndev)) { + netif_carrier_off(ndev); + netif_stop_queue(ndev); + } + + if (test_bit(QL_ADAPTER_UP, &qdev->flags)) + cancel_delayed_work_sync(&qdev->asic_reset_work); + cancel_delayed_work_sync(&qdev->mpi_reset_work); + cancel_delayed_work_sync(&qdev->mpi_work); + cancel_delayed_work_sync(&qdev->mpi_idc_work); + cancel_delayed_work_sync(&qdev->mpi_port_cfg_work); + + for (i = 0; i < qdev->rss_ring_count; i++) + netif_napi_del(&qdev->rx_ring[i].napi); + + clear_bit(QL_ADAPTER_UP, &qdev->flags); + ql_tx_ring_clean(qdev); + ql_free_rx_buffers(qdev); + ql_release_adapter_resources(qdev); +} + /* * This callback is called by the PCI subsystem whenever * a PCI bus error is detected. @@ -4078,17 +4108,21 @@ static pci_ers_result_t qlge_io_error_detected(struct pci_dev *pdev, enum pci_channel_state state) { struct net_device *ndev = pci_get_drvdata(pdev); - struct ql_adapter *qdev = netdev_priv(ndev); - - netif_device_detach(ndev); - if (state == pci_channel_io_perm_failure) + switch (state) { + case pci_channel_io_normal: + return PCI_ERS_RESULT_CAN_RECOVER; + case pci_channel_io_frozen: + netif_device_detach(ndev); + if (netif_running(ndev)) + ql_eeh_close(ndev); + pci_disable_device(pdev); + return PCI_ERS_RESULT_NEED_RESET; + case pci_channel_io_perm_failure: + dev_err(&pdev->dev, + "%s: pci_channel_io_perm_failure.\n", __func__); return PCI_ERS_RESULT_DISCONNECT; - - if (netif_running(ndev)) - ql_adapter_down(qdev); - - pci_disable_device(pdev); + } /* Request a slot reset. */ return PCI_ERS_RESULT_NEED_RESET; @@ -4105,25 +4139,15 @@ static pci_ers_result_t qlge_io_slot_reset(struct pci_dev *pdev) struct net_device *ndev = pci_get_drvdata(pdev); struct ql_adapter *qdev = netdev_priv(ndev); + pdev->error_state = pci_channel_io_normal; + + pci_restore_state(pdev); if (pci_enable_device(pdev)) { QPRINTK(qdev, IFUP, ERR, "Cannot re-enable PCI device after reset.\n"); return PCI_ERS_RESULT_DISCONNECT; } - pci_set_master(pdev); - - netif_carrier_off(ndev); - ql_adapter_reset(qdev); - - /* Make sure the EEPROM is good */ - memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len); - - if (!is_valid_ether_addr(ndev->perm_addr)) { - QPRINTK(qdev, IFUP, ERR, "After reset, invalid MAC address.\n"); - return PCI_ERS_RESULT_DISCONNECT; - } - return PCI_ERS_RESULT_RECOVERED; } @@ -4131,17 +4155,21 @@ static void qlge_io_resume(struct pci_dev *pdev) { struct net_device *ndev = pci_get_drvdata(pdev); struct ql_adapter *qdev = netdev_priv(ndev); + int err = 0; - pci_set_master(pdev); - + if (ql_adapter_reset(qdev)) + QPRINTK(qdev, DRV, ERR, "reset FAILED!\n"); if (netif_running(ndev)) { - if (ql_adapter_up(qdev)) { + err = qlge_open(ndev); + if (err) { QPRINTK(qdev, IFUP, ERR, "Device initialization failed after reset.\n"); return; } + } else { + QPRINTK(qdev, IFUP, ERR, + "Device was not running prior to EEH.\n"); } - netif_device_attach(ndev); } diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c index 99e58e3f8e22..aec05f266107 100644 --- a/drivers/net/qlge/qlge_mpi.c +++ b/drivers/net/qlge/qlge_mpi.c @@ -470,7 +470,8 @@ end: */ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp) { - int status, count; + int status; + unsigned long count; /* Begin polled mode for MPI */ @@ -491,14 +492,14 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp) /* Wait for the command to complete. We loop * here because some AEN might arrive while * we're waiting for the mailbox command to - * complete. If more than 5 arrive then we can + * complete. If more than 5 seconds expire we can * assume something is wrong. */ - count = 5; + count = jiffies + HZ * MAILBOX_TIMEOUT; do { /* Wait for the interrupt to come in. */ status = ql_wait_mbx_cmd_cmplt(qdev); if (status) - goto end; + continue; /* Process the event. If it's an AEN, it * will be handled in-line or a worker @@ -517,15 +518,15 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp) MB_CMD_STS_GOOD) || ((mbcp->mbox_out[0] & 0x0000f000) == MB_CMD_STS_INTRMDT)) - break; - } while (--count); + goto done; + } while (time_before(jiffies, count)); - if (!count) { - QPRINTK(qdev, DRV, ERR, - "Timed out waiting for mailbox complete.\n"); - status = -ETIMEDOUT; - goto end; - } + QPRINTK(qdev, DRV, ERR, + "Timed out waiting for mailbox complete.\n"); + status = -ETIMEDOUT; + goto end; + +done: /* Now we can clear the interrupt condition * and look at our status. diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 7dfcb58b0eb4..8b14c6eda7c3 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -1085,7 +1085,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, int bar = 0; u16 *adrp; - printk(KERN_INFO "%s\n", version); + printk("%s\n", version); err = pci_enable_device(pdev); if (err) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 83c47d95c3aa..0fe2fc90f207 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1029,7 +1029,10 @@ static void rtl8169_vlan_rx_register(struct net_device *dev, spin_lock_irqsave(&tp->lock, flags); tp->vlgrp = grp; - if (tp->vlgrp) + /* + * Do not disable RxVlan on 8110SCd. + */ + if (tp->vlgrp || (tp->mac_version == RTL_GIGA_MAC_VER_05)) tp->cp_cmd |= RxVlan; else tp->cp_cmd &= ~RxVlan; @@ -3197,6 +3200,14 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) } rtl8169_init_phy(dev, tp); + + /* + * Pretend we are using VLANs; This bypasses a nasty bug where + * Interrupts stop flowing on high load on 8110SCd controllers. + */ + if (tp->mac_version == RTL_GIGA_MAC_VER_05) + RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | RxVlan); + device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL); out: @@ -3224,6 +3235,10 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) flush_scheduled_work(); unregister_netdev(dev); + + /* restore original MAC address */ + rtl_rar_set(tp, dev->perm_addr); + rtl_disable_msi(pdev, tp); rtl8169_release_board(pdev, dev, tp->mmio_addr); pci_set_drvdata(pdev, NULL); @@ -3232,9 +3247,9 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, struct net_device *dev) { - unsigned int mtu = dev->mtu; + unsigned int max_frame = dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; - tp->rx_buf_sz = (mtu > RX_BUF_SIZE) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE; + tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE; } static int rtl8169_open(struct net_device *dev) @@ -3368,7 +3383,7 @@ static u16 rtl_rw_cpluscmd(void __iomem *ioaddr) static void rtl_set_rx_max_size(void __iomem *ioaddr, unsigned int rx_buf_sz) { /* Low hurts. Let's disable the filtering. */ - RTL_W16(RxMaxSize, rx_buf_sz); + RTL_W16(RxMaxSize, rx_buf_sz + 1); } static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version) @@ -4870,6 +4885,9 @@ static void rtl_shutdown(struct pci_dev *pdev) rtl8169_net_suspend(dev); + /* restore original MAC address */ + rtl_rar_set(tp, dev->perm_addr); + spin_lock_irq(&tp->lock); rtl8169_asic_down(ioaddr); diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index ddccf5fa56b6..0dd7839322bc 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -3494,6 +3494,7 @@ static void s2io_reset(struct s2io_nic *sp) /* Restore the PCI state saved during initialization. */ pci_restore_state(sp->pdev); + pci_save_state(sp->pdev); pci_read_config_word(sp->pdev, 0x2, &val16); if (check_pci_device_id(val16) != (u16)PCI_ANY_ID) break; diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 01f9432c31ef..98bff5ada09a 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -444,7 +444,8 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, * the appropriate LRO method */ static void efx_rx_packet_lro(struct efx_channel *channel, - struct efx_rx_buffer *rx_buf) + struct efx_rx_buffer *rx_buf, + bool checksummed) { struct napi_struct *napi = &channel->napi_str; @@ -466,7 +467,8 @@ static void efx_rx_packet_lro(struct efx_channel *channel, skb->len = rx_buf->len; skb->data_len = rx_buf->len; skb->truesize += rx_buf->len; - skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->ip_summed = + checksummed ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE; napi_gro_frags(napi); @@ -475,6 +477,7 @@ out: rx_buf->page = NULL; } else { EFX_BUG_ON_PARANOID(!rx_buf->skb); + EFX_BUG_ON_PARANOID(!checksummed); napi_gro_receive(napi, rx_buf->skb); rx_buf->skb = NULL; @@ -570,7 +573,7 @@ void __efx_rx_packet(struct efx_channel *channel, } if (likely(checksummed || rx_buf->page)) { - efx_rx_packet_lro(channel, rx_buf); + efx_rx_packet_lro(channel, rx_buf, checksummed); goto done; } diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c index cee00ad49b57..49eb91b5f50c 100644 --- a/drivers/net/sfc/sfe4001.c +++ b/drivers/net/sfc/sfe4001.c @@ -188,7 +188,7 @@ static int sfn4111t_reset(struct efx_nic *efx) efx_oword_t reg; /* GPIO 3 and the GPIO register are shared with I2C, so block that */ - mutex_lock(&efx->i2c_adap.bus_lock); + i2c_lock_adapter(&efx->i2c_adap); /* Pull RST_N (GPIO 2) low then let it up again, setting the * FLASH_CFG_1 strap (GPIO 3) appropriately. Only change the @@ -204,7 +204,7 @@ static int sfn4111t_reset(struct efx_nic *efx) falcon_write(efx, ®, GPIO_CTL_REG_KER); msleep(1); - mutex_unlock(&efx->i2c_adap.bus_lock); + i2c_unlock_adapter(&efx->i2c_adap); ssleep(1); return 0; diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index f49d0800c1d1..528b912a4b0d 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -30,6 +30,7 @@ #include <linux/phy.h> #include <linux/cache.h> #include <linux/io.h> +#include <asm/cacheflush.h> #include "sh_eth.h" diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 2ab5c39f33ca..6a10d7ba5877 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -4538,6 +4538,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev, goto err_out_free_netdev; } + netif_carrier_off(dev); + netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT); err = request_irq(pdev->irq, sky2_intr, diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 05c91ee6921e..f12206bdbb75 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -2283,7 +2283,7 @@ static int __devinit smc_drv_probe(struct platform_device *pdev) ndev->irq = ires->start; - if (ires->flags & IRQF_TRIGGER_MASK) + if (irq_flags == -1 || ires->flags & IRQF_TRIGGER_MASK) irq_flags = ires->flags & IRQF_TRIGGER_MASK; ret = smc_request_attrib(pdev, ndev); diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index ccdd196f5297..f9cdcbcb77d4 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -986,7 +986,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget) struct net_device *dev = pdata->dev; int npackets = 0; - while (likely(netif_running(dev)) && (npackets < budget)) { + while (npackets < budget) { unsigned int pktlength; unsigned int pktwords; struct sk_buff *skb; diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c index b4909a2dec66..0f7909276237 100644 --- a/drivers/net/smsc9420.c +++ b/drivers/net/smsc9420.c @@ -252,6 +252,9 @@ static int smsc9420_ethtool_get_settings(struct net_device *dev, { struct smsc9420_pdata *pd = netdev_priv(dev); + if (!pd->phy_dev) + return -ENODEV; + cmd->maxtxpkt = 1; cmd->maxrxpkt = 1; return phy_ethtool_gset(pd->phy_dev, cmd); @@ -262,6 +265,9 @@ static int smsc9420_ethtool_set_settings(struct net_device *dev, { struct smsc9420_pdata *pd = netdev_priv(dev); + if (!pd->phy_dev) + return -ENODEV; + return phy_ethtool_sset(pd->phy_dev, cmd); } @@ -290,6 +296,10 @@ static void smsc9420_ethtool_set_msglevel(struct net_device *netdev, u32 data) static int smsc9420_ethtool_nway_reset(struct net_device *netdev) { struct smsc9420_pdata *pd = netdev_priv(netdev); + + if (!pd->phy_dev) + return -ENODEV; + return phy_start_aneg(pd->phy_dev); } @@ -312,6 +322,10 @@ smsc9420_ethtool_getregs(struct net_device *dev, struct ethtool_regs *regs, for (i = 0; i < 0x100; i += (sizeof(u32))) data[j++] = smsc9420_reg_read(pd, i); + // cannot read phy registers if the net device is down + if (!phy_dev) + return; + for (i = 0; i <= 31; i++) data[j++] = smsc9420_mii_read(phy_dev->bus, phy_dev->addr, i); } diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index c2f14dc9ba28..9542995ba667 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -416,13 +416,8 @@ static void init_dma_desc_rings(struct net_device *dev) unsigned int txsize = priv->dma_tx_size; unsigned int rxsize = priv->dma_rx_size; unsigned int bfsize = priv->dma_buf_sz; - int buff2_needed = 0; - int dis_ic = 0; + int buff2_needed = 0, dis_ic = 0; -#ifdef CONFIG_STMMAC_TIMER - /* Using Timers disable interrupts on completion for the reception */ - dis_ic = 1; -#endif /* Set the Buffer size according to the MTU; * indeed, in case of jumbo we need to bump-up the buffer sizes. */ @@ -437,6 +432,11 @@ static void init_dma_desc_rings(struct net_device *dev) else bfsize = DMA_BUFFER_SIZE; +#ifdef CONFIG_STMMAC_TIMER + /* Disable interrupts on completion for the reception if timer is on */ + if (likely(priv->tm->enable)) + dis_ic = 1; +#endif /* If the MTU exceeds 8k so use the second buffer in the chain */ if (bfsize >= BUF_SIZE_8KiB) buff2_needed = 1; @@ -809,20 +809,22 @@ static void stmmac_tx(struct stmmac_priv *priv) static inline void stmmac_enable_irq(struct stmmac_priv *priv) { -#ifndef CONFIG_STMMAC_TIMER - writel(DMA_INTR_DEFAULT_MASK, priv->dev->base_addr + DMA_INTR_ENA); -#else - priv->tm->timer_start(tmrate); +#ifdef CONFIG_STMMAC_TIMER + if (likely(priv->tm->enable)) + priv->tm->timer_start(tmrate); + else #endif + writel(DMA_INTR_DEFAULT_MASK, priv->dev->base_addr + DMA_INTR_ENA); } static inline void stmmac_disable_irq(struct stmmac_priv *priv) { -#ifndef CONFIG_STMMAC_TIMER - writel(0, priv->dev->base_addr + DMA_INTR_ENA); -#else - priv->tm->timer_stop(); +#ifdef CONFIG_STMMAC_TIMER + if (likely(priv->tm->enable)) + priv->tm->timer_stop(); + else #endif + writel(0, priv->dev->base_addr + DMA_INTR_ENA); } static int stmmac_has_work(struct stmmac_priv *priv) @@ -1031,22 +1033,23 @@ static int stmmac_open(struct net_device *dev) } #ifdef CONFIG_STMMAC_TIMER - priv->tm = kmalloc(sizeof(struct stmmac_timer *), GFP_KERNEL); + priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL); if (unlikely(priv->tm == NULL)) { pr_err("%s: ERROR: timer memory alloc failed \n", __func__); return -ENOMEM; } priv->tm->freq = tmrate; - /* Test if the HW timer can be actually used. - * In case of failure continue with no timer. */ + /* Test if the external timer can be actually used. + * In case of failure continue without timer. */ if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) { - pr_warning("stmmaceth: cannot attach the HW timer\n"); + pr_warning("stmmaceth: cannot attach the external timer.\n"); tmrate = 0; priv->tm->freq = 0; priv->tm->timer_start = stmmac_no_timer_started; priv->tm->timer_stop = stmmac_no_timer_stopped; - } + } else + priv->tm->enable = 1; #endif /* Create and initialize the TX/RX descriptors chains. */ @@ -1322,9 +1325,11 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) /* Interrupt on completition only for the latest segment */ priv->mac_type->ops->close_tx_desc(desc); + #ifdef CONFIG_STMMAC_TIMER - /* Clean IC while using timers */ - priv->mac_type->ops->clear_tx_ic(desc); + /* Clean IC while using timer */ + if (likely(priv->tm->enable)) + priv->mac_type->ops->clear_tx_ic(desc); #endif /* To avoid raise condition */ priv->mac_type->ops->set_tx_owner(first); @@ -2028,7 +2033,8 @@ static int stmmac_suspend(struct platform_device *pdev, pm_message_t state) #ifdef CONFIG_STMMAC_TIMER priv->tm->timer_stop(); - dis_ic = 1; + if (likely(priv->tm->enable)) + dis_ic = 1; #endif napi_disable(&priv->napi); diff --git a/drivers/net/stmmac/stmmac_timer.c b/drivers/net/stmmac/stmmac_timer.c index b838c6582077..679f61ffb1f8 100644 --- a/drivers/net/stmmac/stmmac_timer.c +++ b/drivers/net/stmmac/stmmac_timer.c @@ -63,7 +63,7 @@ int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm) stmmac_rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); if (stmmac_rtc == NULL) { - pr_error("open rtc device failed\n"); + pr_err("open rtc device failed\n"); return -ENODEV; } @@ -71,7 +71,7 @@ int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm) /* Periodic mode is not supported */ if ((rtc_irq_set_freq(stmmac_rtc, &stmmac_task, tm->freq) < 0)) { - pr_error("set periodic failed\n"); + pr_err("set periodic failed\n"); rtc_irq_unregister(stmmac_rtc, &stmmac_task); rtc_class_close(stmmac_rtc); return -1; diff --git a/drivers/net/stmmac/stmmac_timer.h b/drivers/net/stmmac/stmmac_timer.h index f795cae33725..6863590d184b 100644 --- a/drivers/net/stmmac/stmmac_timer.h +++ b/drivers/net/stmmac/stmmac_timer.h @@ -26,6 +26,7 @@ struct stmmac_timer { void (*timer_start) (unsigned int new_freq); void (*timer_stop) (void); unsigned int freq; + unsigned int enable; }; /* Open the HW timer device and return 0 in case of success */ diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 7019a0d1a82b..61640b99b705 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -2063,7 +2063,15 @@ static int gem_check_invariants(struct gem *gp) mif_cfg &= ~MIF_CFG_PSELECT; writel(mif_cfg, gp->regs + MIF_CFG); } else { - gp->phy_type = phy_serialink; +#ifdef CONFIG_SPARC + const char *p; + + p = of_get_property(gp->of_node, "shared-pins", NULL); + if (p && !strcmp(p, "serdes")) + gp->phy_type = phy_serdes; + else +#endif + gp->phy_type = phy_serialink; } if (gp->phy_type == phy_mii_mdio1 || gp->phy_type == phy_mii_mdio0) { diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c index 36cb2423bcf1..75fa32e34fd0 100644 --- a/drivers/net/tokenring/ibmtr.c +++ b/drivers/net/tokenring/ibmtr.c @@ -1144,9 +1144,16 @@ static void dir_open_adapter (struct net_device *dev) } else { char **prphase = printphase; char **prerror = printerror; + int pnr = err / 16 - 1; + int enr = err % 16 - 1; DPRINTK("TR Adapter misc open failure, error code = "); - printk("0x%x, Phase: %s, Error: %s\n", - err, prphase[err/16 -1], prerror[err%16 -1]); + if (pnr < 0 || pnr >= ARRAY_SIZE(printphase) || + enr < 0 || + enr >= ARRAY_SIZE(printerror)) + printk("0x%x, invalid Phase/Error.", err); + else + printk("0x%x, Phase: %s, Error: %s\n", err, + prphase[pnr], prerror[enr]); printk(" retrying after %ds delay...\n", TR_RETRY_INTERVAL/HZ); } diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index c47237c2d638..32d93564a74d 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -174,7 +174,7 @@ config USB_NET_CDCETHER * Ericsson Mobile Broadband Module (all variants) * Motorola (DM100 and SB4100) * Broadcom Cable Modem (reference design) - * Toshiba (PCX1100U and F3507g) + * Toshiba (PCX1100U and F3507g/F3607gw) * ... This driver creates an interface named "ethX", where X depends on diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 4a6aff579403..21e1ba160008 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -544,20 +544,60 @@ static const struct usb_device_id products [] = { USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), .driver_info = (unsigned long) &cdc_info, }, { - /* Ericsson F3307 */ + /* Ericsson F3607gw ver 2 */ + USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1905, USB_CLASS_COMM, + USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long) &cdc_info, +}, { + /* Ericsson F3607gw ver 3 */ USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1906, USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), .driver_info = (unsigned long) &cdc_info, }, { + /* Ericsson F3307 */ + USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190a, USB_CLASS_COMM, + USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long) &cdc_info, +}, { + /* Ericsson F3307 ver 2 */ + USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1909, USB_CLASS_COMM, + USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long) &cdc_info, +}, { + /* Ericsson C3607w */ + USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1049, USB_CLASS_COMM, + USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long) &cdc_info, +}, { /* Toshiba F3507g */ USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), .driver_info = (unsigned long) &cdc_info, }, { + /* Toshiba F3607gw */ + USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130c, USB_CLASS_COMM, + USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long) &cdc_info, +}, { + /* Toshiba F3607gw ver 2 */ + USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x1311, USB_CLASS_COMM, + USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long) &cdc_info, +}, { /* Dell F3507g */ USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8147, USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), .driver_info = (unsigned long) &cdc_info, +}, { + /* Dell F3607gw */ + USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8183, USB_CLASS_COMM, + USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long) &cdc_info, +}, { + /* Dell F3607gw ver 2 */ + USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8184, USB_CLASS_COMM, + USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long) &cdc_info, }, { }, // END }; diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 72470f77f556..a2b30a10064f 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -649,6 +649,10 @@ static const struct usb_device_id products[] = { USB_DEVICE(0x0fe6, 0x8101), /* DM9601 USB to Fast Ethernet Adapter */ .driver_info = (unsigned long)&dm9601_info, }, + { + USB_DEVICE(0x0a46, 0x9000), /* DM9000E */ + .driver_info = (unsigned long)&dm9601_info, + }, {}, // END }; diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index fa4e58196c21..43bc3fcc0d85 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -378,7 +378,7 @@ static void dbg_dump(int line_count, const char *func_name, unsigned char *buf, } #define DUMP(buf_, len_) \ - dbg_dump(__LINE__, __func__, buf_, len_) + dbg_dump(__LINE__, __func__, (unsigned char *)buf_, len_) #define DUMP1(buf_, len_) \ do { \ @@ -1363,7 +1363,7 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) /* reset the rts and dtr */ /* do the actual close */ serial->open_count--; - kref_put(&serial->parent->ref, hso_serial_ref_free); + if (serial->open_count <= 0) { serial->open_count = 0; spin_lock_irq(&serial->serial_lock); @@ -1383,6 +1383,8 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) usb_autopm_put_interface(serial->parent->interface); mutex_unlock(&serial->parent->mutex); + + kref_put(&serial->parent->ref, hso_serial_ref_free); } /* close the requested serial port */ @@ -1527,7 +1529,7 @@ static void tiocmget_intr_callback(struct urb *urb) dev_warn(&usb->dev, "hso received invalid serial state notification\n"); DUMP(serial_state_notification, - sizeof(hso_serial_state_notifation)) + sizeof(struct hso_serial_state_notification)); } else { UART_state_bitmap = le16_to_cpu(serial_state_notification-> diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index 0caa8008c51c..f56dec6119c3 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c @@ -362,12 +362,12 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) retval = -EINVAL; goto halt_fail_and_release; } - dev->hard_mtu = tmp; - net->mtu = dev->hard_mtu - net->hard_header_len; dev_warn(&intf->dev, "dev can't take %u byte packets (max %u), " "adjusting MTU to %u\n", - dev->hard_mtu, tmp, net->mtu); + dev->hard_mtu, tmp, tmp - net->hard_header_len); + dev->hard_mtu = tmp; + net->mtu = dev->hard_mtu - net->hard_header_len; } /* REVISIT: peripheral "alignment" request is ignored ... */ diff --git a/drivers/net/veth.c b/drivers/net/veth.c index ade5b344f75d..52af5017c46b 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -210,32 +210,29 @@ rx_drop: static struct net_device_stats *veth_get_stats(struct net_device *dev) { struct veth_priv *priv; - struct net_device_stats *dev_stats; int cpu; - struct veth_net_stats *stats; + struct veth_net_stats *stats, total = {0}; priv = netdev_priv(dev); - dev_stats = &dev->stats; - - dev_stats->rx_packets = 0; - dev_stats->tx_packets = 0; - dev_stats->rx_bytes = 0; - dev_stats->tx_bytes = 0; - dev_stats->tx_dropped = 0; - dev_stats->rx_dropped = 0; - for_each_online_cpu(cpu) { + for_each_possible_cpu(cpu) { stats = per_cpu_ptr(priv->stats, cpu); - dev_stats->rx_packets += stats->rx_packets; - dev_stats->tx_packets += stats->tx_packets; - dev_stats->rx_bytes += stats->rx_bytes; - dev_stats->tx_bytes += stats->tx_bytes; - dev_stats->tx_dropped += stats->tx_dropped; - dev_stats->rx_dropped += stats->rx_dropped; + total.rx_packets += stats->rx_packets; + total.tx_packets += stats->tx_packets; + total.rx_bytes += stats->rx_bytes; + total.tx_bytes += stats->tx_bytes; + total.tx_dropped += stats->tx_dropped; + total.rx_dropped += stats->rx_dropped; } - - return dev_stats; + dev->stats.rx_packets = total.rx_packets; + dev->stats.tx_packets = total.tx_packets; + dev->stats.rx_bytes = total.rx_bytes; + dev->stats.tx_bytes = total.tx_bytes; + dev->stats.tx_dropped = total.tx_dropped; + dev->stats.rx_dropped = total.rx_dropped; + + return &dev->stats; } static int veth_open(struct net_device *dev) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 8d009760277c..b9e002fccbca 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -22,7 +22,6 @@ #include <linux/ethtool.h> #include <linux/module.h> #include <linux/virtio.h> -#include <linux/virtio_ids.h> #include <linux/virtio_net.h> #include <linux/scatterlist.h> #include <linux/if_vlan.h> @@ -454,7 +453,7 @@ static unsigned int free_old_xmit_skbs(struct virtnet_info *vi) vi->dev->stats.tx_bytes += skb->len; vi->dev->stats.tx_packets++; tot_sgs += skb_vnet_hdr(skb)->num_sg; - kfree_skb(skb); + dev_kfree_skb_any(skb); } return tot_sgs; } @@ -517,8 +516,7 @@ again: /* Free up any pending old buffers before queueing new ones. */ free_old_xmit_skbs(vi); - /* Put new one in send queue and do transmit */ - __skb_queue_head(&vi->send, skb); + /* Try to transmit */ capacity = xmit_skb(vi, skb); /* This can happen with OOM and indirect buffers. */ @@ -532,8 +530,17 @@ again: } return NETDEV_TX_BUSY; } - vi->svq->vq_ops->kick(vi->svq); + + /* + * Put new one in send queue. You'd expect we'd need this before + * xmit_skb calls add_buf(), since the callback can be triggered + * immediately after that. But since the callback just triggers + * another call back here, normal network xmit locking prevents the + * race. + */ + __skb_queue_head(&vi->send, skb); + /* Don't wait up for transmitted skbs to be freed. */ skb_orphan(skb); nf_reset(skb); @@ -991,7 +998,7 @@ static unsigned int features[] = { VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, }; -static struct virtio_driver virtio_net = { +static struct virtio_driver virtio_net_driver = { .feature_table = features, .feature_table_size = ARRAY_SIZE(features), .driver.name = KBUILD_MODNAME, @@ -1004,12 +1011,12 @@ static struct virtio_driver virtio_net = { static int __init init(void) { - return register_virtio_driver(&virtio_net); + return register_virtio_driver(&virtio_net_driver); } static void __exit fini(void) { - unregister_virtio_driver(&virtio_net); + unregister_virtio_driver(&virtio_net_driver); } module_init(init); module_exit(fini); diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 6a16f76f277e..004353a46af0 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -481,7 +481,8 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx, } rq->uncommitted[ring_idx] += num_allocated; - dprintk(KERN_ERR "alloc_rx_buf: %d allocated, next2fill %u, next2comp " + dev_dbg(&adapter->netdev->dev, + "alloc_rx_buf: %d allocated, next2fill %u, next2comp " "%u, uncommited %u\n", num_allocated, ring->next2fill, ring->next2comp, rq->uncommitted[ring_idx]); @@ -539,7 +540,8 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, tbi = tq->buf_info + tq->tx_ring.next2fill; tbi->map_type = VMXNET3_MAP_NONE; - dprintk(KERN_ERR "txd[%u]: 0x%Lx 0x%x 0x%x\n", + dev_dbg(&adapter->netdev->dev, + "txd[%u]: 0x%Lx 0x%x 0x%x\n", tq->tx_ring.next2fill, ctx->sop_txd->txd.addr, ctx->sop_txd->dword[2], ctx->sop_txd->dword[3]); vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring); @@ -572,7 +574,8 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, gdesc->dword[2] = dw2 | buf_size; gdesc->dword[3] = 0; - dprintk(KERN_ERR "txd[%u]: 0x%Lx 0x%x 0x%x\n", + dev_dbg(&adapter->netdev->dev, + "txd[%u]: 0x%Lx 0x%x 0x%x\n", tq->tx_ring.next2fill, gdesc->txd.addr, gdesc->dword[2], gdesc->dword[3]); vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring); @@ -600,7 +603,8 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, gdesc->dword[2] = dw2 | frag->size; gdesc->dword[3] = 0; - dprintk(KERN_ERR "txd[%u]: 0x%llu %u %u\n", + dev_dbg(&adapter->netdev->dev, + "txd[%u]: 0x%llu %u %u\n", tq->tx_ring.next2fill, gdesc->txd.addr, gdesc->dword[2], gdesc->dword[3]); vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring); @@ -697,7 +701,8 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, tdd = tq->data_ring.base + tq->tx_ring.next2fill; memcpy(tdd->data, skb->data, ctx->copy_size); - dprintk(KERN_ERR "copy %u bytes to dataRing[%u]\n", + dev_dbg(&adapter->netdev->dev, + "copy %u bytes to dataRing[%u]\n", ctx->copy_size, tq->tx_ring.next2fill); return 1; @@ -808,7 +813,8 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, if (count > vmxnet3_cmd_ring_desc_avail(&tq->tx_ring)) { tq->stats.tx_ring_full++; - dprintk(KERN_ERR "tx queue stopped on %s, next2comp %u" + dev_dbg(&adapter->netdev->dev, + "tx queue stopped on %s, next2comp %u" " next2fill %u\n", adapter->netdev->name, tq->tx_ring.next2comp, tq->tx_ring.next2fill); @@ -853,7 +859,8 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, /* finally flips the GEN bit of the SOP desc */ gdesc->dword[2] ^= VMXNET3_TXD_GEN; - dprintk(KERN_ERR "txd[%u]: SOP 0x%Lx 0x%x 0x%x\n", + dev_dbg(&adapter->netdev->dev, + "txd[%u]: SOP 0x%Lx 0x%x 0x%x\n", (u32)((union Vmxnet3_GenericDesc *)ctx.sop_txd - tq->tx_ring.base), gdesc->txd.addr, gdesc->dword[2], gdesc->dword[3]); @@ -990,7 +997,8 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, if (unlikely(rcd->len == 0)) { /* Pretend the rx buffer is skipped. */ BUG_ON(!(rcd->sop && rcd->eop)); - dprintk(KERN_ERR "rxRing[%u][%u] 0 length\n", + dev_dbg(&adapter->netdev->dev, + "rxRing[%u][%u] 0 length\n", ring_idx, idx); goto rcd_done; } @@ -1683,7 +1691,8 @@ vmxnet3_activate_dev(struct vmxnet3_adapter *adapter) int err; u32 ret; - dprintk(KERN_ERR "%s: skb_buf_size %d, rx_buf_per_pkt %d, ring sizes" + dev_dbg(&adapter->netdev->dev, + "%s: skb_buf_size %d, rx_buf_per_pkt %d, ring sizes" " %u %u %u\n", adapter->netdev->name, adapter->skb_buf_size, adapter->rx_buf_per_pkt, adapter->tx_queue.tx_ring.size, adapter->rx_queue.rx_ring[0].size, diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index 6bb91576e999..3c0d70d58111 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -30,6 +30,7 @@ #include <linux/types.h> #include <linux/ethtool.h> #include <linux/delay.h> +#include <linux/device.h> #include <linux/netdevice.h> #include <linux/pci.h> #include <linux/ethtool.h> @@ -59,7 +60,6 @@ #include <linux/if_vlan.h> #include <linux/if_arp.h> #include <linux/inetdevice.h> -#include <linux/dst.h> #include "vmxnet3_defs.h" diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index e2c33c06190b..8e25ca7080c7 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c @@ -907,6 +907,7 @@ static ssize_t cosa_write(struct file *file, current->state = TASK_RUNNING; chan->tx_status = 1; spin_unlock_irqrestore(&cosa->lock, flags); + up(&chan->wsem); return -ERESTARTSYS; } } diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 7116a1aa20ce..abf896a7390e 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -4790,9 +4790,8 @@ static int proc_stats_rid_open( struct inode *inode, static int get_dec_u16( char *buffer, int *start, int limit ) { u16 value; int valid = 0; - for( value = 0; buffer[*start] >= '0' && - buffer[*start] <= '9' && - *start < limit; (*start)++ ) { + for (value = 0; *start < limit && buffer[*start] >= '0' && + buffer[*start] <= '9'; (*start)++) { valid = 1; value *= 10; value += buffer[*start] - '0'; diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 9c6ab5378f6e..95a8e232b58f 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1125,7 +1125,6 @@ ath5k_mode_setup(struct ath5k_softc *sc) /* configure operational mode */ ath5k_hw_set_opmode(ah); - ath5k_hw_set_mcast_filter(ah, 0, 0); ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); } diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c index b767c3b67b24..b548c8eaaae1 100644 --- a/drivers/net/wireless/ath/ath5k/led.c +++ b/drivers/net/wireless/ath/ath5k/led.c @@ -63,12 +63,16 @@ static const struct pci_device_id ath5k_led_devices[] = { { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) }, /* E-machines E510 (tuliom@gmail.com) */ { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) }, + /* BenQ Joybook R55v (nowymarluk@wp.pl) */ + { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0100), ATH_LED(1, 0) }, /* Acer Extensa 5620z (nekoreeve@gmail.com) */ { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) }, /* Fukato Datacask Jupiter 1014a (mrb74@gmx.at) */ { ATH_SDEVICE(PCI_VENDOR_ID_AZWAVE, 0x1026), ATH_LED(3, 0) }, /* IBM ThinkPad AR5BXB6 (legovini@spiro.fisica.unipd.it) */ { ATH_SDEVICE(PCI_VENDOR_ID_IBM, 0x058a), ATH_LED(1, 0) }, + /* HP Compaq CQ60-206US (ddreggors@jumptv.com) */ + { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) }, /* HP Compaq C700 (nitrousnrg@gmail.com) */ { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) }, /* IBM-specific AR5212 (all others) */ diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 52bed89063d4..43d2be9867fc 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1555,6 +1555,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); + hw->wiphy->ps_default = false; + hw->queues = 4; hw->max_rates = 4; hw->channel_change_time = 5000; diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 16a271787b85..1895d63aad0a 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -679,7 +679,7 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc, return rate; if (rate_table->info[rate].valid_single_stream && - !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)); + !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) return rate; /* This should not happen */ diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 8701034569fa..de4e804bedf0 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -1157,8 +1157,9 @@ struct b43_dmaring *parse_cookie(struct b43_wldev *dev, u16 cookie, int *slot) } static int dma_tx_fragment(struct b43_dmaring *ring, - struct sk_buff *skb) + struct sk_buff **in_skb) { + struct sk_buff *skb = *in_skb; const struct b43_dma_ops *ops = ring->ops; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); u8 *header; @@ -1224,8 +1225,14 @@ static int dma_tx_fragment(struct b43_dmaring *ring, } memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len); + memcpy(bounce_skb->cb, skb->cb, sizeof(skb->cb)); + bounce_skb->dev = skb->dev; + skb_set_queue_mapping(bounce_skb, skb_get_queue_mapping(skb)); + info = IEEE80211_SKB_CB(bounce_skb); + dev_kfree_skb_any(skb); skb = bounce_skb; + *in_skb = bounce_skb; meta->skb = skb; meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { @@ -1355,7 +1362,11 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb) * static, so we don't need to store it per frame. */ ring->queue_prio = skb_get_queue_mapping(skb); - err = dma_tx_fragment(ring, skb); + /* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing + * into the skb data or cb now. */ + hdr = NULL; + info = NULL; + err = dma_tx_fragment(ring, &skb); if (unlikely(err == -ENOKEY)) { /* Drop this packet, as we don't have the encryption key * anymore and must not transmit it unencrypted. */ diff --git a/drivers/net/wireless/b43/leds.h b/drivers/net/wireless/b43/leds.h index 4c56187810fc..32b66d53cdac 100644 --- a/drivers/net/wireless/b43/leds.h +++ b/drivers/net/wireless/b43/leds.h @@ -1,6 +1,7 @@ #ifndef B43_LEDS_H_ #define B43_LEDS_H_ +struct b43_wl; struct b43_wldev; #ifdef CONFIG_B43_LEDS diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index df6b26a0c05e..098dda1a67c1 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4501,7 +4501,6 @@ static void b43_op_stop(struct ieee80211_hw *hw) cancel_work_sync(&(wl->beacon_update_trigger)); - wiphy_rfkill_stop_polling(hw->wiphy); mutex_lock(&wl->mutex); if (b43_status(dev) >= B43_STAT_STARTED) { dev = b43_wireless_core_stop(dev); @@ -4522,9 +4521,8 @@ static int b43_op_beacon_set_tim(struct ieee80211_hw *hw, { struct b43_wl *wl = hw_to_b43_wl(hw); - mutex_lock(&wl->mutex); + /* FIXME: add locking */ b43_update_templates(wl); - mutex_unlock(&wl->mutex); return 0; } diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index 7a3218c5ba7d..ffdce6f3c909 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c @@ -33,7 +33,8 @@ bool b43_is_hw_radio_enabled(struct b43_wldev *dev) & B43_MMIO_RADIO_HWENABLED_HI_MASK)) return 1; } else { - if (b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO) + if (b43_status(dev) >= B43_STAT_STARTED && + b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO) & B43_MMIO_RADIO_HWENABLED_LO_MASK) return 1; } diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 240cff1e6979..6e2fc0cb6f8a 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -6029,7 +6029,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, struct ipw2100_priv *priv; struct net_device *dev; - dev = alloc_ieee80211(sizeof(struct ipw2100_priv), 0); + dev = alloc_ieee80211(sizeof(struct ipw2100_priv)); if (!dev) return NULL; priv = libipw_priv(dev); @@ -6342,7 +6342,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group); - free_ieee80211(dev, 0); + free_ieee80211(dev); pci_set_drvdata(pci_dev, NULL); } @@ -6400,7 +6400,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev) if (dev->base_addr) iounmap((void __iomem *)dev->base_addr); - free_ieee80211(dev, 0); + free_ieee80211(dev); } pci_release_regions(pci_dev); diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 827824d45de9..a6ca536e44f8 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -104,25 +104,6 @@ static int antenna = CFG_SYS_ANTENNA_BOTH; static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */ #endif -static struct ieee80211_rate ipw2200_rates[] = { - { .bitrate = 10 }, - { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 60 }, - { .bitrate = 90 }, - { .bitrate = 120 }, - { .bitrate = 180 }, - { .bitrate = 240 }, - { .bitrate = 360 }, - { .bitrate = 480 }, - { .bitrate = 540 } -}; - -#define ipw2200_a_rates (ipw2200_rates + 4) -#define ipw2200_num_a_rates 8 -#define ipw2200_bg_rates (ipw2200_rates + 0) -#define ipw2200_num_bg_rates 12 #ifdef CONFIG_IPW2200_QOS static int qos_enable = 0; @@ -8674,6 +8655,24 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option) * */ +static int ipw_wx_get_name(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ipw_priv *priv = libipw_priv(dev); + mutex_lock(&priv->mutex); + if (priv->status & STATUS_RF_KILL_MASK) + strcpy(wrqu->name, "radio off"); + else if (!(priv->status & STATUS_ASSOCIATED)) + strcpy(wrqu->name, "unassociated"); + else + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c", + ipw_modes[priv->assoc_request.ieee_mode]); + IPW_DEBUG_WX("Name: %s\n", wrqu->name); + mutex_unlock(&priv->mutex); + return 0; +} + static int ipw_set_channel(struct ipw_priv *priv, u8 channel) { if (channel == 0) { @@ -9973,7 +9972,7 @@ static int ipw_wx_sw_reset(struct net_device *dev, /* Rebase the WE IOCTLs to zero for the handler array */ #define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] static iw_handler ipw_wx_handlers[] = { - IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname, + IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name, IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, @@ -11417,100 +11416,16 @@ static void ipw_bg_down(struct work_struct *work) /* Called by register_netdev() */ static int ipw_net_init(struct net_device *dev) { - int i, rc = 0; struct ipw_priv *priv = libipw_priv(dev); - const struct libipw_geo *geo = libipw_get_geo(priv->ieee); - struct wireless_dev *wdev = &priv->ieee->wdev; mutex_lock(&priv->mutex); if (ipw_up(priv)) { - rc = -EIO; - goto out; - } - - memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN); - - /* fill-out priv->ieee->bg_band */ - if (geo->bg_channels) { - struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band; - - bg_band->band = IEEE80211_BAND_2GHZ; - bg_band->n_channels = geo->bg_channels; - bg_band->channels = - kzalloc(geo->bg_channels * - sizeof(struct ieee80211_channel), GFP_KERNEL); - /* translate geo->bg to bg_band.channels */ - for (i = 0; i < geo->bg_channels; i++) { - bg_band->channels[i].band = IEEE80211_BAND_2GHZ; - bg_band->channels[i].center_freq = geo->bg[i].freq; - bg_band->channels[i].hw_value = geo->bg[i].channel; - bg_band->channels[i].max_power = geo->bg[i].max_power; - if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) - bg_band->channels[i].flags |= - IEEE80211_CHAN_PASSIVE_SCAN; - if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS) - bg_band->channels[i].flags |= - IEEE80211_CHAN_NO_IBSS; - if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT) - bg_band->channels[i].flags |= - IEEE80211_CHAN_RADAR; - /* No equivalent for LIBIPW_CH_80211H_RULES, - LIBIPW_CH_UNIFORM_SPREADING, or - LIBIPW_CH_B_ONLY... */ - } - /* point at bitrate info */ - bg_band->bitrates = ipw2200_bg_rates; - bg_band->n_bitrates = ipw2200_num_bg_rates; - - wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band; - } - - /* fill-out priv->ieee->a_band */ - if (geo->a_channels) { - struct ieee80211_supported_band *a_band = &priv->ieee->a_band; - - a_band->band = IEEE80211_BAND_5GHZ; - a_band->n_channels = geo->a_channels; - a_band->channels = - kzalloc(geo->a_channels * - sizeof(struct ieee80211_channel), GFP_KERNEL); - /* translate geo->bg to a_band.channels */ - for (i = 0; i < geo->a_channels; i++) { - a_band->channels[i].band = IEEE80211_BAND_2GHZ; - a_band->channels[i].center_freq = geo->a[i].freq; - a_band->channels[i].hw_value = geo->a[i].channel; - a_band->channels[i].max_power = geo->a[i].max_power; - if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY) - a_band->channels[i].flags |= - IEEE80211_CHAN_PASSIVE_SCAN; - if (geo->a[i].flags & LIBIPW_CH_NO_IBSS) - a_band->channels[i].flags |= - IEEE80211_CHAN_NO_IBSS; - if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT) - a_band->channels[i].flags |= - IEEE80211_CHAN_RADAR; - /* No equivalent for LIBIPW_CH_80211H_RULES, - LIBIPW_CH_UNIFORM_SPREADING, or - LIBIPW_CH_B_ONLY... */ - } - /* point at bitrate info */ - a_band->bitrates = ipw2200_a_rates; - a_band->n_bitrates = ipw2200_num_a_rates; - - wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = a_band; - } - - set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev); - - /* With that information in place, we can now register the wiphy... */ - if (wiphy_register(wdev->wiphy)) { - rc = -EIO; - goto out; + mutex_unlock(&priv->mutex); + return -EIO; } -out: mutex_unlock(&priv->mutex); - return rc; + return 0; } /* PCI driver stuff */ @@ -11641,7 +11556,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv) if (priv->prom_net_dev) return -EPERM; - priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv), 1); + priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv)); if (priv->prom_net_dev == NULL) return -ENOMEM; @@ -11660,7 +11575,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv) rc = register_netdev(priv->prom_net_dev); if (rc) { - free_ieee80211(priv->prom_net_dev, 1); + free_ieee80211(priv->prom_net_dev); priv->prom_net_dev = NULL; return rc; } @@ -11674,7 +11589,7 @@ static void ipw_prom_free(struct ipw_priv *priv) return; unregister_netdev(priv->prom_net_dev); - free_ieee80211(priv->prom_net_dev, 1); + free_ieee80211(priv->prom_net_dev); priv->prom_net_dev = NULL; } @@ -11702,7 +11617,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, struct ipw_priv *priv; int i; - net_dev = alloc_ieee80211(sizeof(struct ipw_priv), 0); + net_dev = alloc_ieee80211(sizeof(struct ipw_priv)); if (net_dev == NULL) { err = -ENOMEM; goto out; @@ -11850,7 +11765,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); out_free_ieee80211: - free_ieee80211(priv->net_dev, 0); + free_ieee80211(priv->net_dev); out: return err; } @@ -11917,7 +11832,7 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev) pci_release_regions(pdev); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); - free_ieee80211(priv->net_dev, 0); + free_ieee80211(priv->net_dev); free_firmware(); } diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h index bf45391172f3..1e334ff6bd52 100644 --- a/drivers/net/wireless/ipw2x00/libipw.h +++ b/drivers/net/wireless/ipw2x00/libipw.h @@ -31,7 +31,6 @@ #include <linux/ieee80211.h> #include <net/lib80211.h> -#include <net/cfg80211.h> #define LIBIPW_VERSION "git-1.1.13" @@ -784,15 +783,12 @@ struct libipw_geo { struct libipw_device { struct net_device *dev; - struct wireless_dev wdev; struct libipw_security sec; /* Bookkeeping structures */ struct libipw_stats ieee_stats; struct libipw_geo geo; - struct ieee80211_supported_band bg_band; - struct ieee80211_supported_band a_band; /* Probe / Beacon management */ struct list_head network_free_list; @@ -1018,8 +1014,8 @@ static inline int libipw_is_cck_rate(u8 rate) } /* ieee80211.c */ -extern void free_ieee80211(struct net_device *dev, int monitor); -extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor); +extern void free_ieee80211(struct net_device *dev); +extern struct net_device *alloc_ieee80211(int sizeof_priv); extern int libipw_change_mtu(struct net_device *dev, int new_mtu); extern void libipw_networks_age(struct libipw_device *ieee, diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index a0e9f6aed7da..eb2b60834c17 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c @@ -62,9 +62,6 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_AUTHOR(DRV_COPYRIGHT); MODULE_LICENSE("GPL"); -struct cfg80211_ops libipw_config_ops = { }; -void *libipw_wiphy_privid = &libipw_wiphy_privid; - static int libipw_networks_allocate(struct libipw_device *ieee) { if (ieee->networks) @@ -143,7 +140,7 @@ int libipw_change_mtu(struct net_device *dev, int new_mtu) } EXPORT_SYMBOL(libipw_change_mtu); -struct net_device *alloc_ieee80211(int sizeof_priv, int monitor) +struct net_device *alloc_ieee80211(int sizeof_priv) { struct libipw_device *ieee; struct net_device *dev; @@ -160,31 +157,10 @@ struct net_device *alloc_ieee80211(int sizeof_priv, int monitor) ieee->dev = dev; - if (!monitor) { - ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0); - if (!ieee->wdev.wiphy) { - LIBIPW_ERROR("Unable to allocate wiphy.\n"); - goto failed_free_netdev; - } - - ieee->dev->ieee80211_ptr = &ieee->wdev; - ieee->wdev.iftype = NL80211_IFTYPE_STATION; - - /* Fill-out wiphy structure bits we know... Not enough info - here to call set_wiphy_dev or set MAC address or channel info - -- have to do that in ->ndo_init... */ - ieee->wdev.wiphy->privid = libipw_wiphy_privid; - - ieee->wdev.wiphy->max_scan_ssids = 1; - ieee->wdev.wiphy->max_scan_ie_len = 0; - ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) - | BIT(NL80211_IFTYPE_ADHOC); - } - err = libipw_networks_allocate(ieee); if (err) { LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err); - goto failed_free_wiphy; + goto failed_free_netdev; } libipw_networks_initialize(ieee); @@ -217,31 +193,19 @@ struct net_device *alloc_ieee80211(int sizeof_priv, int monitor) return dev; -failed_free_wiphy: - if (!monitor) - wiphy_free(ieee->wdev.wiphy); failed_free_netdev: free_netdev(dev); failed: return NULL; } -void free_ieee80211(struct net_device *dev, int monitor) +void free_ieee80211(struct net_device *dev) { struct libipw_device *ieee = netdev_priv(dev); lib80211_crypt_info_free(&ieee->crypt_info); libipw_networks_free(ieee); - - /* free cfg80211 resources */ - if (!monitor) { - wiphy_unregister(ieee->wdev.wiphy); - kfree(ieee->a_band.channels); - kfree(ieee->bg_band.channels); - wiphy_free(ieee->wdev.wiphy); - } - free_netdev(dev); } diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 2716b91ba9fa..950267ab556a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -161,5 +161,6 @@ struct iwl_cfg iwl1000_bgn_cfg = { .max_ll_items = OTP_MAX_LL_ITEMS_1000, .shadow_ram_support = false, .ht_greenfield_support = true, + .use_rts_for_ht = true, /* use rts/cts protection */ }; diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index c295b8ee9228..1473452ba22f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -175,6 +175,7 @@ struct iwl_cfg iwl6000h_2agn_cfg = { .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, .ht_greenfield_support = true, + .use_rts_for_ht = true, /* use rts/cts protection */ }; /* @@ -198,6 +199,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = { .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, .ht_greenfield_support = true, + .use_rts_for_ht = true, /* use rts/cts protection */ }; struct iwl_cfg iwl6050_2agn_cfg = { @@ -218,6 +220,7 @@ struct iwl_cfg iwl6050_2agn_cfg = { .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, .ht_greenfield_support = true, + .use_rts_for_ht = true, /* use rts/cts protection */ }; struct iwl_cfg iwl6000_3agn_cfg = { @@ -238,6 +241,7 @@ struct iwl_cfg iwl6000_3agn_cfg = { .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, .ht_greenfield_support = true, + .use_rts_for_ht = true, /* use rts/cts protection */ }; struct iwl_cfg iwl6050_3agn_cfg = { @@ -258,6 +262,7 @@ struct iwl_cfg iwl6050_3agn_cfg = { .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, .ht_greenfield_support = true, + .use_rts_for_ht = true, /* use rts/cts protection */ }; MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 346dc06fa7b7..81726ee32858 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -418,6 +418,15 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid, else if (tid == IWL_AGG_ALL_TID) for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); + if (priv->cfg->use_rts_for_ht) { + /* + * switch to RTS/CTS if it is the prefer protection method + * for HT traffic + */ + IWL_DEBUG_HT(priv, "use RTS/CTS protection for HT\n"); + priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN; + iwlcore_commit_rxon(priv); + } } static inline int get_num_of_ant_from_rate(u32 rate_n_flags) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index eaafae091f5b..921dc4a26fe2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -116,9 +116,6 @@ int iwl_commit_rxon(struct iwl_priv *priv) /* always get timestamp with Rx frame */ priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK; - /* allow CTS-to-self if possible. this is relevant only for - * 5000, but will not damage 4965 */ - priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN; ret = iwl_check_rxon_cmd(priv); if (ret) { @@ -218,6 +215,13 @@ int iwl_commit_rxon(struct iwl_priv *priv) "Could not send WEP static key.\n"); } + /* + * allow CTS-to-self if possible for new association. + * this is relevant only for 5000 series and up, + * but will not damage 4965 + */ + priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN; + /* Apply the new configuration * RXON assoc doesn't clear the station table in uCode, */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index e50103a956b1..7754538c2194 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -213,6 +213,7 @@ struct iwl_mod_params { * @pa_type: used by 6000 series only to identify the type of Power Amplifier * @max_ll_items: max number of OTP blocks * @shadow_ram_support: shadow support for OTP memory + * @use_rts_for_ht: use rts/cts protection for HT traffic * * We enable the driver to be backward compatible wrt API version. The * driver specifies which APIs it supports (with @ucode_api_max being the @@ -255,6 +256,7 @@ struct iwl_cfg { const bool shadow_ram_support; const bool ht_greenfield_support; const bool broken_powersave; + bool use_rts_for_ht; }; /*************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index fb9bcfa6d947..b7e196e3c8d3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -1277,8 +1277,16 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid) return -ENXIO; } + if (priv->stations[sta_id].tid[tid].agg.state == + IWL_EMPTYING_HW_QUEUE_ADDBA) { + IWL_DEBUG_HT(priv, "AGG stop before setup done\n"); + ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, ra, tid); + priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; + return 0; + } + if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON) - IWL_WARN(priv, "Stopping AGG while state not IWL_AGG_ON\n"); + IWL_WARN(priv, "Stopping AGG while state not ON or starting\n"); tid_data = &priv->stations[sta_id].tid[tid]; ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c index 039b555e4d76..53d56ab83c03 100644 --- a/drivers/net/wireless/libertas/ethtool.c +++ b/drivers/net/wireless/libertas/ethtool.c @@ -169,16 +169,19 @@ static int lbs_ethtool_set_wol(struct net_device *dev, struct lbs_private *priv = dev->ml_priv; uint32_t criteria = 0; - if (priv->wol_criteria == 0xffffffff && wol->wolopts) - return -EOPNOTSUPP; - if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY)) return -EOPNOTSUPP; - if (wol->wolopts & WAKE_UCAST) criteria |= EHS_WAKE_ON_UNICAST_DATA; - if (wol->wolopts & WAKE_MCAST) criteria |= EHS_WAKE_ON_MULTICAST_DATA; - if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA; - if (wol->wolopts & WAKE_PHY) criteria |= EHS_WAKE_ON_MAC_EVENT; + if (wol->wolopts & WAKE_UCAST) + criteria |= EHS_WAKE_ON_UNICAST_DATA; + if (wol->wolopts & WAKE_MCAST) + criteria |= EHS_WAKE_ON_MULTICAST_DATA; + if (wol->wolopts & WAKE_BCAST) + criteria |= EHS_WAKE_ON_BROADCAST_DATA; + if (wol->wolopts & WAKE_PHY) + criteria |= EHS_WAKE_ON_MAC_EVENT; + if (wol->wolopts == 0) + criteria |= EHS_REMOVE_WAKEUP; return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL); } diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index cb8be8d7abc1..5b3672c4d0cc 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -134,7 +134,7 @@ static void spu_transaction_finish(struct if_spi_card *card) static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) { int err = 0; - u16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK); + __le16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK); struct spi_message m; struct spi_transfer reg_trans; struct spi_transfer data_trans; @@ -166,7 +166,7 @@ static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val) { - u16 buff; + __le16 buff; buff = cpu_to_le16(val); return spu_write(card, reg, (u8 *)&buff, sizeof(u16)); @@ -188,7 +188,7 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) { unsigned int delay; int err = 0; - u16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK); + __le16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK); struct spi_message m; struct spi_transfer reg_trans; struct spi_transfer dummy_trans; @@ -235,7 +235,7 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) /* Read 16 bits from an SPI register */ static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val) { - u16 buf; + __le16 buf; int ret; ret = spu_read(card, reg, (u8 *)&buf, sizeof(buf)); @@ -248,7 +248,7 @@ static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val) * The low 16 bits are read first. */ static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val) { - u32 buf; + __le32 buf; int err; err = spu_read(card, reg, (u8 *)&buf, sizeof(buf)); diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 92bc8c5f1ca2..3fac4efa5ac8 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -508,7 +508,7 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp, /* Fill the receive configuration URB and initialise the Rx call back */ usb_fill_bulk_urb(cardp->rx_urb, cardp->udev, usb_rcvbulkpipe(cardp->udev, cardp->ep_in), - (void *) (skb->tail + (size_t) IPFIELD_ALIGN_OFFSET), + skb->data + IPFIELD_ALIGN_OFFSET, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn, cardp); diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 17e199546eeb..92af9b96bb7a 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -426,12 +426,16 @@ static const char p54u_romboot_3887[] = "~~~~"; static int p54u_firmware_reset_3887(struct ieee80211_hw *dev) { struct p54u_priv *priv = dev->priv; - u8 buf[4]; + u8 *buf; int ret; - memcpy(&buf, p54u_romboot_3887, sizeof(buf)); + buf = kmalloc(4, GFP_KERNEL); + if (!buf) + return -ENOMEM; + memcpy(buf, p54u_romboot_3887, 4); ret = p54u_bulk_msg(priv, P54U_PIPE_DATA, - buf, sizeof(buf)); + buf, 4); + kfree(buf); if (ret) dev_err(&priv->udev->dev, "(p54usb) unable to jump to " "boot ROM (%d)!\n", ret); diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 88cd58eb3b9f..1c88c2ea59aa 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -2879,7 +2879,7 @@ static int write_essid(struct file *file, const char __user *buffer, unsigned long count, void *data) { static char proc_essid[33]; - int len = count; + unsigned int len = count; if (len > 32) len = 32; diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index a084077a1c61..9fe770f7d7bb 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -1994,7 +1994,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size); rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID, test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? - (skbdesc->entry->entry_idx + 1) : 0xff); + txdesc->key_idx : 0xff); rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, skb->len - txdesc->l2pad); rt2x00_set_field32(&word, TXWI_W1_PACKETID, diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 71761b343839..73bbec58341e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -815,6 +815,8 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) mutex_init(&rt2x00dev->csr_mutex); + set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); + /* * Make room for rt2x00_intf inside the per-interface * structure ieee80211_vif. @@ -871,8 +873,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) rt2x00leds_register(rt2x00dev); rt2x00debug_register(rt2x00dev); - set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); - return 0; exit: diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index c64db0ba7f40..c708d0be9155 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -362,8 +362,9 @@ void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev) rt2x00link_reset_tuner(rt2x00dev, false); - ieee80211_queue_delayed_work(rt2x00dev->hw, - &link->work, LINK_TUNE_INTERVAL); + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) + ieee80211_queue_delayed_work(rt2x00dev->hw, + &link->work, LINK_TUNE_INTERVAL); } void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev) @@ -469,8 +470,10 @@ static void rt2x00link_tuner(struct work_struct *work) * Increase tuner counter, and reschedule the next link tuner run. */ link->count++; - ieee80211_queue_delayed_work(rt2x00dev->hw, - &link->work, LINK_TUNE_INTERVAL); + + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) + ieee80211_queue_delayed_work(rt2x00dev->hw, + &link->work, LINK_TUNE_INTERVAL); } void rt2x00link_register(struct rt2x00_dev *rt2x00dev) diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 501544882c2c..f02b48a90593 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -47,6 +47,8 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, (requesttype == USB_VENDOR_REQUEST_IN) ? usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0); + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) + return -ENODEV; for (i = 0; i < REGISTER_BUSY_COUNT; i++) { status = usb_control_msg(usb_dev, pipe, request, requesttype, @@ -60,8 +62,10 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, * -ENODEV: Device has disappeared, no point continuing. * All other errors: Try again. */ - else if (status == -ENODEV) + else if (status == -ENODEV) { + clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); break; + } } ERROR(rt2x00dev, @@ -161,6 +165,9 @@ int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev, { unsigned int i; + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) + return -ENODEV; + for (i = 0; i < REGISTER_BUSY_COUNT; i++) { rt2x00usb_register_read_lock(rt2x00dev, offset, reg); if (!rt2x00_get_field32(*reg, field)) diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index b8f5ee33445e..14e7bb210075 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2389,10 +2389,13 @@ static struct usb_device_id rt73usb_device_table[] = { { USB_DEVICE(0x13b1, 0x0023), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x13b1, 0x0028), USB_DEVICE_DATA(&rt73usb_ops) }, /* MSI */ + { USB_DEVICE(0x0db0, 0x4600), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0db0, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0db0, 0xa861), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0db0, 0xa874), USB_DEVICE_DATA(&rt73usb_ops) }, + /* Ovislink */ + { USB_DEVICE(0x1b75, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) }, /* Ralink */ { USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) }, @@ -2420,6 +2423,8 @@ static struct usb_device_id rt73usb_device_table[] = { /* Planex */ { USB_DEVICE(0x2019, 0xab01), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x2019, 0xab50), USB_DEVICE_DATA(&rt73usb_ops) }, + /* WideTell */ + { USB_DEVICE(0x7167, 0x3840), USB_DEVICE_DATA(&rt73usb_ops) }, /* Zcom */ { USB_DEVICE(0x0cde, 0x001c), USB_DEVICE_DATA(&rt73usb_ops) }, /* ZyXEL */ diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c index a1c670fc1552..cf8a4a40fdf6 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_leds.c +++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c @@ -210,10 +210,10 @@ void rtl8187_leds_exit(struct ieee80211_hw *dev) /* turn the LED off before exiting */ ieee80211_queue_delayed_work(dev, &priv->led_off, 0); - cancel_delayed_work_sync(&priv->led_off); - cancel_delayed_work_sync(&priv->led_on); rtl8187_unregister_led(&priv->led_rx); rtl8187_unregister_led(&priv->led_tx); + cancel_delayed_work_sync(&priv->led_off); + cancel_delayed_work_sync(&priv->led_on); } #endif /* def CONFIG_RTL8187_LED */ diff --git a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c index 9fab13e4004e..cad8037ab2af 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c +++ b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c @@ -18,6 +18,7 @@ #include <net/mac80211.h> #include "rtl8187.h" +#include "rtl8187_rfkill.h" static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv) { |