diff options
56 files changed, 1112 insertions, 369 deletions
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index ebf80b983063..0a0512ae77da 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -273,6 +273,7 @@ obj-$(CONFIG_USB_RTL8150) += usb/ obj-$(CONFIG_USB_HSO) += usb/ obj-$(CONFIG_USB_USBNET) += usb/ obj-$(CONFIG_USB_ZD1201) += usb/ +obj-$(CONFIG_USB_IPHETH) += usb/ obj-y += wireless/ obj-$(CONFIG_NET_TULIP) += tulip/ diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 33451092b8e8..d800b598ae3d 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -1006,7 +1006,7 @@ static int ems_usb_probe(struct usb_interface *intf, netdev = alloc_candev(sizeof(struct ems_usb), MAX_TX_URBS); if (!netdev) { - dev_err(netdev->dev.parent, "Couldn't alloc candev\n"); + dev_err(&intf->dev, "ems_usb: Couldn't alloc candev\n"); return -ENOMEM; } @@ -1036,20 +1036,20 @@ static int ems_usb_probe(struct usb_interface *intf, dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->intr_urb) { - dev_err(netdev->dev.parent, "Couldn't alloc intr URB\n"); + dev_err(&intf->dev, "Couldn't alloc intr URB\n"); goto cleanup_candev; } dev->intr_in_buffer = kzalloc(INTR_IN_BUFFER_SIZE, GFP_KERNEL); if (!dev->intr_in_buffer) { - dev_err(netdev->dev.parent, "Couldn't alloc Intr buffer\n"); + dev_err(&intf->dev, "Couldn't alloc Intr buffer\n"); goto cleanup_intr_urb; } dev->tx_msg_buffer = kzalloc(CPC_HEADER_SIZE + sizeof(struct ems_cpc_msg), GFP_KERNEL); if (!dev->tx_msg_buffer) { - dev_err(netdev->dev.parent, "Couldn't alloc Tx buffer\n"); + dev_err(&intf->dev, "Couldn't alloc Tx buffer\n"); goto cleanup_intr_in_buffer; } diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c index 5248f9e0b2f4..35cd36729155 100644 --- a/drivers/net/cxgb3/ael1002.c +++ b/drivers/net/cxgb3/ael1002.c @@ -934,7 +934,7 @@ static struct cphy_ops xaui_direct_ops = { int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, const struct mdio_ops *mdio_ops) { - cphy_init(phy, adapter, MDIO_PRTAD_NONE, &xaui_direct_ops, mdio_ops, + cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops, SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, "10GBASE-CX4"); return 0; diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index aced6c5e635c..e3f1b8566495 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -439,7 +439,7 @@ static void free_irq_resources(struct adapter *adapter) static int await_mgmt_replies(struct adapter *adap, unsigned long init_cnt, unsigned long n) { - int attempts = 5; + int attempts = 10; while (adap->sge.qs[0].rspq.offload_pkts < init_cnt + n) { if (!--attempts) diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 3e8d0005540f..ef97bfcef9dd 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -168,6 +168,7 @@ #include <linux/ethtool.h> #include <linux/string.h> #include <linux/firmware.h> +#include <linux/rtnetlink.h> #include <asm/unaligned.h> @@ -2280,8 +2281,13 @@ static void e100_tx_timeout_task(struct work_struct *work) netif_printk(nic, tx_err, KERN_DEBUG, nic->netdev, "scb.status=0x%02X\n", ioread8(&nic->csr->scb.status)); - e100_down(netdev_priv(netdev)); - e100_up(netdev_priv(netdev)); + + rtnl_lock(); + if (netif_running(netdev)) { + e100_down(netdev_priv(netdev)); + e100_up(netdev_priv(netdev)); + } + rtnl_unlock(); } static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode) diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 4b0016d69530..17a25e19bbba 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -336,7 +336,6 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; static int global_quad_port_a; /* global port a indication */ struct pci_dev *pdev = adapter->pdev; - u16 eeprom_data = 0; int is_port_b = er32(STATUS) & E1000_STATUS_FUNC_1; s32 rc; @@ -387,16 +386,15 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter) if (pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD) adapter->flags &= ~FLAG_HAS_WOL; break; - case e1000_82573: + case e1000_82574: + case e1000_82583: + /* Disable ASPM L0s due to hardware errata */ + e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L0S); + if (pdev->device == E1000_DEV_ID_82573L) { - if (e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1, - &eeprom_data) < 0) - break; - if (!(eeprom_data & NVM_WORD1A_ASPM_MASK)) { - adapter->flags |= FLAG_HAS_JUMBO_FRAMES; - adapter->max_hw_frame_size = DEFAULT_JUMBO; - } + adapter->flags |= FLAG_HAS_JUMBO_FRAMES; + adapter->max_hw_frame_size = DEFAULT_JUMBO; } break; default: @@ -1792,6 +1790,7 @@ struct e1000_info e1000_82571_info = { | FLAG_RESET_OVERWRITES_LAA /* errata */ | FLAG_TARC_SPEED_MODE_BIT /* errata */ | FLAG_APME_CHECK_PORT_B, + .flags2 = FLAG2_DISABLE_ASPM_L1, /* errata 13 */ .pba = 38, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, @@ -1809,6 +1808,7 @@ struct e1000_info e1000_82572_info = { | FLAG_RX_CSUM_ENABLED | FLAG_HAS_CTRLEXT_ON_LOAD | FLAG_TARC_SPEED_MODE_BIT, /* errata */ + .flags2 = FLAG2_DISABLE_ASPM_L1, /* errata 13 */ .pba = 38, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, @@ -1820,13 +1820,11 @@ struct e1000_info e1000_82572_info = { struct e1000_info e1000_82573_info = { .mac = e1000_82573, .flags = FLAG_HAS_HW_VLAN_FILTER - | FLAG_HAS_JUMBO_FRAMES | FLAG_HAS_WOL | FLAG_APME_IN_CTRL3 | FLAG_RX_CSUM_ENABLED | FLAG_HAS_SMART_POWER_DOWN | FLAG_HAS_AMT - | FLAG_HAS_ERT | FLAG_HAS_SWSM_ON_LOAD, .pba = 20, .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 12648a1cdb78..906c4daaabe9 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -37,6 +37,7 @@ #include <linux/io.h> #include <linux/netdevice.h> #include <linux/pci.h> +#include <linux/pci-aspm.h> #include "hw.h" @@ -370,7 +371,7 @@ struct e1000_adapter { struct e1000_info { enum e1000_mac_type mac; unsigned int flags; - unsigned int flags2; + unsigned int flags2; u32 pba; u32 max_hw_frame_size; s32 (*get_variants)(struct e1000_adapter *); @@ -417,6 +418,7 @@ struct e1000_info { #define FLAG2_CRC_STRIPPING (1 << 0) #define FLAG2_HAS_PHY_WAKEUP (1 << 1) #define FLAG2_IS_DISCARDING (1 << 2) +#define FLAG2_DISABLE_ASPM_L1 (1 << 3) #define E1000_RX_DESC_PS(R, i) \ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) @@ -457,6 +459,7 @@ extern void e1000e_update_stats(struct e1000_adapter *adapter); extern bool e1000e_has_link(struct e1000_adapter *adapter); extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter); extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); +extern void e1000e_disable_aspm(struct pci_dev *pdev, u16 state); extern unsigned int copybreak; diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 5f70c437fa41..2476f8c24c54 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -4310,6 +4310,14 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) return -EINVAL; } + /* 82573 Errata 17 */ + if (((adapter->hw.mac.type == e1000_82573) || + (adapter->hw.mac.type == e1000_82574)) && + (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN)) { + adapter->flags2 |= FLAG2_DISABLE_ASPM_L1; + e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L1); + } + while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) msleep(1); /* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */ @@ -4634,29 +4642,39 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep, } } -static void e1000e_disable_l1aspm(struct pci_dev *pdev) +#ifdef CONFIG_PCIEASPM +static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state) +{ + pci_disable_link_state(pdev, state); +} +#else +static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state) { int pos; - u16 val; + u16 reg16; /* - * 82573 workaround - disable L1 ASPM on mobile chipsets - * - * L1 ASPM on various mobile (ich7) chipsets do not behave properly - * resulting in lost data or garbage information on the pci-e link - * level. This could result in (false) bad EEPROM checksum errors, - * long ping times (up to 2s) or even a system freeze/hang. - * - * Unfortunately this feature saves about 1W power consumption when - * active. + * Both device and parent should have the same ASPM setting. + * Disable ASPM in downstream component first and then upstream. */ - pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); - pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val); - if (val & 0x2) { - dev_warn(&pdev->dev, "Disabling L1 ASPM\n"); - val &= ~0x2; - pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, val); - } + pos = pci_pcie_cap(pdev); + pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); + reg16 &= ~state; + pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); + + pos = pci_pcie_cap(pdev->bus->self); + pci_read_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, ®16); + reg16 &= ~state; + pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16); +} +#endif +void e1000e_disable_aspm(struct pci_dev *pdev, u16 state) +{ + dev_info(&pdev->dev, "Disabling ASPM %s %s\n", + (state & PCIE_LINK_STATE_L0S) ? "L0s" : "", + (state & PCIE_LINK_STATE_L1) ? "L1" : ""); + + __e1000e_disable_aspm(pdev, state); } #ifdef CONFIG_PM_OPS @@ -4672,7 +4690,11 @@ static int __e1000_resume(struct pci_dev *pdev) struct e1000_hw *hw = &adapter->hw; u32 err; - e1000e_disable_l1aspm(pdev); + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + pci_save_state(pdev); + if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1) + e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1); e1000e_set_interrupt_capability(adapter); if (netif_running(netdev)) { @@ -4877,7 +4899,8 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) int err; pci_ers_result_t result; - e1000e_disable_l1aspm(pdev); + if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1) + e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1); err = pci_enable_device_mem(pdev); if (err) { dev_err(&pdev->dev, @@ -4971,13 +4994,6 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter) dev_warn(&adapter->pdev->dev, "Warning: detected DSPD enabled in EEPROM\n"); } - - ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf); - if (!ret_val && (le16_to_cpu(buf) & (3 << 2))) { - /* ASPM enable */ - dev_warn(&adapter->pdev->dev, - "Warning: detected ASPM enabled in EEPROM\n"); - } } static const struct net_device_ops e1000e_netdev_ops = { @@ -5026,7 +5042,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, u16 eeprom_data = 0; u16 eeprom_apme_mask = E1000_EEPROM_APME; - e1000e_disable_l1aspm(pdev); + if (ei->flags2 & FLAG2_DISABLE_ASPM_L1) + e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1); err = pci_enable_device_mem(pdev); if (err) diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index d5160edf2fcf..3acac5f930c8 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -205,8 +205,6 @@ static int fsl_pq_mdio_find_free(struct mii_bus *new_bus) static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct device_node *np) { struct gfar __iomem *enet_regs; - u32 __iomem *ioremap_tbipa; - u64 addr, size; /* * This is mildly evil, but so is our hardware for doing this. @@ -220,9 +218,7 @@ static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct devi return &enet_regs->tbipa; } else if (of_device_is_compatible(np, "fsl,etsec2-mdio") || of_device_is_compatible(np, "fsl,etsec2-tbi")) { - addr = of_translate_address(np, of_get_address(np, 1, &size, NULL)); - ioremap_tbipa = ioremap(addr, size); - return ioremap_tbipa; + return of_iomap(np, 1); } else return NULL; } @@ -279,6 +275,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, u32 __iomem *tbipa; struct mii_bus *new_bus; int tbiaddr = -1; + const u32 *addrp; u64 addr = 0, size = 0; int err = 0; @@ -297,8 +294,19 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, new_bus->priv = priv; fsl_pq_mdio_bus_name(new_bus->id, np); + addrp = of_get_address(np, 0, &size, NULL); + if (!addrp) { + err = -EINVAL; + goto err_free_bus; + } + /* Set the PHY base address */ - addr = of_translate_address(np, of_get_address(np, 0, &size, NULL)); + addr = of_translate_address(np, addrp); + if (addr == OF_BAD_ADDR) { + err = -EINVAL; + goto err_free_bus; + } + map = ioremap(addr, size); if (!map) { err = -ENOMEM; diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 032073d1e3d2..0cef967499d3 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -558,12 +558,8 @@ static int gfar_parse_group(struct device_node *np, struct gfar_private *priv, const char *model) { u32 *queue_mask; - u64 addr, size; - - addr = of_translate_address(np, - of_get_address(np, 0, &size, NULL)); - priv->gfargrp[priv->num_grps].regs = ioremap(addr, size); + priv->gfargrp[priv->num_grps].regs = of_iomap(np, 0); if (!priv->gfargrp[priv->num_grps].regs) return -ENOMEM; diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index 31d24e0e76de..24d9be64342f 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -610,11 +610,7 @@ #define IGP_LED3_MODE 0x07000000 /* PCI/PCI-X/PCI-EX Config space */ -#define PCIE_LINK_STATUS 0x12 #define PCIE_DEVICE_CONTROL2 0x28 - -#define PCIE_LINK_WIDTH_MASK 0x3F0 -#define PCIE_LINK_WIDTH_SHIFT 4 #define PCIE_DEVICE_CONTROL2_16ms 0x0005 #define PHY_REVISION_MASK 0xFFFFFFF0 diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c index be8d010e4021..90c5e01e9235 100644 --- a/drivers/net/igb/e1000_mac.c +++ b/drivers/net/igb/e1000_mac.c @@ -53,17 +53,30 @@ s32 igb_get_bus_info_pcie(struct e1000_hw *hw) u16 pcie_link_status; bus->type = e1000_bus_type_pci_express; - bus->speed = e1000_bus_speed_2500; ret_val = igb_read_pcie_cap_reg(hw, - PCIE_LINK_STATUS, - &pcie_link_status); - if (ret_val) + PCI_EXP_LNKSTA, + &pcie_link_status); + if (ret_val) { bus->width = e1000_bus_width_unknown; - else + bus->speed = e1000_bus_speed_unknown; + } else { + switch (pcie_link_status & PCI_EXP_LNKSTA_CLS) { + case PCI_EXP_LNKSTA_CLS_2_5GB: + bus->speed = e1000_bus_speed_2500; + break; + case PCI_EXP_LNKSTA_CLS_5_0GB: + bus->speed = e1000_bus_speed_5000; + break; + default: + bus->speed = e1000_bus_speed_unknown; + break; + } + bus->width = (enum e1000_bus_width)((pcie_link_status & - PCIE_LINK_WIDTH_MASK) >> - PCIE_LINK_WIDTH_SHIFT); + PCI_EXP_LNKSTA_NLW) >> + PCI_EXP_LNKSTA_NLW_SHIFT); + } reg = rd32(E1000_STATUS); bus->func = (reg & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT; diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index c19b1e0caecd..919e36386675 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1638,6 +1638,7 @@ static int __devinit igb_probe(struct pci_dev *pdev, dev_info(&pdev->dev, "%s: (PCIe:%s:%s) %pM\n", netdev->name, ((hw->bus.speed == e1000_bus_speed_2500) ? "2.5Gb/s" : + (hw->bus.speed == e1000_bus_speed_5000) ? "5.0Gb/s" : "unknown"), ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" : (hw->bus.width == e1000_bus_width_pcie_x2) ? "Width x2" : @@ -5248,7 +5249,7 @@ static bool igb_clean_rx_irq_adv(struct igb_q_vector *q_vector, PAGE_SIZE / 2, PCI_DMA_FROMDEVICE); buffer_info->page_dma = 0; - skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags++, + skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, buffer_info->page, buffer_info->page_offset, length); diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index cc2309027e6a..9ac3f9428195 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -289,7 +289,7 @@ static bool igbvf_clean_rx_irq(struct igbvf_adapter *adapter, PCI_DMA_FROMDEVICE); buffer_info->page_dma = 0; - skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags++, + skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, buffer_info->page, buffer_info->page_offset, length); diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h index 92d2e71d0c8b..521c0c732998 100644 --- a/drivers/net/ixgb/ixgb.h +++ b/drivers/net/ixgb/ixgb.h @@ -78,9 +78,13 @@ struct ixgb_adapter; #define PFX "ixgb: " #ifdef _DEBUG_DRIVER_ -#define IXGB_DBG(args...) printk(KERN_DEBUG PFX args) +#define IXGB_DBG(fmt, args...) printk(KERN_DEBUG PFX fmt, ##args) #else -#define IXGB_DBG(args...) +#define IXGB_DBG(fmt, args...) \ +do { \ + if (0) \ + printk(KERN_DEBUG PFX fmt, ##args); \ +} while (0) #endif /* TX/RX descriptor defines */ diff --git a/drivers/net/ixgb/ixgb_ee.c b/drivers/net/ixgb/ixgb_ee.c index 89ffa7264a12..06303a36aaf7 100644 --- a/drivers/net/ixgb/ixgb_ee.c +++ b/drivers/net/ixgb/ixgb_ee.c @@ -26,6 +26,8 @@ *******************************************************************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "ixgb_hw.h" #include "ixgb_ee.h" /* Local prototypes */ @@ -467,11 +469,11 @@ ixgb_get_eeprom_data(struct ixgb_hw *hw) u16 checksum = 0; struct ixgb_ee_map_type *ee_map; - DEBUGFUNC("ixgb_get_eeprom_data"); + ENTER(); ee_map = (struct ixgb_ee_map_type *)hw->eeprom; - DEBUGOUT("ixgb_ee: Reading eeprom data\n"); + pr_debug("Reading eeprom data\n"); for (i = 0; i < IXGB_EEPROM_SIZE ; i++) { u16 ee_data; ee_data = ixgb_read_eeprom(hw, i); @@ -480,7 +482,7 @@ ixgb_get_eeprom_data(struct ixgb_hw *hw) } if (checksum != (u16) EEPROM_SUM) { - DEBUGOUT("ixgb_ee: Checksum invalid.\n"); + pr_debug("Checksum invalid\n"); /* clear the init_ctrl_reg_1 to signify that the cache is * invalidated */ ee_map->init_ctrl_reg_1 = cpu_to_le16(EEPROM_ICW1_SIGNATURE_CLEAR); @@ -489,7 +491,7 @@ ixgb_get_eeprom_data(struct ixgb_hw *hw) if ((ee_map->init_ctrl_reg_1 & cpu_to_le16(EEPROM_ICW1_SIGNATURE_MASK)) != cpu_to_le16(EEPROM_ICW1_SIGNATURE_VALID)) { - DEBUGOUT("ixgb_ee: Signature invalid.\n"); + pr_debug("Signature invalid\n"); return(false); } @@ -555,13 +557,13 @@ ixgb_get_ee_mac_addr(struct ixgb_hw *hw, int i; struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; - DEBUGFUNC("ixgb_get_ee_mac_addr"); + ENTER(); if (ixgb_check_and_get_eeprom_data(hw) == true) { for (i = 0; i < IXGB_ETH_LENGTH_OF_ADDRESS; i++) { mac_addr[i] = ee_map->mac_addr[i]; - DEBUGOUT2("mac(%d) = %.2X\n", i, mac_addr[i]); } + pr_debug("eeprom mac address = %pM\n", mac_addr); } } diff --git a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c index ff67a84e6802..cd247b8d2b73 100644 --- a/drivers/net/ixgb/ixgb_hw.c +++ b/drivers/net/ixgb/ixgb_hw.c @@ -30,9 +30,13 @@ * Shared functions for accessing and configuring the adapter */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "ixgb_hw.h" #include "ixgb_ids.h" +#include <linux/etherdevice.h> + /* Local function prototypes */ static u32 ixgb_hash_mc_addr(struct ixgb_hw *hw, u8 * mc_addr); @@ -120,13 +124,13 @@ ixgb_adapter_stop(struct ixgb_hw *hw) u32 ctrl_reg; u32 icr_reg; - DEBUGFUNC("ixgb_adapter_stop"); + ENTER(); /* If we are stopped or resetting exit gracefully and wait to be * started again before accessing the hardware. */ if (hw->adapter_stopped) { - DEBUGOUT("Exiting because the adapter is already stopped!!!\n"); + pr_debug("Exiting because the adapter is already stopped!!!\n"); return false; } @@ -136,7 +140,7 @@ ixgb_adapter_stop(struct ixgb_hw *hw) hw->adapter_stopped = true; /* Clear interrupt mask to stop board from generating interrupts */ - DEBUGOUT("Masking off all interrupts\n"); + pr_debug("Masking off all interrupts\n"); IXGB_WRITE_REG(hw, IMC, 0xFFFFFFFF); /* Disable the Transmit and Receive units. Then delay to allow @@ -152,12 +156,12 @@ ixgb_adapter_stop(struct ixgb_hw *hw) * the current PCI configuration. The global reset bit is self- * clearing, and should clear within a microsecond. */ - DEBUGOUT("Issuing a global reset to MAC\n"); + pr_debug("Issuing a global reset to MAC\n"); ctrl_reg = ixgb_mac_reset(hw); /* Clear interrupt mask to stop board from generating interrupts */ - DEBUGOUT("Masking off all interrupts\n"); + pr_debug("Masking off all interrupts\n"); IXGB_WRITE_REG(hw, IMC, 0xffffffff); /* Clear any pending interrupt events. */ @@ -183,7 +187,7 @@ ixgb_identify_xpak_vendor(struct ixgb_hw *hw) u16 vendor_name[5]; ixgb_xpak_vendor xpak_vendor; - DEBUGFUNC("ixgb_identify_xpak_vendor"); + ENTER(); /* Read the first few bytes of the vendor string from the XPAK NVR * registers. These are standard XENPAK/XPAK registers, so all XPAK @@ -222,12 +226,12 @@ ixgb_identify_phy(struct ixgb_hw *hw) ixgb_phy_type phy_type; ixgb_xpak_vendor xpak_vendor; - DEBUGFUNC("ixgb_identify_phy"); + ENTER(); /* Infer the transceiver/phy type from the device id */ switch (hw->device_id) { case IXGB_DEVICE_ID_82597EX: - DEBUGOUT("Identified TXN17401 optics\n"); + pr_debug("Identified TXN17401 optics\n"); phy_type = ixgb_phy_type_txn17401; break; @@ -237,30 +241,30 @@ ixgb_identify_phy(struct ixgb_hw *hw) * type of optics. */ xpak_vendor = ixgb_identify_xpak_vendor(hw); if (xpak_vendor == ixgb_xpak_vendor_intel) { - DEBUGOUT("Identified TXN17201 optics\n"); + pr_debug("Identified TXN17201 optics\n"); phy_type = ixgb_phy_type_txn17201; } else { - DEBUGOUT("Identified G6005 optics\n"); + pr_debug("Identified G6005 optics\n"); phy_type = ixgb_phy_type_g6005; } break; case IXGB_DEVICE_ID_82597EX_LR: - DEBUGOUT("Identified G6104 optics\n"); + pr_debug("Identified G6104 optics\n"); phy_type = ixgb_phy_type_g6104; break; case IXGB_DEVICE_ID_82597EX_CX4: - DEBUGOUT("Identified CX4\n"); + pr_debug("Identified CX4\n"); xpak_vendor = ixgb_identify_xpak_vendor(hw); if (xpak_vendor == ixgb_xpak_vendor_intel) { - DEBUGOUT("Identified TXN17201 optics\n"); + pr_debug("Identified TXN17201 optics\n"); phy_type = ixgb_phy_type_txn17201; } else { - DEBUGOUT("Identified G6005 optics\n"); + pr_debug("Identified G6005 optics\n"); phy_type = ixgb_phy_type_g6005; } break; default: - DEBUGOUT("Unknown physical layer module\n"); + pr_debug("Unknown physical layer module\n"); phy_type = ixgb_phy_type_unknown; break; } @@ -296,18 +300,18 @@ ixgb_init_hw(struct ixgb_hw *hw) u32 ctrl_reg; bool status; - DEBUGFUNC("ixgb_init_hw"); + ENTER(); /* Issue a global reset to the MAC. This will reset the chip's * transmit, receive, DMA, and link units. It will not effect * the current PCI configuration. The global reset bit is self- * clearing, and should clear within a microsecond. */ - DEBUGOUT("Issuing a global reset to MAC\n"); + pr_debug("Issuing a global reset to MAC\n"); ctrl_reg = ixgb_mac_reset(hw); - DEBUGOUT("Issuing an EE reset to MAC\n"); + pr_debug("Issuing an EE reset to MAC\n"); #ifdef HP_ZX1 /* Workaround for 82597EX reset errata */ IXGB_WRITE_REG_IO(hw, CTRL1, IXGB_CTRL1_EE_RST); @@ -335,7 +339,7 @@ ixgb_init_hw(struct ixgb_hw *hw) * If it is not valid, we fail hardware init. */ if (!mac_addr_valid(hw->curr_mac_addr)) { - DEBUGOUT("MAC address invalid after ixgb_init_rx_addrs\n"); + pr_debug("MAC address invalid after ixgb_init_rx_addrs\n"); return(false); } @@ -346,7 +350,7 @@ ixgb_init_hw(struct ixgb_hw *hw) ixgb_get_bus_info(hw); /* Zero out the Multicast HASH table */ - DEBUGOUT("Zeroing the MTA\n"); + pr_debug("Zeroing the MTA\n"); for (i = 0; i < IXGB_MC_TBL_SIZE; i++) IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0); @@ -379,7 +383,7 @@ ixgb_init_rx_addrs(struct ixgb_hw *hw) { u32 i; - DEBUGFUNC("ixgb_init_rx_addrs"); + ENTER(); /* * If the current mac address is valid, assume it is a software override @@ -391,28 +395,19 @@ ixgb_init_rx_addrs(struct ixgb_hw *hw) /* Get the MAC address from the eeprom for later reference */ ixgb_get_ee_mac_addr(hw, hw->curr_mac_addr); - DEBUGOUT3(" Keeping Permanent MAC Addr =%.2X %.2X %.2X ", - hw->curr_mac_addr[0], - hw->curr_mac_addr[1], hw->curr_mac_addr[2]); - DEBUGOUT3("%.2X %.2X %.2X\n", - hw->curr_mac_addr[3], - hw->curr_mac_addr[4], hw->curr_mac_addr[5]); + pr_debug("Keeping Permanent MAC Addr = %pM\n", + hw->curr_mac_addr); } else { /* Setup the receive address. */ - DEBUGOUT("Overriding MAC Address in RAR[0]\n"); - DEBUGOUT3(" New MAC Addr =%.2X %.2X %.2X ", - hw->curr_mac_addr[0], - hw->curr_mac_addr[1], hw->curr_mac_addr[2]); - DEBUGOUT3("%.2X %.2X %.2X\n", - hw->curr_mac_addr[3], - hw->curr_mac_addr[4], hw->curr_mac_addr[5]); + pr_debug("Overriding MAC Address in RAR[0]\n"); + pr_debug("New MAC Addr = %pM\n", hw->curr_mac_addr); ixgb_rar_set(hw, hw->curr_mac_addr, 0); } /* Zero out the other 15 receive addresses. */ - DEBUGOUT("Clearing RAR[1-15]\n"); + pr_debug("Clearing RAR[1-15]\n"); for (i = 1; i < IXGB_RAR_ENTRIES; i++) { /* Write high reg first to disable the AV bit first */ IXGB_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); @@ -444,64 +439,50 @@ ixgb_mc_addr_list_update(struct ixgb_hw *hw, u32 hash_value; u32 i; u32 rar_used_count = 1; /* RAR[0] is used for our MAC address */ + u8 *mca; - DEBUGFUNC("ixgb_mc_addr_list_update"); + ENTER(); /* Set the new number of MC addresses that we are being requested to use. */ hw->num_mc_addrs = mc_addr_count; /* Clear RAR[1-15] */ - DEBUGOUT(" Clearing RAR[1-15]\n"); + pr_debug("Clearing RAR[1-15]\n"); for (i = rar_used_count; i < IXGB_RAR_ENTRIES; i++) { IXGB_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); IXGB_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); } /* Clear the MTA */ - DEBUGOUT(" Clearing MTA\n"); + pr_debug("Clearing MTA\n"); for (i = 0; i < IXGB_MC_TBL_SIZE; i++) IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0); /* Add the new addresses */ + mca = mc_addr_list; for (i = 0; i < mc_addr_count; i++) { - DEBUGOUT(" Adding the multicast addresses:\n"); - DEBUGOUT7(" MC Addr #%d =%.2X %.2X %.2X %.2X %.2X %.2X\n", i, - mc_addr_list[i * (IXGB_ETH_LENGTH_OF_ADDRESS + pad)], - mc_addr_list[i * (IXGB_ETH_LENGTH_OF_ADDRESS + pad) + - 1], - mc_addr_list[i * (IXGB_ETH_LENGTH_OF_ADDRESS + pad) + - 2], - mc_addr_list[i * (IXGB_ETH_LENGTH_OF_ADDRESS + pad) + - 3], - mc_addr_list[i * (IXGB_ETH_LENGTH_OF_ADDRESS + pad) + - 4], - mc_addr_list[i * (IXGB_ETH_LENGTH_OF_ADDRESS + pad) + - 5]); + pr_debug("Adding the multicast addresses:\n"); + pr_debug("MC Addr #%d = %pM\n", i, mca); /* Place this multicast address in the RAR if there is room, * * else put it in the MTA */ if (rar_used_count < IXGB_RAR_ENTRIES) { - ixgb_rar_set(hw, - mc_addr_list + - (i * (IXGB_ETH_LENGTH_OF_ADDRESS + pad)), - rar_used_count); - DEBUGOUT1("Added a multicast address to RAR[%d]\n", i); + ixgb_rar_set(hw, mca, rar_used_count); + pr_debug("Added a multicast address to RAR[%d]\n", i); rar_used_count++; } else { - hash_value = ixgb_hash_mc_addr(hw, - mc_addr_list + - (i * - (IXGB_ETH_LENGTH_OF_ADDRESS - + pad))); + hash_value = ixgb_hash_mc_addr(hw, mca); - DEBUGOUT1(" Hash value = 0x%03X\n", hash_value); + pr_debug("Hash value = 0x%03X\n", hash_value); ixgb_mta_set(hw, hash_value); } + + mca += IXGB_ETH_LENGTH_OF_ADDRESS + pad; } - DEBUGOUT("MC Update Complete\n"); + pr_debug("MC Update Complete\n"); return; } @@ -520,7 +501,7 @@ ixgb_hash_mc_addr(struct ixgb_hw *hw, { u32 hash_value = 0; - DEBUGFUNC("ixgb_hash_mc_addr"); + ENTER(); /* The portion of the address that is used for the hash table is * determined by the mc_filter_type setting. @@ -547,7 +528,7 @@ ixgb_hash_mc_addr(struct ixgb_hw *hw, break; default: /* Invalid mc_filter_type, what should we do? */ - DEBUGOUT("MC filter type param set incorrectly\n"); + pr_debug("MC filter type param set incorrectly\n"); ASSERT(0); break; } @@ -603,7 +584,7 @@ ixgb_rar_set(struct ixgb_hw *hw, { u32 rar_low, rar_high; - DEBUGFUNC("ixgb_rar_set"); + ENTER(); /* HW expects these in little endian so we reverse the byte order * from network order (big endian) to little endian @@ -666,7 +647,7 @@ ixgb_setup_fc(struct ixgb_hw *hw) u32 pap_reg = 0; /* by default, assume no pause time */ bool status = true; - DEBUGFUNC("ixgb_setup_fc"); + ENTER(); /* Get the current control reg 0 settings */ ctrl_reg = IXGB_READ_REG(hw, CTRL0); @@ -710,7 +691,7 @@ ixgb_setup_fc(struct ixgb_hw *hw) break; default: /* We should never get here. The value should be 0-3. */ - DEBUGOUT("Flow control param set incorrectly\n"); + pr_debug("Flow control param set incorrectly\n"); ASSERT(0); break; } @@ -940,7 +921,7 @@ ixgb_check_for_link(struct ixgb_hw *hw) u32 status_reg; u32 xpcss_reg; - DEBUGFUNC("ixgb_check_for_link"); + ENTER(); xpcss_reg = IXGB_READ_REG(hw, XPCSS); status_reg = IXGB_READ_REG(hw, STATUS); @@ -950,7 +931,7 @@ ixgb_check_for_link(struct ixgb_hw *hw) hw->link_up = true; } else if (!(xpcss_reg & IXGB_XPCSS_ALIGN_STATUS) && (status_reg & IXGB_STATUS_LU)) { - DEBUGOUT("XPCSS Not Aligned while Status:LU is set.\n"); + pr_debug("XPCSS Not Aligned while Status:LU is set\n"); hw->link_up = ixgb_link_reset(hw); } else { /* @@ -981,8 +962,7 @@ bool ixgb_check_for_bad_link(struct ixgb_hw *hw) newRFC = IXGB_READ_REG(hw, RFC); if ((hw->lastLFC + 250 < newLFC) || (hw->lastRFC + 250 < newRFC)) { - DEBUGOUT - ("BAD LINK! too many LFC/RFC since last check\n"); + pr_debug("BAD LINK! too many LFC/RFC since last check\n"); bad_link_returncode = true; } hw->lastLFC = newLFC; @@ -1002,11 +982,11 @@ ixgb_clear_hw_cntrs(struct ixgb_hw *hw) { volatile u32 temp_reg; - DEBUGFUNC("ixgb_clear_hw_cntrs"); + ENTER(); /* if we are stopped or resetting exit gracefully */ if (hw->adapter_stopped) { - DEBUGOUT("Exiting because the adapter is stopped!!!\n"); + pr_debug("Exiting because the adapter is stopped!!!\n"); return; } @@ -1156,26 +1136,21 @@ static bool mac_addr_valid(u8 *mac_addr) { bool is_valid = true; - DEBUGFUNC("mac_addr_valid"); + ENTER(); /* Make sure it is not a multicast address */ - if (IS_MULTICAST(mac_addr)) { - DEBUGOUT("MAC address is multicast\n"); + if (is_multicast_ether_addr(mac_addr)) { + pr_debug("MAC address is multicast\n"); is_valid = false; } /* Not a broadcast address */ - else if (IS_BROADCAST(mac_addr)) { - DEBUGOUT("MAC address is broadcast\n"); + else if (is_broadcast_ether_addr(mac_addr)) { + pr_debug("MAC address is broadcast\n"); is_valid = false; } /* Reject the zero address */ - else if (mac_addr[0] == 0 && - mac_addr[1] == 0 && - mac_addr[2] == 0 && - mac_addr[3] == 0 && - mac_addr[4] == 0 && - mac_addr[5] == 0) { - DEBUGOUT("MAC address is all zeros\n"); + else if (is_zero_ether_addr(mac_addr)) { + pr_debug("MAC address is all zeros\n"); is_valid = false; } return (is_valid); diff --git a/drivers/net/ixgb/ixgb_hw.h b/drivers/net/ixgb/ixgb_hw.h index af6ca3aab5ad..873d32b89fba 100644 --- a/drivers/net/ixgb/ixgb_hw.h +++ b/drivers/net/ixgb/ixgb_hw.h @@ -636,18 +636,6 @@ struct ixgb_flash_buffer { u8 filler3[0xAAAA]; }; -/* - * This is a little-endian specific check. - */ -#define IS_MULTICAST(Address) \ - (bool)(((u8 *)(Address))[0] & ((u8)0x01)) - -/* - * Check whether an address is broadcast. - */ -#define IS_BROADCAST(Address) \ - ((((u8 *)(Address))[0] == ((u8)0xff)) && (((u8 *)(Address))[1] == ((u8)0xff))) - /* Flow control parameters */ struct ixgb_fc { u32 high_water; /* Flow Control High-water */ diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 912dd1d5772c..3cf7951ac152 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -26,6 +26,8 @@ *******************************************************************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "ixgb.h" char ixgb_driver_name[] = "ixgb"; @@ -146,10 +148,8 @@ MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); static int __init ixgb_init_module(void) { - printk(KERN_INFO "%s - version %s\n", - ixgb_driver_string, ixgb_driver_version); - - printk(KERN_INFO "%s\n", ixgb_copyright); + pr_info("%s - version %s\n", ixgb_driver_string, ixgb_driver_version); + pr_info("%s\n", ixgb_copyright); return pci_register_driver(&ixgb_driver); } @@ -374,8 +374,7 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } else { if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) || (err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))) { - printk(KERN_ERR - "ixgb: No usable DMA configuration, aborting\n"); + pr_err("No usable DMA configuration, aborting\n"); goto err_dma_mask; } pci_using_dac = 0; @@ -1118,15 +1117,14 @@ ixgb_watchdog(unsigned long data) if (adapter->hw.link_up) { if (!netif_carrier_ok(netdev)) { - printk(KERN_INFO "ixgb: %s NIC Link is Up 10 Gbps " - "Full Duplex, Flow Control: %s\n", - netdev->name, - (adapter->hw.fc.type == ixgb_fc_full) ? - "RX/TX" : - ((adapter->hw.fc.type == ixgb_fc_rx_pause) ? - "RX" : - ((adapter->hw.fc.type == ixgb_fc_tx_pause) ? - "TX" : "None"))); + netdev_info(netdev, + "NIC Link is Up 10 Gbps Full Duplex, Flow Control: %s\n", + (adapter->hw.fc.type == ixgb_fc_full) ? + "RX/TX" : + (adapter->hw.fc.type == ixgb_fc_rx_pause) ? + "RX" : + (adapter->hw.fc.type == ixgb_fc_tx_pause) ? + "TX" : "None"); adapter->link_speed = 10000; adapter->link_duplex = FULL_DUPLEX; netif_carrier_on(netdev); @@ -1135,8 +1133,7 @@ ixgb_watchdog(unsigned long data) if (netif_carrier_ok(netdev)) { adapter->link_speed = 0; adapter->link_duplex = 0; - printk(KERN_INFO "ixgb: %s NIC Link is Down\n", - netdev->name); + netdev_info(netdev, "NIC Link is Down\n"); netif_carrier_off(netdev); } } @@ -2322,7 +2319,7 @@ static void ixgb_io_resume(struct pci_dev *pdev) if (netif_running(netdev)) { if (ixgb_up(adapter)) { - printk ("ixgb: can't bring device back up after reset\n"); + pr_err("can't bring device back up after reset\n"); return; } } diff --git a/drivers/net/ixgb/ixgb_osdep.h b/drivers/net/ixgb/ixgb_osdep.h index 371a6be4d965..e361185920ef 100644 --- a/drivers/net/ixgb/ixgb_osdep.h +++ b/drivers/net/ixgb/ixgb_osdep.h @@ -41,20 +41,8 @@ #undef ASSERT #define ASSERT(x) BUG_ON(!(x)) -#define MSGOUT(S, A, B) printk(KERN_DEBUG S "\n", A, B) - -#ifdef DBG -#define DEBUGOUT(S) printk(KERN_DEBUG S "\n") -#define DEBUGOUT1(S, A...) printk(KERN_DEBUG S "\n", A) -#else -#define DEBUGOUT(S) -#define DEBUGOUT1(S, A...) -#endif - -#define DEBUGFUNC(F) DEBUGOUT(F) -#define DEBUGOUT2 DEBUGOUT1 -#define DEBUGOUT3 DEBUGOUT2 -#define DEBUGOUT7 DEBUGOUT3 + +#define ENTER() pr_debug("%s\n", __func__); #define IXGB_WRITE_REG(a, reg, value) ( \ writel((value), ((a)->hw_addr + IXGB_##reg))) diff --git a/drivers/net/ixgb/ixgb_param.c b/drivers/net/ixgb/ixgb_param.c index af35e1ddadd6..88a08f056241 100644 --- a/drivers/net/ixgb/ixgb_param.c +++ b/drivers/net/ixgb/ixgb_param.c @@ -26,6 +26,8 @@ *******************************************************************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "ixgb.h" /* This is the only thing that needs to be changed to adjust the @@ -209,16 +211,16 @@ ixgb_validate_option(unsigned int *value, const struct ixgb_option *opt) case enable_option: switch (*value) { case OPTION_ENABLED: - printk(KERN_INFO "%s Enabled\n", opt->name); + pr_info("%s Enabled\n", opt->name); return 0; case OPTION_DISABLED: - printk(KERN_INFO "%s Disabled\n", opt->name); + pr_info("%s Disabled\n", opt->name); return 0; } break; case range_option: if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { - printk(KERN_INFO "%s set to %i\n", opt->name, *value); + pr_info("%s set to %i\n", opt->name, *value); return 0; } break; @@ -230,7 +232,7 @@ ixgb_validate_option(unsigned int *value, const struct ixgb_option *opt) ent = &opt->arg.l.p[i]; if (*value == ent->i) { if (ent->str[0] != '\0') - printk(KERN_INFO "%s\n", ent->str); + pr_info("%s\n", ent->str); return 0; } } @@ -240,8 +242,7 @@ ixgb_validate_option(unsigned int *value, const struct ixgb_option *opt) BUG(); } - printk(KERN_INFO "Invalid %s specified (%i) %s\n", - opt->name, *value, opt->err); + pr_info("Invalid %s specified (%i) %s\n", opt->name, *value, opt->err); *value = opt->def; return -1; } @@ -261,9 +262,8 @@ ixgb_check_options(struct ixgb_adapter *adapter) { int bd = adapter->bd_number; if (bd >= IXGB_MAX_NIC) { - printk(KERN_NOTICE - "Warning: no configuration for board #%i\n", bd); - printk(KERN_NOTICE "Using defaults for all values\n"); + pr_notice("Warning: no configuration for board #%i\n", bd); + pr_notice("Using defaults for all values\n"); } { /* Transmit Descriptor Count */ @@ -363,8 +363,7 @@ ixgb_check_options(struct ixgb_adapter *adapter) adapter->hw.fc.high_water = opt.def; } if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) ) - printk(KERN_INFO - "Ignoring RxFCHighThresh when no RxFC\n"); + pr_info("Ignoring RxFCHighThresh when no RxFC\n"); } { /* Receive Flow Control Low Threshold */ const struct ixgb_option opt = { @@ -383,8 +382,7 @@ ixgb_check_options(struct ixgb_adapter *adapter) adapter->hw.fc.low_water = opt.def; } if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) ) - printk(KERN_INFO - "Ignoring RxFCLowThresh when no RxFC\n"); + pr_info("Ignoring RxFCLowThresh when no RxFC\n"); } { /* Flow Control Pause Time Request*/ const struct ixgb_option opt = { @@ -404,17 +402,14 @@ ixgb_check_options(struct ixgb_adapter *adapter) adapter->hw.fc.pause_time = opt.def; } if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) ) - printk(KERN_INFO - "Ignoring FCReqTimeout when no RxFC\n"); + pr_info("Ignoring FCReqTimeout when no RxFC\n"); } /* high low and spacing check for rx flow control thresholds */ if (adapter->hw.fc.type & ixgb_fc_tx_pause) { /* high must be greater than low */ if (adapter->hw.fc.high_water < (adapter->hw.fc.low_water + 8)) { /* set defaults */ - printk(KERN_INFO - "RxFCHighThresh must be >= (RxFCLowThresh + 8), " - "Using Defaults\n"); + pr_info("RxFCHighThresh must be >= (RxFCLowThresh + 8), Using Defaults\n"); adapter->hw.fc.high_water = DEFAULT_FCRTH; adapter->hw.fc.low_water = DEFAULT_FCRTL; } diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index f894bb633040..d189ba7e8f15 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -39,6 +39,8 @@ #define IXGBE_82599_MC_TBL_SIZE 128 #define IXGBE_82599_VFT_TBL_SIZE 128 +void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); +void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, ixgbe_link_speed speed, @@ -69,8 +71,14 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) if (hw->phy.multispeed_fiber) { /* Set up dual speed SFP+ support */ mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber; + mac->ops.disable_tx_laser = + &ixgbe_disable_tx_laser_multispeed_fiber; + mac->ops.enable_tx_laser = + &ixgbe_enable_tx_laser_multispeed_fiber; mac->ops.flap_tx_laser = &ixgbe_flap_tx_laser_multispeed_fiber; } else { + mac->ops.disable_tx_laser = NULL; + mac->ops.enable_tx_laser = NULL; mac->ops.flap_tx_laser = NULL; if ((mac->ops.get_media_type(hw) == ixgbe_media_type_backplane) && @@ -415,6 +423,44 @@ s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, return status; } + /** + * ixgbe_disable_tx_laser_multispeed_fiber - Disable Tx laser + * @hw: pointer to hardware structure + * + * The base drivers may require better control over SFP+ module + * PHY states. This includes selectively shutting down the Tx + * laser on the PHY, effectively halting physical link. + **/ +void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) +{ + u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); + + /* Disable tx laser; allow 100us to go dark per spec */ + esdp_reg |= IXGBE_ESDP_SDP3; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); + IXGBE_WRITE_FLUSH(hw); + udelay(100); +} + +/** + * ixgbe_enable_tx_laser_multispeed_fiber - Enable Tx laser + * @hw: pointer to hardware structure + * + * The base drivers may require better control over SFP+ module + * PHY states. This includes selectively turning on the Tx + * laser on the PHY, effectively starting physical link. + **/ +void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) +{ + u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); + + /* Enable tx laser; allow 100ms to light up */ + esdp_reg &= ~IXGBE_ESDP_SDP3; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); + IXGBE_WRITE_FLUSH(hw); + msleep(100); +} + /** * ixgbe_flap_tx_laser_multispeed_fiber - Flap Tx laser * @hw: pointer to hardware structure @@ -429,23 +475,11 @@ s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, **/ void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) { - u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); - hw_dbg(hw, "ixgbe_flap_tx_laser_multispeed_fiber\n"); if (hw->mac.autotry_restart) { - /* Disable tx laser; allow 100us to go dark per spec */ - esdp_reg |= IXGBE_ESDP_SDP3; - IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - IXGBE_WRITE_FLUSH(hw); - udelay(100); - - /* Enable tx laser; allow 100ms to light up */ - esdp_reg &= ~IXGBE_ESDP_SDP3; - IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - IXGBE_WRITE_FLUSH(hw); - msleep(100); - + ixgbe_disable_tx_laser_multispeed_fiber(hw); + ixgbe_enable_tx_laser_multispeed_fiber(hw); hw->mac.autotry_restart = false; } } diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 8f461d5cee77..5f8c6ab7a98a 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -2079,12 +2079,32 @@ static int ixgbe_get_coalesce(struct net_device *netdev, return 0; } +/* + * this function must be called before setting the new value of + * rx_itr_setting + */ +static bool ixgbe_reenable_rsc(struct ixgbe_adapter *adapter, + struct ethtool_coalesce *ec) +{ + /* check the old value and enable RSC if necessary */ + if ((adapter->rx_itr_setting == 0) && + (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) { + adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; + adapter->netdev->features |= NETIF_F_LRO; + DPRINTK(PROBE, INFO, "rx-usecs set to %d, re-enabling RSC\n", + ec->rx_coalesce_usecs); + return true; + } + return false; +} + static int ixgbe_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec) { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_q_vector *q_vector; int i; + bool need_reset = false; /* don't accept tx specific changes if we've got mixed RxTx vectors */ if (adapter->q_vector[0]->txr_count && adapter->q_vector[0]->rxr_count @@ -2095,11 +2115,20 @@ static int ixgbe_set_coalesce(struct net_device *netdev, adapter->tx_ring[0]->work_limit = ec->tx_max_coalesced_frames_irq; if (ec->rx_coalesce_usecs > 1) { + u32 max_int; + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) + max_int = IXGBE_MAX_RSC_INT_RATE; + else + max_int = IXGBE_MAX_INT_RATE; + /* check the limits */ - if ((1000000/ec->rx_coalesce_usecs > IXGBE_MAX_INT_RATE) || + if ((1000000/ec->rx_coalesce_usecs > max_int) || (1000000/ec->rx_coalesce_usecs < IXGBE_MIN_INT_RATE)) return -EINVAL; + /* check the old value and enable RSC if necessary */ + need_reset = ixgbe_reenable_rsc(adapter, ec); + /* store the value in ints/second */ adapter->rx_eitr_param = 1000000/ec->rx_coalesce_usecs; @@ -2108,6 +2137,9 @@ static int ixgbe_set_coalesce(struct net_device *netdev, /* clear the lower bit as its used for dynamic state */ adapter->rx_itr_setting &= ~1; } else if (ec->rx_coalesce_usecs == 1) { + /* check the old value and enable RSC if necessary */ + need_reset = ixgbe_reenable_rsc(adapter, ec); + /* 1 means dynamic mode */ adapter->rx_eitr_param = 20000; adapter->rx_itr_setting = 1; @@ -2116,14 +2148,30 @@ static int ixgbe_set_coalesce(struct net_device *netdev, * any other value means disable eitr, which is best * served by setting the interrupt rate very high */ - if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) - adapter->rx_eitr_param = IXGBE_MAX_RSC_INT_RATE; - else - adapter->rx_eitr_param = IXGBE_MAX_INT_RATE; + adapter->rx_eitr_param = IXGBE_MAX_INT_RATE; adapter->rx_itr_setting = 0; + + /* + * if hardware RSC is enabled, disable it when + * setting low latency mode, to avoid errata, assuming + * that when the user set low latency mode they want + * it at the cost of anything else + */ + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { + adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED; + netdev->features &= ~NETIF_F_LRO; + DPRINTK(PROBE, INFO, + "rx-usecs set to 0, disabling RSC\n"); + + need_reset = true; + } } if (ec->tx_coalesce_usecs > 1) { + /* + * don't have to worry about max_int as above because + * tx vectors don't do hardware RSC (an rx function) + */ /* check the limits */ if ((1000000/ec->tx_coalesce_usecs > IXGBE_MAX_INT_RATE) || (1000000/ec->tx_coalesce_usecs < IXGBE_MIN_INT_RATE)) @@ -2167,6 +2215,18 @@ static int ixgbe_set_coalesce(struct net_device *netdev, ixgbe_write_eitr(q_vector); } + /* + * do reset here at the end to make sure EITR==0 case is handled + * correctly w.r.t stopping tx, and changing TXDCTL.WTHRESH settings + * also locks in RSC enable/disable which requires reset + */ + if (need_reset) { + if (netif_running(netdev)) + ixgbe_reinit_locked(adapter); + else + ixgbe_reset(adapter); + } + return 0; } @@ -2178,10 +2238,26 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) ethtool_op_set_flags(netdev, data); /* if state changes we need to update adapter->flags and reset */ - if ((!!(data & ETH_FLAG_LRO)) != - (!!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) { - adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED; - need_reset = true; + if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) { + /* + * cast both to bool and verify if they are set the same + * but only enable RSC if itr is non-zero, as + * itr=0 and RSC are mutually exclusive + */ + if (((!!(data & ETH_FLAG_LRO)) != + (!!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) && + adapter->rx_itr_setting) { + adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED; + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + need_reset = true; + break; + default: + break; + } + } else if (!adapter->rx_itr_setting) { + netdev->features &= ~ETH_FLAG_LRO; + } } /* diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index a98ff0e76e86..5258b3d6405b 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1190,6 +1190,15 @@ void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector) itr_reg |= (itr_reg << 16); } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { /* + * 82599 can support a value of zero, so allow it for + * max interrupt rate, but there is an errata where it can + * not be zero with RSC + */ + if (itr_reg == 8 && + !(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) + itr_reg = 0; + + /* * set the WDIS bit to not clear the timer bits and cause an * immediate assertion of the interrupt */ @@ -2936,8 +2945,13 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) for (i = 0; i < adapter->num_tx_queues; i++) { j = adapter->tx_ring[i]->reg_idx; txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j)); - /* enable WTHRESH=8 descriptors, to encourage burst writeback */ - txdctl |= (8 << 16); + if (adapter->rx_itr_setting == 0) { + /* cannot set wthresh when itr==0 */ + txdctl &= ~0x007F0000; + } else { + /* enable WTHRESH=8 descriptors, to encourage burst writeback */ + txdctl |= (8 << 16); + } IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl); } @@ -2991,6 +3005,10 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) else ixgbe_configure_msi_and_legacy(adapter); + /* enable the optics */ + if (hw->phy.multispeed_fiber) + hw->mac.ops.enable_tx_laser(hw); + clear_bit(__IXGBE_DOWN, &adapter->state); ixgbe_napi_enable_all(adapter); @@ -3252,6 +3270,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter) /* signal that we are down to the interrupt handler */ set_bit(__IXGBE_DOWN, &adapter->state); + /* power down the optics */ + if (hw->phy.multispeed_fiber) + hw->mac.ops.disable_tx_laser(hw); + /* disable receive for all VFs and wait one second */ if (adapter->num_vfs) { /* ping all the active vfs to let them know we are going down */ @@ -3269,22 +3291,23 @@ void ixgbe_down(struct ixgbe_adapter *adapter) rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN); - netif_tx_disable(netdev); - IXGBE_WRITE_FLUSH(hw); msleep(10); netif_tx_stop_all_queues(netdev); - ixgbe_irq_disable(adapter); - - ixgbe_napi_disable_all(adapter); - clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state); del_timer_sync(&adapter->sfp_timer); del_timer_sync(&adapter->watchdog_timer); cancel_work_sync(&adapter->watchdog_task); + netif_carrier_off(netdev); + netif_tx_disable(netdev); + + ixgbe_irq_disable(adapter); + + ixgbe_napi_disable_all(adapter); + if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) cancel_work_sync(&adapter->fdir_reinit_task); @@ -3302,8 +3325,6 @@ void ixgbe_down(struct ixgbe_adapter *adapter) (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) & ~IXGBE_DMATXCTL_TE)); - netif_carrier_off(netdev); - /* clear n-tuple filters that are cached */ ethtool_ntuple_flush(netdev); @@ -6262,6 +6283,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, goto err_eeprom; } + /* power down the optics */ + if (hw->phy.multispeed_fiber) + hw->mac.ops.disable_tx_laser(hw); + init_timer(&adapter->watchdog_timer); adapter->watchdog_timer.function = &ixgbe_watchdog; adapter->watchdog_timer.data = (unsigned long)adapter; @@ -6409,16 +6434,6 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) del_timer_sync(&adapter->sfp_timer); cancel_work_sync(&adapter->watchdog_task); cancel_work_sync(&adapter->sfp_task); - if (adapter->hw.phy.multispeed_fiber) { - struct ixgbe_hw *hw = &adapter->hw; - /* - * Restart clause 37 autoneg, disable and re-enable - * the tx laser, to clear & alert the link partner - * that it needs to restart autotry - */ - hw->mac.autotry_restart = true; - hw->mac.ops.flap_tx_laser(hw); - } cancel_work_sync(&adapter->multispeed_fiber_task); cancel_work_sync(&adapter->sfp_config_module_task); if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index aed4ed665648..a0f9084c81cd 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2398,6 +2398,8 @@ struct ixgbe_mac_operations { s32 (*enable_rx_dma)(struct ixgbe_hw *, u32); /* Link */ + void (*disable_tx_laser)(struct ixgbe_hw *); + void (*enable_tx_laser)(struct ixgbe_hw *); void (*flap_tx_laser)(struct ixgbe_hw *); s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool); s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool); diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c index 4dcd61f81ec2..b8ed1ee37ac1 100644 --- a/drivers/net/ks8851.c +++ b/drivers/net/ks8851.c @@ -717,12 +717,14 @@ static void ks8851_tx_work(struct work_struct *work) txb = skb_dequeue(&ks->txq); last = skb_queue_empty(&ks->txq); - ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA); - ks8851_wrpkt(ks, txb, last); - ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); - ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE); + if (txb != NULL) { + ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA); + ks8851_wrpkt(ks, txb, last); + ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); + ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE); - ks8851_done_tx(ks, txb); + ks8851_done_tx(ks, txb); + } } mutex_unlock(&ks->lock); diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 85d6420f8404..d97e1fd234ba 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -181,7 +181,7 @@ static int macvtap_forward(struct net_device *dev, struct sk_buff *skb) return -ENOLINK; skb_queue_tail(&q->sk.sk_receive_queue, skb); - wake_up_interruptible_poll(q->sk.sk_sleep, POLLIN | POLLRDNORM | POLLRDBAND); + wake_up_interruptible_poll(sk_sleep(&q->sk), POLLIN | POLLRDNORM | POLLRDBAND); return 0; } @@ -562,7 +562,7 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb, struct sk_buff *skb; ssize_t ret = 0; - add_wait_queue(q->sk.sk_sleep, &wait); + add_wait_queue(sk_sleep(&q->sk), &wait); while (len) { current->state = TASK_INTERRUPTIBLE; @@ -587,7 +587,7 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb, } current->state = TASK_RUNNING; - remove_wait_queue(q->sk.sk_sleep, &wait); + remove_wait_queue(sk_sleep(&q->sk), &wait); return ret; } diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 3d1d3a7b7ed3..757f87bb1db3 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -781,8 +781,13 @@ static netdev_tx_t el3_start_xmit(struct sk_buff *skb, inw(ioaddr + EL3_STATUS)); spin_lock_irqsave(&lp->window_lock, flags); + + dev->stats.tx_bytes += skb->len; + + /* Put out the doubleword header... */ outw(skb->len, ioaddr + TX_FIFO); outw(0, ioaddr + TX_FIFO); + /* ... and the packet rounded to a doubleword. */ outsl(ioaddr + TX_FIFO, skb->data, (skb->len+3)>>2); dev->trans_start = jiffies; @@ -1021,8 +1026,6 @@ static void update_stats(struct net_device *dev) /* BadSSD */ inb(ioaddr + 12); up = inb(ioaddr + 13); - dev->stats.tx_bytes += tx + ((up & 0xf0) << 12); - EL3WINDOW(1); } diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index cdd11ba100ea..c059c8db42e3 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -258,7 +258,7 @@ static inline struct pppox_sock *get_item_by_addr(struct net *net, dev = dev_get_by_name_rcu(net, sp->sa_addr.pppoe.dev); if (dev) { ifindex = dev->ifindex; - pn = net_generic(net, pppoe_net_id); + pn = pppoe_pernet(net); pppox_sock = get_item(pn, sp->sa_addr.pppoe.sid, sp->sa_addr.pppoe.remote, ifindex); } diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 340da3915b96..217e709bda3e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -2775,6 +2775,7 @@ static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev, { iounmap(ioaddr); pci_release_regions(pdev); + pci_clear_mwi(pdev); pci_disable_device(pdev); free_netdev(dev); } @@ -2841,8 +2842,13 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) spin_lock_irq(&tp->lock); RTL_W8(Cfg9346, Cfg9346_Unlock); + RTL_W32(MAC4, high); + RTL_R32(MAC4); + RTL_W32(MAC0, low); + RTL_R32(MAC0); + RTL_W8(Cfg9346, Cfg9346_Lock); spin_unlock_irq(&tp->lock); @@ -3030,9 +3036,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_free_dev_1; } - rc = pci_set_mwi(pdev); - if (rc < 0) - goto err_out_disable_2; + if (pci_set_mwi(pdev) < 0) + netif_info(tp, probe, dev, "Mem-Wr-Inval unavailable\n"); /* make sure PCI base addr 1 is MMIO */ if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) { @@ -3040,7 +3045,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) "region #%d not an MMIO resource, aborting\n", region); rc = -ENODEV; - goto err_out_mwi_3; + goto err_out_mwi_2; } /* check for weird/broken PCI region reporting */ @@ -3048,13 +3053,13 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) netif_err(tp, probe, dev, "Invalid PCI region size(s), aborting\n"); rc = -ENODEV; - goto err_out_mwi_3; + goto err_out_mwi_2; } rc = pci_request_regions(pdev, MODULENAME); if (rc < 0) { netif_err(tp, probe, dev, "could not request regions\n"); - goto err_out_mwi_3; + goto err_out_mwi_2; } tp->cp_cmd = PCIMulRW | RxChkSum; @@ -3067,7 +3072,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (rc < 0) { netif_err(tp, probe, dev, "DMA configuration failed\n"); - goto err_out_free_res_4; + goto err_out_free_res_3; } } @@ -3076,7 +3081,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (!ioaddr) { netif_err(tp, probe, dev, "cannot remap MMIO, aborting\n"); rc = -EIO; - goto err_out_free_res_4; + goto err_out_free_res_3; } tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); @@ -3118,7 +3123,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (i == ARRAY_SIZE(rtl_chip_info)) { dev_err(&pdev->dev, "driver bug, MAC version not found in rtl_chip_info\n"); - goto err_out_msi_5; + goto err_out_msi_4; } tp->chipset = i; @@ -3183,7 +3188,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) rc = register_netdev(dev); if (rc < 0) - goto err_out_msi_5; + goto err_out_msi_4; pci_set_drvdata(pdev, dev); @@ -3212,14 +3217,13 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) out: return rc; -err_out_msi_5: +err_out_msi_4: rtl_disable_msi(pdev, tp); iounmap(ioaddr); -err_out_free_res_4: +err_out_free_res_3: pci_release_regions(pdev); -err_out_mwi_3: +err_out_mwi_2: pci_clear_mwi(pdev); -err_out_disable_2: pci_disable_device(pdev); err_out_free_dev_1: free_netdev(dev); diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 7724d7e4ebd6..573054ae7b58 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8700,6 +8700,7 @@ static int tg3_test_msi(struct tg3 *tp) pci_disable_msi(tp->pdev); tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; + tp->napi[0].irq_vec = tp->pdev->irq; err = tg3_request_irq(tp, 0); if (err) diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index ba56ce4382d9..63be4caec70e 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -385,4 +385,16 @@ config USB_CDC_PHONET cellular modem, as found on most Nokia handsets with the "PC suite" USB profile. +config USB_IPHETH + tristate "Apple iPhone USB Ethernet driver" + default n + ---help--- + Module used to share Internet connection (tethering) from your + iPhone (Original, 3G and 3GS) to your system. + Note that you need userspace libraries and programs that are needed + to pair your device with your system and that understand the iPhone + protocol. + + For more information: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver + endmenu diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index 82ea62955b56..edb09c0ddf8e 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -23,4 +23,5 @@ obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o obj-$(CONFIG_USB_USBNET) += usbnet.o obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o +obj-$(CONFIG_USB_IPHETH) += ipheth.o diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c new file mode 100644 index 000000000000..fd1033130a81 --- /dev/null +++ b/drivers/net/usb/ipheth.c @@ -0,0 +1,568 @@ +/* + * ipheth.c - Apple iPhone USB Ethernet driver + * + * Copyright (c) 2009 Diego Giagio <diego@giagio.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of GIAGIO.COM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Alternatively, provided that this notice is retained in full, this + * software may be distributed under the terms of the GNU General + * Public License ("GPL") version 2, in which case the provisions of the + * GPL apply INSTEAD OF those given above. + * + * The provided data structures and external interfaces from this code + * are not restricted to be used by modules with a GPL compatible license. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * + * Attention: iPhone device must be paired, otherwise it won't respond to our + * driver. For more info: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver + * + */ + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/ethtool.h> +#include <linux/usb.h> +#include <linux/workqueue.h> + +#define USB_VENDOR_APPLE 0x05ac +#define USB_PRODUCT_IPHONE 0x1290 +#define USB_PRODUCT_IPHONE_3G 0x1292 +#define USB_PRODUCT_IPHONE_3GS 0x1294 + +#define IPHETH_USBINTF_CLASS 255 +#define IPHETH_USBINTF_SUBCLASS 253 +#define IPHETH_USBINTF_PROTO 1 + +#define IPHETH_BUF_SIZE 1516 +#define IPHETH_TX_TIMEOUT (5 * HZ) + +#define IPHETH_INTFNUM 2 +#define IPHETH_ALT_INTFNUM 1 + +#define IPHETH_CTRL_ENDP 0x00 +#define IPHETH_CTRL_BUF_SIZE 0x40 +#define IPHETH_CTRL_TIMEOUT (5 * HZ) + +#define IPHETH_CMD_GET_MACADDR 0x00 +#define IPHETH_CMD_CARRIER_CHECK 0x45 + +#define IPHETH_CARRIER_CHECK_TIMEOUT round_jiffies_relative(1 * HZ) +#define IPHETH_CARRIER_ON 0x04 + +static struct usb_device_id ipheth_table[] = { + { USB_DEVICE_AND_INTERFACE_INFO( + USB_VENDOR_APPLE, USB_PRODUCT_IPHONE, + IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, + IPHETH_USBINTF_PROTO) }, + { USB_DEVICE_AND_INTERFACE_INFO( + USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3G, + IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, + IPHETH_USBINTF_PROTO) }, + { USB_DEVICE_AND_INTERFACE_INFO( + USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3GS, + IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, + IPHETH_USBINTF_PROTO) }, + { } +}; +MODULE_DEVICE_TABLE(usb, ipheth_table); + +struct ipheth_device { + struct usb_device *udev; + struct usb_interface *intf; + struct net_device *net; + struct sk_buff *tx_skb; + struct urb *tx_urb; + struct urb *rx_urb; + unsigned char *tx_buf; + unsigned char *rx_buf; + unsigned char *ctrl_buf; + u8 bulk_in; + u8 bulk_out; + struct delayed_work carrier_work; +}; + +static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags); + +static int ipheth_alloc_urbs(struct ipheth_device *iphone) +{ + struct urb *tx_urb = NULL; + struct urb *rx_urb = NULL; + u8 *tx_buf = NULL; + u8 *rx_buf = NULL; + + tx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (tx_urb == NULL) + goto error; + + rx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (rx_urb == NULL) + goto error; + + tx_buf = usb_buffer_alloc(iphone->udev, + IPHETH_BUF_SIZE, + GFP_KERNEL, + &tx_urb->transfer_dma); + if (tx_buf == NULL) + goto error; + + rx_buf = usb_buffer_alloc(iphone->udev, + IPHETH_BUF_SIZE, + GFP_KERNEL, + &rx_urb->transfer_dma); + if (rx_buf == NULL) + goto error; + + + iphone->tx_urb = tx_urb; + iphone->rx_urb = rx_urb; + iphone->tx_buf = tx_buf; + iphone->rx_buf = rx_buf; + return 0; + +error: + usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, rx_buf, + rx_urb->transfer_dma); + usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, tx_buf, + tx_urb->transfer_dma); + usb_free_urb(rx_urb); + usb_free_urb(tx_urb); + return -ENOMEM; +} + +static void ipheth_free_urbs(struct ipheth_device *iphone) +{ + usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, iphone->rx_buf, + iphone->rx_urb->transfer_dma); + usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf, + iphone->tx_urb->transfer_dma); + usb_free_urb(iphone->rx_urb); + usb_free_urb(iphone->tx_urb); +} + +static void ipheth_kill_urbs(struct ipheth_device *dev) +{ + usb_kill_urb(dev->tx_urb); + usb_kill_urb(dev->rx_urb); +} + +static void ipheth_rcvbulk_callback(struct urb *urb) +{ + struct ipheth_device *dev; + struct sk_buff *skb; + int status; + char *buf; + int len; + + dev = urb->context; + if (dev == NULL) + return; + + status = urb->status; + switch (status) { + case -ENOENT: + case -ECONNRESET: + case -ESHUTDOWN: + return; + case 0: + break; + default: + err("%s: urb status: %d", __func__, urb->status); + return; + } + + len = urb->actual_length; + buf = urb->transfer_buffer; + + skb = dev_alloc_skb(NET_IP_ALIGN + len); + if (!skb) { + err("%s: dev_alloc_skb: -ENOMEM", __func__); + dev->net->stats.rx_dropped++; + return; + } + + skb_reserve(skb, NET_IP_ALIGN); + memcpy(skb_put(skb, len), buf + NET_IP_ALIGN, len - NET_IP_ALIGN); + skb->dev = dev->net; + skb->protocol = eth_type_trans(skb, dev->net); + + dev->net->stats.rx_packets++; + dev->net->stats.rx_bytes += len; + + netif_rx(skb); + ipheth_rx_submit(dev, GFP_ATOMIC); +} + +static void ipheth_sndbulk_callback(struct urb *urb) +{ + struct ipheth_device *dev; + + dev = urb->context; + if (dev == NULL) + return; + + if (urb->status != 0 && + urb->status != -ENOENT && + urb->status != -ECONNRESET && + urb->status != -ESHUTDOWN) + err("%s: urb status: %d", __func__, urb->status); + + dev_kfree_skb_irq(dev->tx_skb); + netif_wake_queue(dev->net); +} + +static int ipheth_carrier_set(struct ipheth_device *dev) +{ + struct usb_device *udev = dev->udev; + int retval; + + retval = usb_control_msg(udev, + usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP), + IPHETH_CMD_CARRIER_CHECK, /* request */ + 0xc0, /* request type */ + 0x00, /* value */ + 0x02, /* index */ + dev->ctrl_buf, IPHETH_CTRL_BUF_SIZE, + IPHETH_CTRL_TIMEOUT); + if (retval < 0) { + err("%s: usb_control_msg: %d", __func__, retval); + return retval; + } + + if (dev->ctrl_buf[0] == IPHETH_CARRIER_ON) + netif_carrier_on(dev->net); + else + netif_carrier_off(dev->net); + + return 0; +} + +static void ipheth_carrier_check_work(struct work_struct *work) +{ + struct ipheth_device *dev = container_of(work, struct ipheth_device, + carrier_work.work); + + ipheth_carrier_set(dev); + schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT); +} + +static int ipheth_get_macaddr(struct ipheth_device *dev) +{ + struct usb_device *udev = dev->udev; + struct net_device *net = dev->net; + int retval; + + retval = usb_control_msg(udev, + usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP), + IPHETH_CMD_GET_MACADDR, /* request */ + 0xc0, /* request type */ + 0x00, /* value */ + 0x02, /* index */ + dev->ctrl_buf, + IPHETH_CTRL_BUF_SIZE, + IPHETH_CTRL_TIMEOUT); + if (retval < 0) { + err("%s: usb_control_msg: %d", __func__, retval); + } else if (retval < ETH_ALEN) { + err("%s: usb_control_msg: short packet: %d bytes", + __func__, retval); + retval = -EINVAL; + } else { + memcpy(net->dev_addr, dev->ctrl_buf, ETH_ALEN); + retval = 0; + } + + return retval; +} + +static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags) +{ + struct usb_device *udev = dev->udev; + int retval; + + usb_fill_bulk_urb(dev->rx_urb, udev, + usb_rcvbulkpipe(udev, dev->bulk_in), + dev->rx_buf, IPHETH_BUF_SIZE, + ipheth_rcvbulk_callback, + dev); + dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + retval = usb_submit_urb(dev->rx_urb, mem_flags); + if (retval) + err("%s: usb_submit_urb: %d", __func__, retval); + return retval; +} + +static int ipheth_open(struct net_device *net) +{ + struct ipheth_device *dev = netdev_priv(net); + struct usb_device *udev = dev->udev; + int retval = 0; + + usb_set_interface(udev, IPHETH_INTFNUM, IPHETH_ALT_INTFNUM); + + retval = ipheth_carrier_set(dev); + if (retval) + return retval; + + retval = ipheth_rx_submit(dev, GFP_KERNEL); + if (retval) + return retval; + + schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT); + netif_start_queue(net); + return retval; +} + +static int ipheth_close(struct net_device *net) +{ + struct ipheth_device *dev = netdev_priv(net); + + cancel_delayed_work_sync(&dev->carrier_work); + netif_stop_queue(net); + return 0; +} + +static int ipheth_tx(struct sk_buff *skb, struct net_device *net) +{ + struct ipheth_device *dev = netdev_priv(net); + struct usb_device *udev = dev->udev; + int retval; + + /* Paranoid */ + if (skb->len > IPHETH_BUF_SIZE) { + WARN(1, "%s: skb too large: %d bytes", __func__, skb->len); + dev->net->stats.tx_dropped++; + dev_kfree_skb_irq(skb); + return NETDEV_TX_OK; + } + + memcpy(dev->tx_buf, skb->data, skb->len); + if (skb->len < IPHETH_BUF_SIZE) + memset(dev->tx_buf + skb->len, 0, IPHETH_BUF_SIZE - skb->len); + + usb_fill_bulk_urb(dev->tx_urb, udev, + usb_sndbulkpipe(udev, dev->bulk_out), + dev->tx_buf, IPHETH_BUF_SIZE, + ipheth_sndbulk_callback, + dev); + dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + retval = usb_submit_urb(dev->tx_urb, GFP_ATOMIC); + if (retval) { + err("%s: usb_submit_urb: %d", __func__, retval); + dev->net->stats.tx_errors++; + dev_kfree_skb_irq(skb); + } else { + dev->tx_skb = skb; + + dev->net->stats.tx_packets++; + dev->net->stats.tx_bytes += skb->len; + netif_stop_queue(net); + } + + return NETDEV_TX_OK; +} + +static void ipheth_tx_timeout(struct net_device *net) +{ + struct ipheth_device *dev = netdev_priv(net); + + err("%s: TX timeout", __func__); + dev->net->stats.tx_errors++; + usb_unlink_urb(dev->tx_urb); +} + +static struct net_device_stats *ipheth_stats(struct net_device *net) +{ + struct ipheth_device *dev = netdev_priv(net); + return &dev->net->stats; +} + +static u32 ipheth_ethtool_op_get_link(struct net_device *net) +{ + struct ipheth_device *dev = netdev_priv(net); + return netif_carrier_ok(dev->net); +} + +static struct ethtool_ops ops = { + .get_link = ipheth_ethtool_op_get_link +}; + +static const struct net_device_ops ipheth_netdev_ops = { + .ndo_open = &ipheth_open, + .ndo_stop = &ipheth_close, + .ndo_start_xmit = &ipheth_tx, + .ndo_tx_timeout = &ipheth_tx_timeout, + .ndo_get_stats = &ipheth_stats, +}; + +static struct device_type ipheth_type = { + .name = "wwan", +}; + +static int ipheth_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(intf); + struct usb_host_interface *hintf; + struct usb_endpoint_descriptor *endp; + struct ipheth_device *dev; + struct net_device *netdev; + int i; + int retval; + + netdev = alloc_etherdev(sizeof(struct ipheth_device)); + if (!netdev) + return -ENOMEM; + + netdev->netdev_ops = &ipheth_netdev_ops; + netdev->watchdog_timeo = IPHETH_TX_TIMEOUT; + strcpy(netdev->name, "wwan%d"); + + dev = netdev_priv(netdev); + dev->udev = udev; + dev->net = netdev; + dev->intf = intf; + + /* Set up endpoints */ + hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM); + if (hintf == NULL) { + retval = -ENODEV; + err("Unable to find alternate settings interface"); + goto err_endpoints; + } + + for (i = 0; i < hintf->desc.bNumEndpoints; i++) { + endp = &hintf->endpoint[i].desc; + if (usb_endpoint_is_bulk_in(endp)) + dev->bulk_in = endp->bEndpointAddress; + else if (usb_endpoint_is_bulk_out(endp)) + dev->bulk_out = endp->bEndpointAddress; + } + if (!(dev->bulk_in && dev->bulk_out)) { + retval = -ENODEV; + err("Unable to find endpoints"); + goto err_endpoints; + } + + dev->ctrl_buf = kmalloc(IPHETH_CTRL_BUF_SIZE, GFP_KERNEL); + if (dev->ctrl_buf == NULL) { + retval = -ENOMEM; + goto err_alloc_ctrl_buf; + } + + retval = ipheth_get_macaddr(dev); + if (retval) + goto err_get_macaddr; + + INIT_DELAYED_WORK(&dev->carrier_work, ipheth_carrier_check_work); + + retval = ipheth_alloc_urbs(dev); + if (retval) { + err("error allocating urbs: %d", retval); + goto err_alloc_urbs; + } + + usb_set_intfdata(intf, dev); + + SET_NETDEV_DEV(netdev, &intf->dev); + SET_ETHTOOL_OPS(netdev, &ops); + SET_NETDEV_DEVTYPE(netdev, &ipheth_type); + + retval = register_netdev(netdev); + if (retval) { + err("error registering netdev: %d", retval); + retval = -EIO; + goto err_register_netdev; + } + + dev_info(&intf->dev, "Apple iPhone USB Ethernet device attached\n"); + return 0; + +err_register_netdev: + ipheth_free_urbs(dev); +err_alloc_urbs: +err_get_macaddr: +err_alloc_ctrl_buf: + kfree(dev->ctrl_buf); +err_endpoints: + free_netdev(netdev); + return retval; +} + +static void ipheth_disconnect(struct usb_interface *intf) +{ + struct ipheth_device *dev; + + dev = usb_get_intfdata(intf); + if (dev != NULL) { + unregister_netdev(dev->net); + ipheth_kill_urbs(dev); + ipheth_free_urbs(dev); + kfree(dev->ctrl_buf); + free_netdev(dev->net); + } + usb_set_intfdata(intf, NULL); + dev_info(&intf->dev, "Apple iPhone USB Ethernet now disconnected\n"); +} + +static struct usb_driver ipheth_driver = { + .name = "ipheth", + .probe = ipheth_probe, + .disconnect = ipheth_disconnect, + .id_table = ipheth_table, +}; + +static int __init ipheth_init(void) +{ + int retval; + + retval = usb_register(&ipheth_driver); + if (retval) { + err("usb_register failed: %d", retval); + return retval; + } + return 0; +} + +static void __exit ipheth_exit(void) +{ + usb_deregister(&ipheth_driver); +} + +module_init(ipheth_init); +module_exit(ipheth_exit); + +MODULE_AUTHOR("Diego Giagio <diego@giagio.com>"); +MODULE_DESCRIPTION("Apple iPhone USB Ethernet driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index c8f302991b66..c4c3d68be19a 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -442,7 +442,10 @@ #define PCI_EXP_LNKCTL_LABIE 0x0800 /* Lnk Autonomous Bandwidth Interrupt Enable */ #define PCI_EXP_LNKSTA 18 /* Link Status */ #define PCI_EXP_LNKSTA_CLS 0x000f /* Current Link Speed */ +#define PCI_EXP_LNKSTA_CLS_2_5GB 0x01 /* Current Link Speed 2.5GT/s */ +#define PCI_EXP_LNKSTA_CLS_5_0GB 0x02 /* Current Link Speed 5.0GT/s */ #define PCI_EXP_LNKSTA_NLW 0x03f0 /* Nogotiated Link Width */ +#define PCI_EXP_LNKSTA_NLW_SHIFT 4 /* start of NLW mask in link status */ #define PCI_EXP_LNKSTA_LT 0x0800 /* Link Training */ #define PCI_EXP_LNKSTA_SLC 0x1000 /* Slot Clock Configuration */ #define PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */ diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index b487bc1b99ab..c1d42957b86b 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -248,7 +248,7 @@ static inline void inet_rps_reset_flow(const struct sock *sk) #endif } -static inline void inet_rps_save_rxhash(const struct sock *sk, u32 rxhash) +static inline void inet_rps_save_rxhash(struct sock *sk, u32 rxhash) { #ifdef CONFIG_RPS if (unlikely(inet_sk(sk)->rxhash != rxhash)) { diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index 79f67eae8a7e..a066fdd50da6 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h @@ -224,7 +224,9 @@ static inline struct net *twsk_net(const struct inet_timewait_sock *twsk) { #ifdef CONFIG_NET_NS - return rcu_dereference(twsk->tw_net); + return rcu_dereference_raw(twsk->tw_net); /* protected by locking, */ + /* reference counting, */ + /* initialization, or RCU. */ #else return &init_net; #endif diff --git a/include/net/sock.h b/include/net/sock.h index 86a8ca177a29..4081db86a352 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1236,8 +1236,11 @@ __sk_dst_set(struct sock *sk, struct dst_entry *dst) struct dst_entry *old_dst; sk_tx_queue_clear(sk); - old_dst = rcu_dereference_check(sk->sk_dst_cache, - lockdep_is_held(&sk->sk_dst_lock)); + /* + * This can be called while sk is owned by the caller only, + * with no state that can be checked in a rcu_dereference_check() cond + */ + old_dst = rcu_dereference_raw(sk->sk_dst_cache); rcu_assign_pointer(sk->sk_dst_cache, dst); dst_release(old_dst); } diff --git a/include/net/tcp.h b/include/net/tcp.h index 3f87fd87bc9c..fb5c66b2ab81 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1033,6 +1033,14 @@ static inline int keepalive_probes(const struct tcp_sock *tp) return tp->keepalive_probes ? : sysctl_tcp_keepalive_probes; } +static inline u32 keepalive_time_elapsed(const struct tcp_sock *tp) +{ + const struct inet_connection_sock *icsk = &tp->inet_conn; + + return min_t(u32, tcp_time_stamp - icsk->icsk_ack.lrcvtime, + tcp_time_stamp - tp->rcv_tstamp); +} + static inline int tcp_fin_time(const struct sock *sk) { int fin_timeout = tcp_sk(sk)->linger2 ? : sysctl_tcp_fin_timeout; diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 5b8a6e73b02f..82599405dc15 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -36,7 +36,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) skb_reset_mac_header(skb); skb_pull(skb, ETH_HLEN); - if (dest[0] & 1) { + if (is_multicast_ether_addr(dest)) { if (br_multicast_rcv(br, NULL, skb)) goto out; diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 38d1fbde5fb8..fcba313f1894 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -28,6 +28,7 @@ #include <net/ipv6.h> #include <net/mld.h> #include <net/addrconf.h> +#include <net/ip6_checksum.h> #endif #include "br_private.h" @@ -1041,21 +1042,21 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br, static void br_multicast_add_router(struct net_bridge *br, struct net_bridge_port *port) { - struct hlist_node *p; - struct hlist_node **h; - - for (h = &br->router_list.first; - (p = *h) && - (unsigned long)container_of(p, struct net_bridge_port, rlist) > - (unsigned long)port; - h = &p->next) - ; - - port->rlist.pprev = h; - port->rlist.next = p; - rcu_assign_pointer(*h, &port->rlist); - if (p) - p->pprev = &port->rlist.next; + struct net_bridge_port *p; + struct hlist_node *n, *last = NULL; + + hlist_for_each_entry(p, n, &br->router_list, rlist) { + if ((unsigned long) port >= (unsigned long) p) { + hlist_add_before_rcu(n, &port->rlist); + return; + } + last = n; + } + + if (last) + hlist_add_after_rcu(last, &port->rlist); + else + hlist_add_head_rcu(&port->rlist, &br->router_list); } static void br_multicast_mark_router(struct net_bridge *br, @@ -1340,9 +1341,6 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, unsigned offset; int err; - BR_INPUT_SKB_CB(skb)->igmp = 0; - BR_INPUT_SKB_CB(skb)->mrouters_only = 0; - /* We treat OOM as packet loss for now. */ if (!pskb_may_pull(skb, sizeof(*iph))) return -EINVAL; @@ -1440,9 +1438,6 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, unsigned offset; int err; - BR_INPUT_SKB_CB(skb)->igmp = 0; - BR_INPUT_SKB_CB(skb)->mrouters_only = 0; - if (!pskb_may_pull(skb, sizeof(*ip6h))) return -EINVAL; @@ -1550,6 +1545,9 @@ out: int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port, struct sk_buff *skb) { + BR_INPUT_SKB_CB(skb)->igmp = 0; + BR_INPUT_SKB_CB(skb)->mrouters_only = 0; + if (br->multicast_disabled) return 0; diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 90317e7d10b4..d455375789fb 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -169,7 +169,7 @@ static int caif_sktrecv_cb(struct cflayer *layr, struct cfpkt *pkt) /* Signal reader that data is available. */ - wake_up_interruptible(cf_sk->sk.sk_sleep); + wake_up_interruptible(sk_sleep(&cf_sk->sk)); return 0; } @@ -203,7 +203,7 @@ static void caif_sktflowctrl_cb(struct cflayer *layr, dbfs_atomic_inc(&cnt.num_tx_flow_on_ind); /* Signal reader that data is available. */ SET_TX_FLOW_ON(cf_sk); - wake_up_interruptible(cf_sk->sk.sk_sleep); + wake_up_interruptible(sk_sleep(&cf_sk->sk)); break; case CAIF_CTRLCMD_FLOW_OFF_IND: @@ -217,7 +217,7 @@ static void caif_sktflowctrl_cb(struct cflayer *layr, caif_assert(STATE_IS_OPEN(cf_sk)); SET_PENDING_OFF(cf_sk); SET_TX_FLOW_ON(cf_sk); - wake_up_interruptible(cf_sk->sk.sk_sleep); + wake_up_interruptible(sk_sleep(&cf_sk->sk)); break; case CAIF_CTRLCMD_DEINIT_RSP: @@ -225,8 +225,8 @@ static void caif_sktflowctrl_cb(struct cflayer *layr, caif_assert(!STATE_IS_OPEN(cf_sk)); SET_PENDING_OFF(cf_sk); if (!STATE_IS_PENDING_DESTROY(cf_sk)) { - if (cf_sk->sk.sk_sleep != NULL) - wake_up_interruptible(cf_sk->sk.sk_sleep); + if (sk_sleep(&cf_sk->sk) != NULL) + wake_up_interruptible(sk_sleep(&cf_sk->sk)); } dbfs_atomic_inc(&cnt.num_deinit); sock_put(&cf_sk->sk); @@ -238,7 +238,7 @@ static void caif_sktflowctrl_cb(struct cflayer *layr, SET_STATE_CLOSED(cf_sk); SET_PENDING_OFF(cf_sk); SET_TX_FLOW_OFF(cf_sk); - wake_up_interruptible(cf_sk->sk.sk_sleep); + wake_up_interruptible(sk_sleep(&cf_sk->sk)); break; case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND: @@ -247,7 +247,7 @@ static void caif_sktflowctrl_cb(struct cflayer *layr, /* Use sk_shutdown to indicate remote shutdown indication */ cf_sk->sk.sk_shutdown |= RCV_SHUTDOWN; cf_sk->file_mode = 0; - wake_up_interruptible(cf_sk->sk.sk_sleep); + wake_up_interruptible(sk_sleep(&cf_sk->sk)); break; default: @@ -325,7 +325,7 @@ static int caif_recvmsg(struct kiocb *iocb, struct socket *sock, release_sock(&cf_sk->sk); result = - wait_event_interruptible(*cf_sk->sk.sk_sleep, + wait_event_interruptible(*sk_sleep(&cf_sk->sk), !STATE_IS_PENDING(cf_sk)); lock_sock(&(cf_sk->sk)); @@ -365,7 +365,7 @@ static int caif_recvmsg(struct kiocb *iocb, struct socket *sock, release_sock(&cf_sk->sk); /* Block reader until data arrives or socket is closed. */ - if (wait_event_interruptible(*cf_sk->sk.sk_sleep, + if (wait_event_interruptible(*sk_sleep(&cf_sk->sk), cfpkt_qpeek(cf_sk->pktq) || STATE_IS_REMOTE_SHUTDOWN(cf_sk) || !STATE_IS_OPEN(cf_sk)) == @@ -537,7 +537,7 @@ static int caif_sendmsg(struct kiocb *kiocb, struct socket *sock, * for its conclusion. */ result = - wait_event_interruptible(*cf_sk->sk.sk_sleep, + wait_event_interruptible(*sk_sleep(&cf_sk->sk), !STATE_IS_PENDING(cf_sk)); /* I want to be alone on cf_sk (except status and queue) */ lock_sock(&(cf_sk->sk)); @@ -573,7 +573,7 @@ static int caif_sendmsg(struct kiocb *kiocb, struct socket *sock, release_sock(&cf_sk->sk); /* Wait until flow is on or socket is closed */ - if (wait_event_interruptible(*cf_sk->sk.sk_sleep, + if (wait_event_interruptible(*sk_sleep(&cf_sk->sk), TX_FLOW_IS_ON(cf_sk) || !STATE_IS_OPEN(cf_sk) || STATE_IS_REMOTE_SHUTDOWN(cf_sk) @@ -650,7 +650,7 @@ static int caif_sendmsg(struct kiocb *kiocb, struct socket *sock, release_sock(&cf_sk->sk); /* Wait until flow is on or socket is closed */ - if (wait_event_interruptible(*cf_sk->sk.sk_sleep, + if (wait_event_interruptible(*sk_sleep(&cf_sk->sk), TX_FLOW_IS_ON(cf_sk) || !STATE_IS_OPEN(cf_sk) || STATE_IS_REMOTE_SHUTDOWN(cf_sk) @@ -898,7 +898,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uservaddr, * for its conclusion. */ result = - wait_event_interruptible(*cf_sk->sk.sk_sleep, + wait_event_interruptible(*sk_sleep(&cf_sk->sk), !STATE_IS_PENDING(cf_sk)); lock_sock(&(cf_sk->sk)); @@ -965,7 +965,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uservaddr, release_sock(&cf_sk->sk); result = - wait_event_interruptible(*cf_sk->sk.sk_sleep, + wait_event_interruptible(*sk_sleep(&cf_sk->sk), !STATE_IS_PENDING(cf_sk)); lock_sock(&(cf_sk->sk)); @@ -1107,7 +1107,7 @@ static int caif_release(struct socket *sock) * CAIF stack. */ if (!(sock->file->f_flags & O_NONBLOCK)) { - res = wait_event_interruptible(*cf_sk->sk.sk_sleep, + res = wait_event_interruptible(*sk_sleep(&cf_sk->sk), !STATE_IS_PENDING(cf_sk)); if (res == -ERESTARTSYS) { diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index bd8c4712ea24..69a20bfc527c 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -469,10 +469,10 @@ EXPORT_SYMBOL_GPL(register_pernet_subsys); * addition run the exit method for all existing network * namespaces. */ -void unregister_pernet_subsys(struct pernet_operations *module) +void unregister_pernet_subsys(struct pernet_operations *ops) { mutex_lock(&net_mutex); - unregister_pernet_operations(module); + unregister_pernet_operations(ops); mutex_unlock(&net_mutex); } EXPORT_SYMBOL_GPL(unregister_pernet_subsys); diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index fd781b62fa7f..23a71cb21273 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1319,10 +1319,11 @@ replay: err = ops->newlink(net, dev, tb, data); else err = register_netdevice(dev); - if (err < 0 && !IS_ERR(dev)) { + + if (err < 0 && !IS_ERR(dev)) free_netdev(dev); + if (err < 0) goto out; - } err = rtnl_configure_link(dev, ifm); if (err < 0) diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c index c7da600750bb..93c91b633a56 100644 --- a/net/ieee802154/af_ieee802154.c +++ b/net/ieee802154/af_ieee802154.c @@ -151,6 +151,9 @@ static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg, dev_load(sock_net(sk), ifr.ifr_name); dev = dev_get_by_name(sock_net(sk), ifr.ifr_name); + if (!dev) + return -ENODEV; + if (dev->type == ARPHRD_IEEE802154 && dev->netdev_ops->ndo_do_ioctl) ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd); diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index e0a3e3537b14..78cbc39f56c4 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -70,13 +70,17 @@ int inet_csk_bind_conflict(const struct sock *sk, (!sk->sk_bound_dev_if || !sk2->sk_bound_dev_if || sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) { + const __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2); + if (!reuse || !sk2->sk_reuse || sk2->sk_state == TCP_LISTEN) { - const __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2); if (!sk2_rcv_saddr || !sk_rcv_saddr || sk2_rcv_saddr == sk_rcv_saddr) break; - } + } else if (reuse && sk2->sk_reuse && + sk2_rcv_saddr && + sk2_rcv_saddr == sk_rcv_saddr) + break; } } return node != NULL; @@ -120,9 +124,11 @@ again: smallest_size = tb->num_owners; smallest_rover = rover; if (atomic_read(&hashinfo->bsockets) > (high - low) + 1) { - spin_unlock(&head->lock); - snum = smallest_rover; - goto have_snum; + if (!inet_csk(sk)->icsk_af_ops->bind_conflict(sk, tb)) { + spin_unlock(&head->lock); + snum = smallest_rover; + goto have_snum; + } } } goto next; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 6689c61cab47..8ce29747ad9b 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2298,7 +2298,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, if (sock_flag(sk, SOCK_KEEPOPEN) && !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) { - __u32 elapsed = tcp_time_stamp - tp->rcv_tstamp; + u32 elapsed = keepalive_time_elapsed(tp); if (tp->keepalive_time > elapsed) elapsed = tp->keepalive_time - elapsed; else diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index c732be00606b..440a5c6004f6 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -517,7 +517,7 @@ static void tcp_keepalive_timer (unsigned long data) struct sock *sk = (struct sock *) data; struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); - __u32 elapsed; + u32 elapsed; /* Only process if socket is not in use. */ bh_lock_sock(sk); @@ -554,7 +554,7 @@ static void tcp_keepalive_timer (unsigned long data) if (tp->packets_out || tcp_send_head(sk)) goto resched; - elapsed = tcp_time_stamp - tp->rcv_tstamp; + elapsed = keepalive_time_elapsed(tp); if (elapsed >= keepalive_time_when(tp)) { if (icsk->icsk_probes_out >= keepalive_probes(tp)) { diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 0c5e3c3b7fd5..9ca1efc923a1 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -42,11 +42,16 @@ int inet6_csk_bind_conflict(const struct sock *sk, if (sk != sk2 && (!sk->sk_bound_dev_if || !sk2->sk_bound_dev_if || - sk->sk_bound_dev_if == sk2->sk_bound_dev_if) && - (!sk->sk_reuse || !sk2->sk_reuse || - sk2->sk_state == TCP_LISTEN) && - ipv6_rcv_saddr_equal(sk, sk2)) - break; + sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) { + if ((!sk->sk_reuse || !sk2->sk_reuse || + sk2->sk_state == TCP_LISTEN) && + ipv6_rcv_saddr_equal(sk, sk2)) + break; + else if (sk->sk_reuse && sk2->sk_reuse && + !ipv6_addr_any(inet6_rcv_saddr(sk)) && + ipv6_rcv_saddr_equal(sk, sk2)) + break; + } } return node != NULL; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 61e2bef56090..7db09c3f5289 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -625,7 +625,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) /* We must not fragment if the socket is set to force MTU discovery * or if the skb it not generated by a local socket. */ - if (!skb->local_df) { + if (!skb->local_df && skb->len > mtu) { skb->dev = skb_dst(skb)->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), diff --git a/net/ipv6/route.c b/net/ipv6/route.c index c2438e8cb9d0..05ebd7833043 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -815,7 +815,7 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk, { int flags = 0; - if (rt6_need_strict(&fl->fl6_dst)) + if (fl->oif || rt6_need_strict(&fl->fl6_dst)) flags |= RT6_LOOKUP_F_IFACE; if (!ipv6_addr_any(&fl->fl6_src)) diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 8c452fd5ceae..4a0e77e14468 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -94,7 +94,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, xdst->u.dst.dev = dev; dev_hold(dev); - xdst->u.rt6.rt6i_idev = in6_dev_get(rt->u.dst.dev); + xdst->u.rt6.rt6i_idev = in6_dev_get(dev); if (!xdst->u.rt6.rt6i_idev) return -ENODEV; diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c index 9b4ced6e0968..c33da6576942 100644 --- a/net/phonet/pn_dev.c +++ b/net/phonet/pn_dev.c @@ -46,9 +46,16 @@ struct phonet_net { int phonet_net_id __read_mostly; +static struct phonet_net *phonet_pernet(struct net *net) +{ + BUG_ON(!net); + + return net_generic(net, phonet_net_id); +} + struct phonet_device_list *phonet_device_list(struct net *net) { - struct phonet_net *pnn = net_generic(net, phonet_net_id); + struct phonet_net *pnn = phonet_pernet(net); return &pnn->pndevs; } @@ -261,7 +268,7 @@ static int phonet_device_autoconf(struct net_device *dev) static void phonet_route_autodel(struct net_device *dev) { - struct phonet_net *pnn = net_generic(dev_net(dev), phonet_net_id); + struct phonet_net *pnn = phonet_pernet(dev_net(dev)); unsigned i; DECLARE_BITMAP(deleted, 64); @@ -313,7 +320,7 @@ static struct notifier_block phonet_device_notifier = { /* Per-namespace Phonet devices handling */ static int __net_init phonet_init_net(struct net *net) { - struct phonet_net *pnn = net_generic(net, phonet_net_id); + struct phonet_net *pnn = phonet_pernet(net); if (!proc_net_fops_create(net, "phonet", 0, &pn_sock_seq_fops)) return -ENOMEM; @@ -326,7 +333,7 @@ static int __net_init phonet_init_net(struct net *net) static void __net_exit phonet_exit_net(struct net *net) { - struct phonet_net *pnn = net_generic(net, phonet_net_id); + struct phonet_net *pnn = phonet_pernet(net); struct net_device *dev; unsigned i; @@ -376,7 +383,7 @@ void phonet_device_exit(void) int phonet_route_add(struct net_device *dev, u8 daddr) { - struct phonet_net *pnn = net_generic(dev_net(dev), phonet_net_id); + struct phonet_net *pnn = phonet_pernet(dev_net(dev)); struct phonet_routes *routes = &pnn->routes; int err = -EEXIST; @@ -393,7 +400,7 @@ int phonet_route_add(struct net_device *dev, u8 daddr) int phonet_route_del(struct net_device *dev, u8 daddr) { - struct phonet_net *pnn = net_generic(dev_net(dev), phonet_net_id); + struct phonet_net *pnn = phonet_pernet(dev_net(dev)); struct phonet_routes *routes = &pnn->routes; daddr = daddr >> 2; @@ -413,7 +420,7 @@ int phonet_route_del(struct net_device *dev, u8 daddr) struct net_device *phonet_route_get(struct net *net, u8 daddr) { - struct phonet_net *pnn = net_generic(net, phonet_net_id); + struct phonet_net *pnn = phonet_pernet(net); struct phonet_routes *routes = &pnn->routes; struct net_device *dev; @@ -428,7 +435,7 @@ struct net_device *phonet_route_get(struct net *net, u8 daddr) struct net_device *phonet_route_output(struct net *net, u8 daddr) { - struct phonet_net *pnn = net_generic(net, phonet_net_id); + struct phonet_net *pnn = phonet_pernet(net); struct phonet_routes *routes = &pnn->routes; struct net_device *dev; diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c index 5ea82fc47c3e..e599ba2f950d 100644 --- a/net/rds/rdma_transport.c +++ b/net/rds/rdma_transport.c @@ -133,7 +133,7 @@ static int __init rds_rdma_listen_init(void) ret = PTR_ERR(cm_id); printk(KERN_ERR "RDS/RDMA: failed to setup listener, " "rdma_create_id() returned %d\n", ret); - goto out; + return ret; } sin.sin_family = AF_INET, diff --git a/net/rxrpc/ar-recvmsg.c b/net/rxrpc/ar-recvmsg.c index 60c2b94e6b54..0c65013e3bfe 100644 --- a/net/rxrpc/ar-recvmsg.c +++ b/net/rxrpc/ar-recvmsg.c @@ -91,7 +91,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock, /* wait for a message to turn up */ release_sock(&rx->sk); - prepare_to_wait_exclusive(rx->sk.sk_sleep, &wait, + prepare_to_wait_exclusive(sk_sleep(&rx->sk), &wait, TASK_INTERRUPTIBLE); ret = sock_error(&rx->sk); if (ret) @@ -102,7 +102,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock, goto wait_interrupted; timeo = schedule_timeout(timeo); } - finish_wait(rx->sk.sk_sleep, &wait); + finish_wait(sk_sleep(&rx->sk), &wait); lock_sock(&rx->sk); continue; } @@ -356,7 +356,7 @@ csum_copy_error: wait_interrupted: ret = sock_intr_errno(timeo); wait_error: - finish_wait(rx->sk.sk_sleep, &wait); + finish_wait(sk_sleep(&rx->sk), &wait); if (continue_call) rxrpc_put_call(continue_call); if (copied) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 6cffbc4da029..296e65e01064 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -402,6 +402,7 @@ static void __x25_destroy_socket(struct sock *sk) /* * Queue the unaccepted socket for death */ + skb->sk->sk_state = TCP_LISTEN; sock_set_flag(skb->sk, SOCK_DEAD); x25_start_heartbeat(skb->sk); x25_sk(skb->sk)->state = X25_STATE_0; |