diff options
Diffstat (limited to 'drivers/net')
80 files changed, 501 insertions, 308 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 9fd8e5ecd5d..5bc74590c73 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -276,8 +276,13 @@ struct be_adapter { int link_speed; u8 port_type; u8 transceiver; + u8 generation; /* BladeEngine ASIC generation */ }; +/* BladeEngine Generation numbers */ +#define BE_GEN2 2 +#define BE_GEN3 3 + extern const struct ethtool_ops be_ethtool_ops; #define drvr_stats(adapter) (&adapter->stats.drvr_stats) diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 102ade13416..fee6eee7ae5 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -286,7 +286,7 @@ static void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len, MCC_WRB_SGE_CNT_SHIFT; wrb->payload_length = payload_len; wrb->tag0 = opcode; - be_dws_cpu_to_le(wrb, 20); + be_dws_cpu_to_le(wrb, 8); } /* Don't touch the hdr after it's prepared */ diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index c002b8391b4..13b33c84108 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -164,7 +164,8 @@ struct be_cmd_req_hdr { u8 domain; /* dword 0 */ u32 timeout; /* dword 1 */ u32 request_length; /* dword 2 */ - u32 rsvd; /* dword 3 */ + u8 version; /* dword 3 */ + u8 rsvd[3]; /* dword 3 */ }; #define RESP_HDR_INFO_OPCODE_SHIFT 0 /* bits 0 - 7 */ diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 3a1f7902c16..626b76c0ebc 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -910,7 +910,7 @@ static inline struct page *be_alloc_pages(u32 size) static void be_post_rx_frags(struct be_adapter *adapter) { struct be_rx_page_info *page_info_tbl = adapter->rx_obj.page_info_tbl; - struct be_rx_page_info *page_info = NULL; + struct be_rx_page_info *page_info = NULL, *prev_page_info = NULL; struct be_queue_info *rxq = &adapter->rx_obj.q; struct page *pagep = NULL; struct be_eth_rx_d *rxd; @@ -941,7 +941,6 @@ static void be_post_rx_frags(struct be_adapter *adapter) rxd = queue_head_node(rxq); rxd->fragpa_lo = cpu_to_le32(frag_dmaaddr & 0xFFFFFFFF); rxd->fragpa_hi = cpu_to_le32(upper_32_bits(frag_dmaaddr)); - queue_head_inc(rxq); /* Any space left in the current big page for another frag? */ if ((page_offset + rx_frag_size + rx_frag_size) > @@ -949,10 +948,13 @@ static void be_post_rx_frags(struct be_adapter *adapter) pagep = NULL; page_info->last_page_user = true; } + + prev_page_info = page_info; + queue_head_inc(rxq); page_info = &page_info_tbl[rxq->head]; } if (pagep) - page_info->last_page_user = true; + prev_page_info->last_page_user = true; if (posted) { atomic_add(posted, &rxq->used); @@ -1348,7 +1350,7 @@ static irqreturn_t be_intx(int irq, void *dev) int isr; isr = ioread32(adapter->csr + CEV_ISR0_OFFSET + - be_pci_func(adapter) * CEV_ISR_SIZE); + (adapter->tx_eq.q.id/ 8) * CEV_ISR_SIZE); if (!isr) return IRQ_NONE; @@ -2049,6 +2051,7 @@ static void be_unmap_pci_bars(struct be_adapter *adapter) static int be_map_pci_bars(struct be_adapter *adapter) { u8 __iomem *addr; + int pcicfg_reg; addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2), pci_resource_len(adapter->pdev, 2)); @@ -2062,8 +2065,13 @@ static int be_map_pci_bars(struct be_adapter *adapter) goto pci_map_err; adapter->db = addr; - addr = ioremap_nocache(pci_resource_start(adapter->pdev, 1), - pci_resource_len(adapter->pdev, 1)); + if (adapter->generation == BE_GEN2) + pcicfg_reg = 1; + else + pcicfg_reg = 0; + + addr = ioremap_nocache(pci_resource_start(adapter->pdev, pcicfg_reg), + pci_resource_len(adapter->pdev, pcicfg_reg)); if (addr == NULL) goto pci_map_err; adapter->pcicfg = addr; @@ -2160,6 +2168,7 @@ static int be_stats_init(struct be_adapter *adapter) cmd->va = pci_alloc_consistent(adapter->pdev, cmd->size, &cmd->dma); if (cmd->va == NULL) return -1; + memset(cmd->va, 0, cmd->size); return 0; } @@ -2238,6 +2247,20 @@ static int __devinit be_probe(struct pci_dev *pdev, goto rel_reg; } adapter = netdev_priv(netdev); + + switch (pdev->device) { + case BE_DEVICE_ID1: + case OC_DEVICE_ID1: + adapter->generation = BE_GEN2; + break; + case BE_DEVICE_ID2: + case OC_DEVICE_ID2: + adapter->generation = BE_GEN3; + break; + default: + adapter->generation = 0; + } + adapter->pdev = pdev; pci_set_drvdata(pdev, adapter); adapter->netdev = netdev; diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 8ffea3990d0..0b23bc4f56c 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c @@ -33,6 +33,7 @@ #include <asm/dma.h> #include <linux/dma-mapping.h> +#include <asm/dpmc.h> #include <asm/blackfin.h> #include <asm/cacheflush.h> #include <asm/portmux.h> @@ -386,8 +387,8 @@ static int mii_probe(struct net_device *dev) u32 sclk, mdc_div; /* Enable PHY output early */ - if (!(bfin_read_VR_CTL() & PHYCLKOE)) - bfin_write_VR_CTL(bfin_read_VR_CTL() | PHYCLKOE); + if (!(bfin_read_VR_CTL() & CLKBUFOE)) + bfin_write_VR_CTL(bfin_read_VR_CTL() | CLKBUFOE); sclk = get_sclk(); mdc_div = ((sclk / MDC_CLK) / 2) - 1; diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 3f0071cfe56..efa0e41bf3e 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3639,7 +3639,7 @@ static int bond_open(struct net_device *bond_dev) */ if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) { /* something went wrong - fail the open operation */ - return -1; + return -ENOMEM; } INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor); diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 2a567df3ea7..e8932db7ee7 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -326,6 +326,8 @@ struct e1000_adapter { /* for ioport free */ int bars; int need_ioport; + + bool discarding; }; enum e1000_state_t { diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 7e855f9bbd9..d29bb532ecc 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -1698,18 +1698,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) rctl &= ~E1000_RCTL_SZ_4096; rctl |= E1000_RCTL_BSEX; switch (adapter->rx_buffer_len) { - case E1000_RXBUFFER_256: - rctl |= E1000_RCTL_SZ_256; - rctl &= ~E1000_RCTL_BSEX; - break; - case E1000_RXBUFFER_512: - rctl |= E1000_RCTL_SZ_512; - rctl &= ~E1000_RCTL_BSEX; - break; - case E1000_RXBUFFER_1024: - rctl |= E1000_RCTL_SZ_1024; - rctl &= ~E1000_RCTL_BSEX; - break; case E1000_RXBUFFER_2048: default: rctl |= E1000_RCTL_SZ_2048; @@ -2802,13 +2790,13 @@ static int e1000_tx_map(struct e1000_adapter *adapter, dma_error: dev_err(&pdev->dev, "TX DMA map failed\n"); buffer_info->dma = 0; - count--; - - while (count >= 0) { + if (count) count--; - i--; - if (i < 0) + + while (count--) { + if (i==0) i += tx_ring->count; + i--; buffer_info = &tx_ring->buffer_info[i]; e1000_unmap_and_free_tx_resource(adapter, buffer_info); } @@ -3176,13 +3164,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) * however with the new *_jumbo_rx* routines, jumbo receives will use * fragmented skbs */ - if (max_frame <= E1000_RXBUFFER_256) - adapter->rx_buffer_len = E1000_RXBUFFER_256; - else if (max_frame <= E1000_RXBUFFER_512) - adapter->rx_buffer_len = E1000_RXBUFFER_512; - else if (max_frame <= E1000_RXBUFFER_1024) - adapter->rx_buffer_len = E1000_RXBUFFER_1024; - else if (max_frame <= E1000_RXBUFFER_2048) + if (max_frame <= E1000_RXBUFFER_2048) adapter->rx_buffer_len = E1000_RXBUFFER_2048; else #if (PAGE_SIZE >= E1000_RXBUFFER_16384) @@ -3850,13 +3832,22 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, length = le16_to_cpu(rx_desc->length); /* !EOP means multiple descriptors were used to store a single - * packet, also make sure the frame isn't just CRC only */ - if (unlikely(!(status & E1000_RXD_STAT_EOP) || (length <= 4))) { + * packet, if thats the case we need to toss it. In fact, we + * to toss every packet with the EOP bit clear and the next + * frame that _does_ have the EOP bit set, as it is by + * definition only a frame fragment + */ + if (unlikely(!(status & E1000_RXD_STAT_EOP))) + adapter->discarding = true; + + if (adapter->discarding) { /* All receives must fit into a single buffer */ E1000_DBG("%s: Receive packet consumed multiple" " buffers\n", netdev->name); /* recycle */ buffer_info->skb = skb; + if (status & E1000_RXD_STAT_EOP) + adapter->discarding = false; goto next_desc; } diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index cebbd9079d5..d236efaf747 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -421,6 +421,7 @@ struct e1000_info { /* CRC Stripping defines */ #define FLAG2_CRC_STRIPPING (1 << 0) #define FLAG2_HAS_PHY_WAKEUP (1 << 1) +#define FLAG2_IS_DISCARDING (1 << 2) #define E1000_RX_DESC_PS(R, i) \ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) @@ -582,7 +583,6 @@ extern s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data); extern s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data); -extern s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow); extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw); extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw); extern s32 e1000_check_polarity_82577(struct e1000_hw *hw); diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index ad08cf3f40c..8b6ecd12788 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -138,6 +138,10 @@ #define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */ #define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */ +/* KMRN Mode Control */ +#define HV_KMRN_MODE_CTRL PHY_REG(769, 16) +#define HV_KMRN_MDIO_SLOW 0x0400 + /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ /* Offset 04h HSFSTS */ union ich8_hws_flash_status { @@ -219,6 +223,7 @@ static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active); static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw); static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw); static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link); +static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw); static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) { @@ -270,7 +275,21 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; phy->id = e1000_phy_unknown; - e1000e_get_phy_id(hw); + ret_val = e1000e_get_phy_id(hw); + if (ret_val) + goto out; + if ((phy->id == 0) || (phy->id == PHY_REVISION_MASK)) { + /* + * In case the PHY needs to be in mdio slow mode (eg. 82577), + * set slow mode and try to get the PHY id again. + */ + ret_val = e1000_set_mdio_slow_mode_hv(hw); + if (ret_val) + goto out; + ret_val = e1000e_get_phy_id(hw); + if (ret_val) + goto out; + } phy->type = e1000e_get_phy_type_from_id(phy->id); switch (phy->type) { @@ -292,6 +311,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) break; } +out: return ret_val; } @@ -1076,16 +1096,44 @@ out: /** + * e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode + * @hw: pointer to the HW structure + **/ +static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw) +{ + s32 ret_val; + u16 data; + + ret_val = e1e_rphy(hw, HV_KMRN_MODE_CTRL, &data); + if (ret_val) + return ret_val; + + data |= HV_KMRN_MDIO_SLOW; + + ret_val = e1e_wphy(hw, HV_KMRN_MODE_CTRL, data); + + return ret_val; +} + +/** * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be * done after every PHY reset. **/ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) { s32 ret_val = 0; + u16 phy_data; if (hw->mac.type != e1000_pchlan) return ret_val; + /* Set MDIO slow mode before any other MDIO access */ + if (hw->phy.type == e1000_phy_82577) { + ret_val = e1000_set_mdio_slow_mode_hv(hw); + if (ret_val) + goto out; + } + if (((hw->phy.type == e1000_phy_82577) && ((hw->phy.revision == 1) || (hw->phy.revision == 2))) || ((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) { @@ -1118,16 +1166,32 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) hw->phy.addr = 1; ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); + hw->phy.ops.release(hw); if (ret_val) goto out; - hw->phy.ops.release(hw); /* * Configure the K1 Si workaround during phy reset assuming there is * link so that it disables K1 if link is in 1Gbps. */ ret_val = e1000_k1_gig_workaround_hv(hw, true); + if (ret_val) + goto out; + /* Workaround for link disconnects on a busy hub in half duplex */ + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto out; + ret_val = hw->phy.ops.read_reg_locked(hw, + PHY_REG(BM_PORT_CTRL_PAGE, 17), + &phy_data); + if (ret_val) + goto release; + ret_val = hw->phy.ops.write_reg_locked(hw, + PHY_REG(BM_PORT_CTRL_PAGE, 17), + phy_data & 0x00FF); +release: + hw->phy.ops.release(hw); out: return ret_val; } @@ -1184,6 +1248,7 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) /* Allow time for h/w to get to a quiescent state after reset */ mdelay(10); + /* Perform any necessary post-reset workarounds */ if (hw->mac.type == e1000_pchlan) { ret_val = e1000_hv_phy_workarounds_ich8lan(hw); if (ret_val) @@ -2484,6 +2549,10 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) if (!ret_val) e1000_release_swflag_ich8lan(hw); + /* Perform any necessary post-reset workarounds */ + if (hw->mac.type == e1000_pchlan) + ret_val = e1000_hv_phy_workarounds_ich8lan(hw); + if (ctrl & E1000_CTRL_PHY_RST) ret_val = hw->phy.ops.get_cfg_done(hw); @@ -2528,9 +2597,6 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) kab |= E1000_KABGTXD_BGSQLBIAS; ew32(KABGTXD, kab); - if (hw->mac.type == e1000_pchlan) - ret_val = e1000_hv_phy_workarounds_ich8lan(hw); - out: return ret_val; } diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index c45965a256b..57f149b75fb 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -450,13 +450,23 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, length = le16_to_cpu(rx_desc->length); - /* !EOP means multiple descriptors were used to store a single - * packet, also make sure the frame isn't just CRC only */ - if (!(status & E1000_RXD_STAT_EOP) || (length <= 4)) { + /* + * !EOP means multiple descriptors were used to store a single + * packet, if that's the case we need to toss it. In fact, we + * need to toss every packet with the EOP bit clear and the + * next frame that _does_ have the EOP bit set, as it is by + * definition only a frame fragment + */ + if (unlikely(!(status & E1000_RXD_STAT_EOP))) + adapter->flags2 |= FLAG2_IS_DISCARDING; + + if (adapter->flags2 & FLAG2_IS_DISCARDING) { /* All receives must fit into a single buffer */ e_dbg("Receive packet consumed multiple buffers\n"); /* recycle */ buffer_info->skb = skb; + if (status & E1000_RXD_STAT_EOP) + adapter->flags2 &= ~FLAG2_IS_DISCARDING; goto next_desc; } @@ -745,10 +755,16 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, PCI_DMA_FROMDEVICE); buffer_info->dma = 0; - if (!(staterr & E1000_RXD_STAT_EOP)) { + /* see !EOP comment in other rx routine */ + if (!(staterr & E1000_RXD_STAT_EOP)) + adapter->flags2 |= FLAG2_IS_DISCARDING; + + if (adapter->flags2 & FLAG2_IS_DISCARDING) { e_dbg("Packet Split buffers didn't pick up the full " "packet\n"); dev_kfree_skb_irq(skb); + if (staterr & E1000_RXD_STAT_EOP) + adapter->flags2 &= ~FLAG2_IS_DISCARDING; goto next_desc; } @@ -1118,6 +1134,7 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter) rx_ring->next_to_clean = 0; rx_ring->next_to_use = 0; + adapter->flags2 &= ~FLAG2_IS_DISCARDING; writel(0, adapter->hw.hw_addr + rx_ring->head); writel(0, adapter->hw.hw_addr + rx_ring->tail); @@ -2333,18 +2350,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) rctl &= ~E1000_RCTL_SZ_4096; rctl |= E1000_RCTL_BSEX; switch (adapter->rx_buffer_len) { - case 256: - rctl |= E1000_RCTL_SZ_256; - rctl &= ~E1000_RCTL_BSEX; - break; - case 512: - rctl |= E1000_RCTL_SZ_512; - rctl &= ~E1000_RCTL_BSEX; - break; - case 1024: - rctl |= E1000_RCTL_SZ_1024; - rctl &= ~E1000_RCTL_BSEX; - break; case 2048: default: rctl |= E1000_RCTL_SZ_2048; @@ -3781,7 +3786,7 @@ static int e1000_tso(struct e1000_adapter *adapter, 0, IPPROTO_TCP, 0); cmd_length = E1000_TXD_CMD_IP; ipcse = skb_transport_offset(skb) - 1; - } else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) { + } else if (skb_is_gso_v6(skb)) { ipv6_hdr(skb)->payload_len = 0; tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, @@ -3962,13 +3967,13 @@ static int e1000_tx_map(struct e1000_adapter *adapter, dma_error: dev_err(&pdev->dev, "TX DMA map failed\n"); buffer_info->dma = 0; - count--; - - while (count >= 0) { + if (count) count--; - i--; - if (i < 0) + + while (count--) { + if (i==0) i += tx_ring->count; + i--; buffer_info = &tx_ring->buffer_info[i]; e1000_put_txbuf(adapter, buffer_info);; } @@ -4317,13 +4322,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) * fragmented skbs */ - if (max_frame <= 256) - adapter->rx_buffer_len = 256; - else if (max_frame <= 512) - adapter->rx_buffer_len = 512; - else if (max_frame <= 1024) - adapter->rx_buffer_len = 1024; - else if (max_frame <= 2048) + if (max_frame <= 2048) adapter->rx_buffer_len = 2048; else adapter->rx_buffer_len = 4096; diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 55a2c0acfee..7f3ceb9dad6 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -152,32 +152,9 @@ s32 e1000e_get_phy_id(struct e1000_hw *hw) if (phy->id != 0 && phy->id != PHY_REVISION_MASK) goto out; - /* - * If the PHY ID is still unknown, we may have an 82577 - * without link. We will try again after setting Slow MDIC - * mode. No harm in trying again in this case since the PHY - * ID is unknown at this point anyway. - */ - ret_val = phy->ops.acquire(hw); - if (ret_val) - goto out; - ret_val = e1000_set_mdio_slow_mode_hv(hw, true); - if (ret_val) - goto out; - phy->ops.release(hw); - retry_count++; } out: - /* Revert to MDIO fast mode, if applicable */ - if (retry_count) { - ret_val = phy->ops.acquire(hw); - if (ret_val) - return ret_val; - ret_val = e1000_set_mdio_slow_mode_hv(hw, false); - phy->ops.release(hw); - } - return ret_val; } @@ -2791,38 +2768,6 @@ static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) } /** - * e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode - * @hw: pointer to the HW structure - * @slow: true for slow mode, false for normal mode - * - * Assumes semaphore already acquired. - **/ -s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow) -{ - s32 ret_val = 0; - u16 data = 0; - - /* Set MDIO mode - page 769, register 16: 0x2580==slow, 0x2180==fast */ - hw->phy.addr = 1; - ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, - (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT)); - if (ret_val) - goto out; - - ret_val = e1000e_write_phy_reg_mdic(hw, BM_CS_CTRL1, - (0x2180 | (slow << 10))); - if (ret_val) - goto out; - - /* dummy read when reverting to fast mode - throw away result */ - if (!slow) - ret_val = e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data); - -out: - return ret_val; -} - -/** * __e1000_read_phy_reg_hv - Read HV PHY register * @hw: pointer to the HW structure * @offset: register offset to be read @@ -2839,7 +2784,6 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, s32 ret_val; u16 page = BM_PHY_REG_PAGE(offset); u16 reg = BM_PHY_REG_NUM(offset); - bool in_slow_mode = false; if (!locked) { ret_val = hw->phy.ops.acquire(hw); @@ -2847,16 +2791,6 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, return ret_val; } - /* Workaround failure in MDIO access while cable is disconnected */ - if ((hw->phy.type == e1000_phy_82577) && - !(er32(STATUS) & E1000_STATUS_LU)) { - ret_val = e1000_set_mdio_slow_mode_hv(hw, true); - if (ret_val) - goto out; - - in_slow_mode = true; - } - /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, @@ -2893,10 +2827,6 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, data); out: - /* Revert to MDIO fast mode, if applicable */ - if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) - ret_val |= e1000_set_mdio_slow_mode_hv(hw, false); - if (!locked) hw->phy.ops.release(hw); @@ -2948,7 +2878,6 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, s32 ret_val; u16 page = BM_PHY_REG_PAGE(offset); u16 reg = BM_PHY_REG_NUM(offset); - bool in_slow_mode = false; if (!locked) { ret_val = hw->phy.ops.acquire(hw); @@ -2956,16 +2885,6 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, return ret_val; } - /* Workaround failure in MDIO access while cable is disconnected */ - if ((hw->phy.type == e1000_phy_82577) && - !(er32(STATUS) & E1000_STATUS_LU)) { - ret_val = e1000_set_mdio_slow_mode_hv(hw, true); - if (ret_val) - goto out; - - in_slow_mode = true; - } - /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, @@ -3019,10 +2938,6 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, data); out: - /* Revert to MDIO fast mode, if applicable */ - if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) - ret_val |= e1000_set_mdio_slow_mode_hv(hw, false); - if (!locked) hw->phy.ops.release(hw); diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 933c64ff246..997124d2992 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -3422,7 +3422,7 @@ static inline int igb_tso_adv(struct igb_ring *tx_ring, iph->daddr, 0, IPPROTO_TCP, 0); - } else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) { + } else if (skb_is_gso_v6(skb)) { ipv6_hdr(skb)->payload_len = 0; tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, @@ -3584,6 +3584,7 @@ static inline int igb_tx_map_adv(struct igb_ring *tx_ring, struct sk_buff *skb, for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { struct skb_frag_struct *frag; + count++; i++; if (i == tx_ring->count) i = 0; @@ -3605,7 +3606,6 @@ static inline int igb_tx_map_adv(struct igb_ring *tx_ring, struct sk_buff *skb, if (pci_dma_mapping_error(pdev, buffer_info->dma)) goto dma_error; - count++; } tx_ring->buffer_info[i].skb = skb; diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 0dbd0320023..2aa71a766c3 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -1963,7 +1963,7 @@ static int igbvf_tso(struct igbvf_adapter *adapter, iph->daddr, 0, IPPROTO_TCP, 0); - } else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) { + } else if (skb_is_gso_v6(skb)) { ipv6_hdr(skb)->payload_len = 0; tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, @@ -2117,6 +2117,7 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter, /* set time_stamp *before* dma to help avoid a possible race */ buffer_info->time_stamp = jiffies; buffer_info->next_to_watch = i; + buffer_info->mapped_as_page = false; buffer_info->dma = pci_map_single(pdev, skb->data, len, PCI_DMA_TODEVICE); if (pci_dma_mapping_error(pdev, buffer_info->dma)) @@ -2126,6 +2127,7 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter, for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { struct skb_frag_struct *frag; + count++; i++; if (i == tx_ring->count) i = 0; @@ -2146,7 +2148,6 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter, PCI_DMA_TODEVICE); if (pci_dma_mapping_error(pdev, buffer_info->dma)) goto dma_error; - count++; } tx_ring->buffer_info[i].skb = skb; @@ -2163,14 +2164,14 @@ dma_error: buffer_info->length = 0; buffer_info->next_to_watch = 0; buffer_info->mapped_as_page = false; - count--; + if (count) + count--; /* clear timestamp and dma mappings for remaining portion of packet */ - while (count >= 0) { - count--; - i--; - if (i < 0) + while (count--) { + if (i==0) i += tx_ring->count; + i--; buffer_info = &tx_ring->buffer_info[i]; igbvf_put_txbuf(adapter, buffer_info); } diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index bcd0f01d5fe..593d1a4f217 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1363,13 +1363,13 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb, dma_error: dev_err(&pdev->dev, "TX DMA map failed\n"); buffer_info->dma = 0; - count--; - - while (count >= 0) { + if (count) count--; - i--; - if (i < 0) + + while (count--) { + if (i==0) i += tx_ring->count; + i--; buffer_info = &tx_ring->buffer_info[i]; ixgb_unmap_and_free_tx_resource(adapter, buffer_info); } diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile index 21b41f42b61..bfef0ebcba9 100644 --- a/drivers/net/ixgbe/Makefile +++ b/drivers/net/ixgbe/Makefile @@ -1,7 +1,7 @@ ################################################################################ # # Intel 10 Gigabit PCI Express Linux driver -# Copyright(c) 1999 - 2009 Intel Corporation. +# Copyright(c) 1999 - 2010 Intel Corporation. # # This program is free software; you can redistribute it and/or modify it # under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 8da8eb53508..303e7bd39b6 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 204177d78ce..3103f416531 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 538340527aa..b49bd6b9feb 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 688b8ca5da3..21f158f79dd 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index 27f3214bed2..dfff0ffaa50 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c index a1562287342..9aea4f04bbd 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.c +++ b/drivers/net/ixgbe/ixgbe_dcb.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_dcb.h b/drivers/net/ixgbe/ixgbe_dcb.h index 64a9fa15c05..5caafd4afbc 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.h +++ b/drivers/net/ixgbe/ixgbe_dcb.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c index f30263898eb..f0e9279d466 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.h b/drivers/net/ixgbe/ixgbe_dcb_82598.h index ebbe53c352a..cc728fa092e 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c index ec8a252636d..4f7a26ab411 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.h b/drivers/net/ixgbe/ixgbe_dcb_82599.h index 9e5e2827e4a..0f3f791e1e1 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 3c7a79a7d7c..dd4883f642b 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -223,7 +223,7 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, if (adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] != adapter->dcb_cfg.bw_percentage[0][bwg_id]) { - adapter->dcb_set_bitmap |= BIT_PG_RX; + adapter->dcb_set_bitmap |= BIT_PG_TX; adapter->dcb_set_bitmap |= BIT_RESETLINK; } } @@ -341,6 +341,12 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) if (!adapter->dcb_set_bitmap) return DCB_NO_HW_CHG; + ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, + adapter->ring_feature[RING_F_DCB].indices); + + if (ret) + return DCB_NO_HW_CHG; + /* * Only take down the adapter if the configuration change * requires a reset. @@ -359,14 +365,6 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) } } - ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, - adapter->ring_feature[RING_F_DCB].indices); - if (ret) { - if (adapter->dcb_set_bitmap & BIT_RESETLINK) - clear_bit(__IXGBE_RESETTING, &adapter->state); - return DCB_NO_HW_CHG; - } - if (adapter->dcb_cfg.pfc_mode_enable) { if ((adapter->hw.mac.type != ixgbe_mac_82598EB) && (adapter->hw.fc.current_mode != ixgbe_fc_pfc)) diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 0bd49d3b9f6..d77961fc75f 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index da32a108a7b..e9a20c88c15 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h index de8ff53187d..abf4b2b3f25 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.h +++ b/drivers/net/ixgbe/ixgbe_fcoe.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 2ad754c864c..b5f64ad6797 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -52,7 +52,7 @@ static const char ixgbe_driver_string[] = #define DRV_VERSION "2.0.44-k2" const char ixgbe_driver_version[] = DRV_VERSION; -static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation."; +static char ixgbe_copyright[] = "Copyright (c) 1999-2010 Intel Corporation."; static const struct ixgbe_info *ixgbe_info_tbl[] = { [board_82598] = &ixgbe_82598_info, @@ -4928,7 +4928,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, iph->daddr, 0, IPPROTO_TCP, 0); - } else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) { + } else if (skb_is_gso_v6(skb)) { ipv6_hdr(skb)->payload_len = 0; tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, @@ -5167,14 +5167,14 @@ dma_error: tx_buffer_info->dma = 0; tx_buffer_info->time_stamp = 0; tx_buffer_info->next_to_watch = 0; - count--; + if (count) + count--; /* clear timestamp and dma mappings for remaining portion of packet */ - while (count >= 0) { - count--; - i--; - if (i < 0) + while (count--) { + if (i==0) i += tx_ring->count; + i--; tx_buffer_info = &tx_ring->tx_buffer_info[i]; ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); } @@ -5576,6 +5576,10 @@ static void ixgbe_netpoll(struct net_device *netdev) struct ixgbe_adapter *adapter = netdev_priv(netdev); int i; + /* if interface is down do nothing */ + if (test_bit(__IXGBE_DOWN, &adapter->state)) + return; + adapter->flags |= IXGBE_FLAG_IN_NETPOLL; if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 9ecad17522c..1c1efd38695 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h index 9b700f5bf1e..9cf5f3b4cc5 100644 --- a/drivers/net/ixgbe/ixgbe_phy.h +++ b/drivers/net/ixgbe/ixgbe_phy.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 84650c6ebe0..9eafddfa1b9 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c index c146304d8d6..c0ceebccaa4 100644 --- a/drivers/net/ks8851_mll.c +++ b/drivers/net/ks8851_mll.c @@ -854,8 +854,8 @@ static void ks_update_link_status(struct net_device *netdev, struct ks_net *ks) static irqreturn_t ks_irq(int irq, void *pw) { - struct ks_net *ks = pw; - struct net_device *netdev = ks->netdev; + struct net_device *netdev = pw; + struct ks_net *ks = netdev_priv(netdev); u16 status; /*this should be the first in IRQ handler */ diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 813aca3fc43..7b17404d085 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -717,6 +717,7 @@ static struct pcmcia_device_id fmvj18x_ids[] = { PCMCIA_PFC_DEVICE_PROD_ID12(0, "NEC", "PK-UG-J001" ,0x18df0ba0 ,0x831b1064), PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0d0a), PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0e0a), + PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0e01), PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0a05), PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x1101), PCMCIA_DEVICE_NULL, diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index b0e9f9c5172..0295097d6c4 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -410,7 +410,6 @@ EXPORT_SYMBOL(phy_start_aneg); static void phy_change(struct work_struct *work); -static void phy_state_machine(struct work_struct *work); /** * phy_start_machine - start PHY state machine tracking @@ -430,7 +429,6 @@ void phy_start_machine(struct phy_device *phydev, { phydev->adjust_state = handler; - INIT_DELAYED_WORK(&phydev->state_queue, phy_state_machine); schedule_delayed_work(&phydev->state_queue, HZ); } @@ -761,7 +759,7 @@ EXPORT_SYMBOL(phy_start); * phy_state_machine - Handle the state machine * @work: work_struct that describes the work to be done */ -static void phy_state_machine(struct work_struct *work) +void phy_state_machine(struct work_struct *work) { struct delayed_work *dwork = to_delayed_work(work); struct phy_device *phydev = diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 8212b2b9342..adbc0fded13 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -177,6 +177,7 @@ struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id) dev->state = PHY_DOWN; mutex_init(&dev->lock); + INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine); return dev; } diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 707b391afa0..894a7c84fae 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -4119,7 +4119,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev, err = pcie_set_readrq(pdev, 4096); if (err) { dev_err(&pdev->dev, "Set readrq failed.\n"); - goto err_out; + goto err_out1; } err = pci_request_regions(pdev, DRV_NAME); @@ -4140,7 +4140,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev, if (err) { dev_err(&pdev->dev, "No usable DMA configuration.\n"); - goto err_out; + goto err_out2; } /* Set PCIe reset type for EEH to fundamental. */ @@ -4152,7 +4152,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev, if (!qdev->reg_base) { dev_err(&pdev->dev, "Register mapping failed.\n"); err = -ENOMEM; - goto err_out; + goto err_out2; } qdev->doorbell_area_size = pci_resource_len(pdev, 3); @@ -4162,14 +4162,14 @@ static int __devinit ql_init_device(struct pci_dev *pdev, if (!qdev->doorbell_area) { dev_err(&pdev->dev, "Doorbell register mapping failed.\n"); err = -ENOMEM; - goto err_out; + goto err_out2; } err = ql_get_board_info(qdev); if (err) { dev_err(&pdev->dev, "Register access failed.\n"); err = -EIO; - goto err_out; + goto err_out2; } qdev->msg_enable = netif_msg_init(debug, default_msg); spin_lock_init(&qdev->hw_lock); @@ -4179,7 +4179,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev, err = qdev->nic_ops->get_flash(qdev); if (err) { dev_err(&pdev->dev, "Invalid FLASH.\n"); - goto err_out; + goto err_out2; } memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len); @@ -4212,8 +4212,9 @@ static int __devinit ql_init_device(struct pci_dev *pdev, DRV_NAME, DRV_VERSION); } return 0; -err_out: +err_out2: ql_release_all(pdev); +err_out1: pci_disable_device(pdev); return err; } diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index cc4218667cb..3c4836d0898 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -3421,7 +3421,7 @@ static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit, break; } } else { - if (!(val64 & busy_bit)) { + if (val64 & busy_bit) { ret = SUCCESS; break; } diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c index 683353b904c..9f035b9f035 100644 --- a/drivers/net/sfc/mcdi.c +++ b/drivers/net/sfc/mcdi.c @@ -142,8 +142,9 @@ static int efx_mcdi_poll(struct efx_nic *efx) if (spins != 0) { --spins; udelay(1); - } else - schedule(); + } else { + schedule_timeout_uninterruptible(1); + } time = get_seconds(); @@ -803,7 +804,7 @@ int efx_mcdi_nvram_read(struct efx_nic *efx, unsigned int type, loff_t offset, u8 *buffer, size_t length) { u8 inbuf[MC_CMD_NVRAM_READ_IN_LEN]; - u8 outbuf[MC_CMD_NVRAM_READ_OUT_LEN(length)]; + u8 outbuf[MC_CMD_NVRAM_READ_OUT_LEN(EFX_MCDI_NVRAM_LEN_MAX)]; size_t outlen; int rc; @@ -827,7 +828,7 @@ fail: int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type, loff_t offset, const u8 *buffer, size_t length) { - u8 inbuf[MC_CMD_NVRAM_WRITE_IN_LEN(length)]; + u8 inbuf[MC_CMD_NVRAM_WRITE_IN_LEN(EFX_MCDI_NVRAM_LEN_MAX)]; int rc; MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_TYPE, type); @@ -837,7 +838,8 @@ int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type, BUILD_BUG_ON(MC_CMD_NVRAM_WRITE_OUT_LEN != 0); - rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_WRITE, inbuf, sizeof(inbuf), + rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_WRITE, inbuf, + ALIGN(MC_CMD_NVRAM_WRITE_IN_LEN(length), 4), NULL, 0, NULL); if (rc) goto fail; diff --git a/drivers/net/sfc/mcdi.h b/drivers/net/sfc/mcdi.h index de916728c2e..10ce98f4c0f 100644 --- a/drivers/net/sfc/mcdi.h +++ b/drivers/net/sfc/mcdi.h @@ -111,6 +111,7 @@ extern int efx_mcdi_nvram_read(struct efx_nic *efx, unsigned int type, extern int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type, loff_t offset, const u8 *buffer, size_t length); +#define EFX_MCDI_NVRAM_LEN_MAX 128 extern int efx_mcdi_nvram_erase(struct efx_nic *efx, unsigned int type, loff_t offset, size_t length); extern int efx_mcdi_nvram_update_finish(struct efx_nic *efx, diff --git a/drivers/net/sfc/mcdi_pcol.h b/drivers/net/sfc/mcdi_pcol.h index 2a85360a46f..73e71f42062 100644 --- a/drivers/net/sfc/mcdi_pcol.h +++ b/drivers/net/sfc/mcdi_pcol.h @@ -1090,8 +1090,10 @@ #define MC_CMD_MAC_RX_LANES01_DISP_ERR 57 #define MC_CMD_MAC_RX_LANES23_DISP_ERR 58 #define MC_CMD_MAC_RX_MATCH_FAULT 59 +#define MC_CMD_GMAC_DMABUF_START 64 +#define MC_CMD_GMAC_DMABUF_END 95 /* Insert new members here. */ -#define MC_CMD_MAC_GENERATION_END 60 +#define MC_CMD_MAC_GENERATION_END 96 #define MC_CMD_MAC_NSTATS (MC_CMD_MAC_GENERATION_END+1) /* MC_CMD_MAC_STATS: diff --git a/drivers/net/sfc/mtd.c b/drivers/net/sfc/mtd.c index 3a464529a46..407bbaddfea 100644 --- a/drivers/net/sfc/mtd.c +++ b/drivers/net/sfc/mtd.c @@ -23,7 +23,6 @@ #include "mcdi_pcol.h" #define EFX_SPI_VERIFY_BUF_LEN 16 -#define EFX_MCDI_CHUNK_LEN 128 struct efx_mtd_partition { struct mtd_info mtd; @@ -428,7 +427,7 @@ static int siena_mtd_read(struct mtd_info *mtd, loff_t start, int rc = 0; while (offset < end) { - chunk = min_t(size_t, end - offset, EFX_MCDI_CHUNK_LEN); + chunk = min_t(size_t, end - offset, EFX_MCDI_NVRAM_LEN_MAX); rc = efx_mcdi_nvram_read(efx, part->mcdi.nvram_type, offset, buffer, chunk); if (rc) @@ -491,7 +490,7 @@ static int siena_mtd_write(struct mtd_info *mtd, loff_t start, } while (offset < end) { - chunk = min_t(size_t, end - offset, EFX_MCDI_CHUNK_LEN); + chunk = min_t(size_t, end - offset, EFX_MCDI_NVRAM_LEN_MAX); rc = efx_mcdi_nvram_write(efx, part->mcdi.nvram_type, offset, buffer, chunk); if (rc) diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c index ff8f0a417fa..e0d13a45101 100644 --- a/drivers/net/sfc/qt202x_phy.c +++ b/drivers/net/sfc/qt202x_phy.c @@ -318,12 +318,6 @@ static int qt202x_reset_phy(struct efx_nic *efx) /* Wait 250ms for the PHY to complete bootup */ msleep(250); - /* Check that all the MMDs we expect are present and responding. We - * expect faults on some if the link is down, but not on the PHY XS */ - rc = efx_mdio_check_mmds(efx, QT202X_REQUIRED_DEVS, MDIO_DEVS_PHYXS); - if (rc < 0) - goto fail; - falcon_board(efx)->type->init_phy(efx); return rc; diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index af393357979..250c8827b84 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c @@ -79,10 +79,14 @@ struct efx_loopback_state { static int efx_test_mdio(struct efx_nic *efx, struct efx_self_tests *tests) { int rc = 0; - int devad = __ffs(efx->mdio.mmds); + int devad; u16 physid1, physid2; - if (efx->phy_type == PHY_TYPE_NONE) + if (efx->mdio.mode_support & MDIO_SUPPORTS_C45) + devad = __ffs(efx->mdio.mmds); + else if (efx->mdio.mode_support & MDIO_SUPPORTS_C22) + devad = MDIO_DEVAD_NONE; + else return 0; mutex_lock(&efx->mac_lock); diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 37f486b65f6..d760650c5c0 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -644,6 +644,7 @@ static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port) { u32 reg1; + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); reg1 &= ~phy_power[port]; @@ -651,6 +652,7 @@ static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port) reg1 |= coma_mode[port]; sky2_pci_write32(hw, PCI_DEV_REG1, reg1); + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); sky2_pci_read32(hw, PCI_DEV_REG1); if (hw->chip_id == CHIP_ID_YUKON_FE) @@ -707,9 +709,11 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port) gm_phy_write(hw, port, PHY_MARV_CTRL, PHY_CT_PDOWN); } + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); reg1 |= phy_power[port]; /* set PHY to PowerDown/COMA Mode */ sky2_pci_write32(hw, PCI_DEV_REG1, reg1); + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); } /* Force a renegotiation */ @@ -2149,7 +2153,9 @@ static void sky2_qlink_intr(struct sky2_hw *hw) /* reset PHY Link Detect */ phy = sky2_pci_read16(hw, PSM_CONFIG_REG4); + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); sky2_pci_write16(hw, PSM_CONFIG_REG4, phy | 1); + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); sky2_link_up(sky2); } @@ -2640,6 +2646,7 @@ static void sky2_hw_intr(struct sky2_hw *hw) if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) { u16 pci_err; + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); pci_err = sky2_pci_read16(hw, PCI_STATUS); if (net_ratelimit()) dev_err(&pdev->dev, "PCI hardware error (0x%x)\n", @@ -2647,12 +2654,14 @@ static void sky2_hw_intr(struct sky2_hw *hw) sky2_pci_write16(hw, PCI_STATUS, pci_err | PCI_STATUS_ERROR_BITS); + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); } if (status & Y2_IS_PCI_EXP) { /* PCI-Express uncorrectable Error occurred */ u32 err; + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS); sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS, 0xfffffffful); @@ -2660,6 +2669,7 @@ static void sky2_hw_intr(struct sky2_hw *hw) dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err); sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS); + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); } if (status & Y2_HWE_L1_MASK) @@ -3038,6 +3048,7 @@ static void sky2_reset(struct sky2_hw *hw) } sky2_power_on(hw); + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); for (i = 0; i < hw->ports; i++) { sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); @@ -3074,6 +3085,7 @@ static void sky2_reset(struct sky2_hw *hw) reg <<= PSM_CONFIG_REG4_TIMER_PHY_LINK_DETECT_BASE; /* reset PHY Link Detect */ + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); sky2_pci_write16(hw, PSM_CONFIG_REG4, reg | PSM_CONFIG_REG4_RST_PHY_LINK_DETECT); sky2_pci_write16(hw, PSM_CONFIG_REG4, reg); @@ -3091,6 +3103,7 @@ static void sky2_reset(struct sky2_hw *hw) /* restore the PCIe Link Control register */ sky2_pci_write16(hw, cap + PCI_EXP_LNKCTL, reg); } + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); /* re-enable PEX PM in PEX PHY debug reg. 8 (clear bit 12) */ sky2_write32(hw, Y2_PEX_PHY_DATA, PEX_DB_ACCESS | (0x08UL << 16)); @@ -3228,6 +3241,27 @@ static inline u8 sky2_wol_supported(const struct sky2_hw *hw) return sky2_is_copper(hw) ? (WAKE_PHY | WAKE_MAGIC) : 0; } +static void sky2_hw_set_wol(struct sky2_hw *hw) +{ + int wol = 0; + int i; + + for (i = 0; i < hw->ports; i++) { + struct net_device *dev = hw->dev[i]; + struct sky2_port *sky2 = netdev_priv(dev); + + if (sky2->wol) + wol = 1; + } + + if (hw->chip_id == CHIP_ID_YUKON_EC_U || + hw->chip_id == CHIP_ID_YUKON_EX || + hw->chip_id == CHIP_ID_YUKON_FE_P) + sky2_write32(hw, B0_CTST, wol ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF); + + device_set_wakeup_enable(&hw->pdev->dev, wol); +} + static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { const struct sky2_port *sky2 = netdev_priv(dev); @@ -3247,13 +3281,7 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) sky2->wol = wol->wolopts; - if (hw->chip_id == CHIP_ID_YUKON_EC_U || - hw->chip_id == CHIP_ID_YUKON_EX || - hw->chip_id == CHIP_ID_YUKON_FE_P) - sky2_write32(hw, B0_CTST, sky2->wol - ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF); - - device_set_wakeup_enable(&hw->pdev->dev, sky2->wol); + sky2_hw_set_wol(hw); if (!netif_running(dev)) sky2_wol_init(sky2); diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 95db60adde4..f9521136a86 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -1063,7 +1063,7 @@ static int netdev_open(struct net_device *dev) if (retval) { printk(KERN_ERR "starfire: Failed to load firmware \"%s\"\n", FIRMWARE_RX); - return retval; + goto out_init; } if (fw_rx->size % 4) { printk(KERN_ERR "starfire: bogus length %zu in \"%s\"\n", @@ -1108,6 +1108,9 @@ out_tx: release_firmware(fw_tx); out_rx: release_firmware(fw_rx); +out_init: + if (retval) + netdev_close(dev); return retval; } diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 3a74d216859..7f82b0238e0 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4,7 +4,7 @@ * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com) * Copyright (C) 2004 Sun Microsystems Inc. - * Copyright (C) 2005-2009 Broadcom Corporation. + * Copyright (C) 2005-2010 Broadcom Corporation. * * Firmware is: * Derived from proprietary unpublished source code, @@ -68,8 +68,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.105" -#define DRV_MODULE_RELDATE "December 2, 2009" +#define DRV_MODULE_VERSION "3.106" +#define DRV_MODULE_RELDATE "January 12, 2010" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -1037,7 +1037,11 @@ static void tg3_mdio_start(struct tg3 *tp) else tp->phy_addr = 1; - is_serdes = tr32(SG_DIG_STATUS) & SG_DIG_IS_SERDES; + if (tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) + is_serdes = tr32(SG_DIG_STATUS) & SG_DIG_IS_SERDES; + else + is_serdes = tr32(TG3_CPMU_PHY_STRAP) & + TG3_CPMU_PHY_STRAP_IS_SERDES; if (is_serdes) tp->phy_addr += 7; } else @@ -4693,8 +4697,9 @@ next_pkt: (*post_ptr)++; if (unlikely(rx_std_posted >= tp->rx_std_max_post)) { - u32 idx = *post_ptr % TG3_RX_RING_SIZE; - tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, idx); + tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE; + tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, + tpr->rx_std_prod_idx); work_mask &= ~RXD_OPAQUE_RING_STD; rx_std_posted = 0; } @@ -7742,7 +7747,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) ((u64) tpr->rx_std_mapping >> 32)); tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW, ((u64) tpr->rx_std_mapping & 0xffffffff)); - if (!(tp->tg3_flags3 & TG3_FLG3_5755_PLUS)) + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717) tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR, NIC_SRAM_RX_BUFFER_DESC); @@ -12122,7 +12127,8 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) tp->phy_id = eeprom_phy_id; if (eeprom_phy_serdes) { - if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) + if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) tp->tg3_flags2 |= TG3_FLG2_MII_SERDES; else tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES; @@ -13384,6 +13390,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (err) return err; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 && + (tp->pci_chip_rev_id != CHIPREV_ID_5717_A0 || + (tp->tg3_flags2 & TG3_FLG2_MII_SERDES))) + return -ENOTSUPP; + /* Initialize data/descriptor byte/word swapping. */ val = tr32(GRC_MODE); val &= GRC_MODE_HOST_STACKUP; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index cd30889650f..8a167912902 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -4,6 +4,7 @@ * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) * Copyright (C) 2001 Jeff Garzik (jgarzik@pobox.com) * Copyright (C) 2004 Sun Microsystems Inc. + * Copyright (C) 2007-2010 Broadcom Corporation. */ #ifndef _T3_H @@ -1054,6 +1055,8 @@ #define CPMU_MUTEX_REQ_DRIVER 0x00001000 #define TG3_CPMU_MUTEX_GNT 0x00003660 #define CPMU_MUTEX_GNT_DRIVER 0x00001000 +#define TG3_CPMU_PHY_STRAP 0x00003664 +#define TG3_CPMU_PHY_STRAP_IS_SERDES 0x00000020 /* 0x3664 --> 0x3800 unused */ /* Mbuf cluster free registers */ diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 595777dcadb..20696b5d60a 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -249,6 +249,7 @@ static struct pci_device_id tulip_pci_tbl[] = { { 0x17B3, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x10b7, 0x9300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* 3Com 3CSOHO100B-TX */ { 0x14ea, 0xab08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* Planex FNW-3602-TX */ + { 0x1414, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* Microsoft MN-120 */ { 0x1414, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { } /* terminate list */ }; diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 96bdc0b4388..eb8fe7e16c6 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3279,13 +3279,12 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) /* Handle the transmitted buffer and release */ /* the BD to be used with the current frame */ - if (bd == ugeth->txBd[txQ]) /* queue empty? */ + skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; + if (!skb) break; dev->stats.tx_packets++; - skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; - if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN && skb_recycle_check(skb, ugeth->ug_info->uf_info.max_rx_buf_length + diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 21e183a83b9..4f27f022fbf 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -419,7 +419,7 @@ static int cdc_manage_power(struct usbnet *dev, int on) static const struct driver_info cdc_info = { .description = "CDC Ethernet Device", - .flags = FLAG_ETHER | FLAG_LINK_INTR, + .flags = FLAG_ETHER, // .check_connect = cdc_check_connect, .bind = cdc_bind, .unbind = usbnet_cdc_unbind, diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index c708ecc3cb2..9ead30bd00c 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -395,8 +395,7 @@ static void refill_work(struct work_struct *work) vi = container_of(work, struct virtnet_info, refill.work); napi_disable(&vi->napi); - try_fill_recv(vi, GFP_KERNEL); - still_empty = (vi->num == 0); + still_empty = !try_fill_recv(vi, GFP_KERNEL); napi_enable(&vi->napi); /* In theory, this can happen: if we don't get any buffers in diff --git a/drivers/net/wimax/i2400m/i2400m-usb.h b/drivers/net/wimax/i2400m/i2400m-usb.h index 5cc0f279417..2d7c96d7e86 100644 --- a/drivers/net/wimax/i2400m/i2400m-usb.h +++ b/drivers/net/wimax/i2400m/i2400m-usb.h @@ -151,6 +151,7 @@ enum { /* Device IDs */ USB_DEVICE_ID_I6050 = 0x0186, + USB_DEVICE_ID_I6050_2 = 0x0188, }; @@ -234,6 +235,7 @@ struct i2400mu { u8 rx_size_auto_shrink; struct dentry *debugfs_dentry; + unsigned i6050:1; /* 1 if this is a 6050 based SKU */ }; diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c index 3b48681f8a0..98f4f8c5fb6 100644 --- a/drivers/net/wimax/i2400m/usb.c +++ b/drivers/net/wimax/i2400m/usb.c @@ -478,7 +478,16 @@ int i2400mu_probe(struct usb_interface *iface, i2400m->bus_bm_wait_for_ack = i2400mu_bus_bm_wait_for_ack; i2400m->bus_bm_mac_addr_impaired = 0; - if (id->idProduct == USB_DEVICE_ID_I6050) { + switch (id->idProduct) { + case USB_DEVICE_ID_I6050: + case USB_DEVICE_ID_I6050_2: + i2400mu->i6050 = 1; + break; + default: + break; + } + + if (i2400mu->i6050) { i2400m->bus_fw_names = i2400mu_bus_fw_names_6050; i2400mu->endpoint_cfg.bulk_out = 0; i2400mu->endpoint_cfg.notification = 3; @@ -719,6 +728,7 @@ int i2400mu_post_reset(struct usb_interface *iface) static struct usb_device_id i2400mu_id_table[] = { { USB_DEVICE(0x8086, USB_DEVICE_ID_I6050) }, + { USB_DEVICE(0x8086, USB_DEVICE_ID_I6050_2) }, { USB_DEVICE(0x8086, 0x0181) }, { USB_DEVICE(0x8086, 0x1403) }, { USB_DEVICE(0x8086, 0x1405) }, diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 5d1c8677f18..6a3f4da7fb4 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -97,7 +97,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; int ret; u16 val; - u32 cksum, offset; + u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX; /* * Read values from EEPROM and store them in the capability structure @@ -116,12 +116,38 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) * Validate the checksum of the EEPROM date. There are some * devices with invalid EEPROMs. */ - for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) { + AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_UPPER, val); + if (val) { + eep_max = (val & AR5K_EEPROM_SIZE_UPPER_MASK) << + AR5K_EEPROM_SIZE_ENDLOC_SHIFT; + AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_LOWER, val); + eep_max = (eep_max | val) - AR5K_EEPROM_INFO_BASE; + + /* + * Fail safe check to prevent stupid loops due + * to busted EEPROMs. XXX: This value is likely too + * big still, waiting on a better value. + */ + if (eep_max > (3 * AR5K_EEPROM_INFO_MAX)) { + ATH5K_ERR(ah->ah_sc, "Invalid max custom EEPROM size: " + "%d (0x%04x) max expected: %d (0x%04x)\n", + eep_max, eep_max, + 3 * AR5K_EEPROM_INFO_MAX, + 3 * AR5K_EEPROM_INFO_MAX); + return -EIO; + } + } + + for (cksum = 0, offset = 0; offset < eep_max; offset++) { AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val); cksum ^= val; } if (cksum != AR5K_EEPROM_INFO_CKSUM) { - ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum); + ATH5K_ERR(ah->ah_sc, "Invalid EEPROM " + "checksum: 0x%04x eep_max: 0x%04x (%s)\n", + cksum, eep_max, + eep_max == AR5K_EEPROM_INFO_MAX ? + "default size" : "custom size"); return -EIO; } diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h index 0123f3521a0..473a483bb9c 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.h +++ b/drivers/net/wireless/ath/ath5k/eeprom.h @@ -37,6 +37,14 @@ #define AR5K_EEPROM_RFKILL_POLARITY_S 1 #define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ + +/* FLASH(EEPROM) Defines for AR531X chips */ +#define AR5K_EEPROM_SIZE_LOWER 0x1b /* size info -- lower */ +#define AR5K_EEPROM_SIZE_UPPER 0x1c /* size info -- upper */ +#define AR5K_EEPROM_SIZE_UPPER_MASK 0xfff0 +#define AR5K_EEPROM_SIZE_UPPER_SHIFT 4 +#define AR5K_EEPROM_SIZE_ENDLOC_SHIFT 12 + #define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */ #define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ #define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE) diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 03a1106ad72..5774cea23a3 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig @@ -25,7 +25,7 @@ config ATH9K config ATH9K_DEBUGFS bool "Atheros ath9k debugging" - depends on ATH9K + depends on ATH9K && DEBUG_FS ---help--- Say Y, if you need access to ath9k's statistics for interrupts, rate control, etc. diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index e2cef2ff5d8..1597a42731e 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -33,11 +33,11 @@ struct ath_node; /* Macro to expand scalars to 64-bit objects */ -#define ito64(x) (sizeof(x) == 8) ? \ +#define ito64(x) (sizeof(x) == 1) ? \ (((unsigned long long int)(x)) & (0xff)) : \ - (sizeof(x) == 16) ? \ + (sizeof(x) == 2) ? \ (((unsigned long long int)(x)) & 0xffff) : \ - ((sizeof(x) == 32) ? \ + ((sizeof(x) == 4) ? \ (((unsigned long long int)(x)) & 0xffffffff) : \ (unsigned long long int)(x)) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 2ec61f08cfd..ae371448b5a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -855,12 +855,11 @@ static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah) } } -static void ath9k_hw_init_11a_eeprom_fix(struct ath_hw *ah) +static void ath9k_hw_init_eeprom_fix(struct ath_hw *ah) { u32 i, j; - if ((ah->hw_version.devid == AR9280_DEVID_PCI) && - test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) { + if (ah->hw_version.devid == AR9280_DEVID_PCI) { /* EEPROM Fixup */ for (i = 0; i < ah->iniModes.ia_rows; i++) { @@ -980,7 +979,7 @@ int ath9k_hw_init(struct ath_hw *ah) if (r) return r; - ath9k_hw_init_11a_eeprom_fix(ah); + ath9k_hw_init_eeprom_fix(ah); r = ath9k_hw_init_macaddr(ah); if (r) { diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 996eb90263c..643bea35686 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2655,10 +2655,10 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { ath9k_ps_wakeup(sc); ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); - ath_beacon_return(sc, avp); ath9k_ps_restore(sc); } + ath_beacon_return(sc, avp); sc->sc_flags &= ~SC_OP_BEACONS; for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 484c5fdf7c2..9b4b8b5c757 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -1961,7 +1961,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, struct ieee80211_tx_info *info; struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; u32 status = le32_to_cpu(tx_resp->u.status); - int tid = MAX_TID_COUNT; + int uninitialized_var(tid); int sta_id; int freed; u8 *qc = NULL; diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 33a5866538e..de45f308b74 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -1598,6 +1598,7 @@ struct iwl_cfg iwl5300_agn_cfg = { .use_bsm = false, .ht_greenfield_support = true, .led_compensation = 51, + .use_rts_for_ht = true, /* use rts/cts protection */ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, }; @@ -1622,6 +1623,7 @@ struct iwl_cfg iwl5100_bgn_cfg = { .use_bsm = false, .ht_greenfield_support = true, .led_compensation = 51, + .use_rts_for_ht = true, /* use rts/cts protection */ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, }; @@ -1667,6 +1669,7 @@ struct iwl_cfg iwl5100_agn_cfg = { .use_bsm = false, .ht_greenfield_support = true, .led_compensation = 51, + .use_rts_for_ht = true, /* use rts/cts protection */ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, }; @@ -1691,6 +1694,7 @@ struct iwl_cfg iwl5350_agn_cfg = { .use_bsm = false, .ht_greenfield_support = true, .led_compensation = 51, + .use_rts_for_ht = true, /* use rts/cts protection */ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, }; @@ -1715,6 +1719,7 @@ struct iwl_cfg iwl5150_agn_cfg = { .use_bsm = false, .ht_greenfield_support = true, .led_compensation = 51, + .use_rts_for_ht = true, /* use rts/cts protection */ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 574d3665870..5461f105bd2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2344,6 +2344,21 @@ static void iwl_ht_conf(struct iwl_priv *priv, IWL_DEBUG_MAC80211(priv, "leave\n"); } +static inline void iwl_set_no_assoc(struct iwl_priv *priv) +{ + priv->assoc_id = 0; + iwl_led_disassociate(priv); + /* + * inform the ucode that there is no longer an + * association and that no more packets should be + * sent + */ + priv->staging_rxon.filter_flags &= + ~RXON_FILTER_ASSOC_MSK; + priv->staging_rxon.assoc_id = 0; + iwlcore_commit_rxon(priv); +} + #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) void iwl_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -2475,20 +2490,8 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; if (!iwl_is_rfkill(priv)) priv->cfg->ops->lib->post_associate(priv); - } else { - priv->assoc_id = 0; - iwl_led_disassociate(priv); - - /* - * inform the ucode that there is no longer an - * association and that no more packets should be - * send - */ - priv->staging_rxon.filter_flags &= - ~RXON_FILTER_ASSOC_MSK; - priv->staging_rxon.assoc_id = 0; - iwlcore_commit_rxon(priv); - } + } else + iwl_set_no_assoc(priv); } if (changes && iwl_is_associated(priv) && priv->assoc_id) { @@ -2503,12 +2506,14 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, } } - if ((changes & BSS_CHANGED_BEACON_ENABLED) && - vif->bss_conf.enable_beacon) { - memcpy(priv->staging_rxon.bssid_addr, - bss_conf->bssid, ETH_ALEN); - memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); - iwlcore_config_ap(priv); + if (changes & BSS_CHANGED_BEACON_ENABLED) { + if (vif->bss_conf.enable_beacon) { + memcpy(priv->staging_rxon.bssid_addr, + bss_conf->bssid, ETH_ALEN); + memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); + iwlcore_config_ap(priv); + } else + iwl_set_no_assoc(priv); } mutex_unlock(&priv->mutex); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 165d1f6e2dd..3822cf53e36 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -711,7 +711,7 @@ extern void iwl_txq_ctx_stop(struct iwl_priv *priv); extern int iwl_queue_space(const struct iwl_queue *q); static inline int iwl_queue_used(const struct iwl_queue *q, int i) { - return q->write_ptr > q->read_ptr ? + return q->write_ptr >= q->read_ptr ? (i >= q->read_ptr && i < q->write_ptr) : !(i < q->read_ptr && i >= q->write_ptr); } diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c index e7d88d1da15..83cc4e500a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c @@ -1,3 +1,29 @@ +/****************************************************************************** + * + * Copyright(c) 2009 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless <ilw@linux.intel.com> + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + #include <linux/module.h> /* sparse doesn't like tracepoint macros */ diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 21361968ab7..d9c7363b1bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -1,3 +1,29 @@ +/****************************************************************************** + * + * Copyright(c) 2009 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless <ilw@linux.intel.com> + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + #if !defined(__IWLWIFI_DEVICE_TRACE) || defined(TRACE_HEADER_MULTI_READ) #define __IWLWIFI_DEVICE_TRACE diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index cde09a890b7..90fbdb25399 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -297,7 +297,7 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags, } EXPORT_SYMBOL(iwl_add_station); -static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr) +static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const u8 *addr) { unsigned long flags; u8 sta_id = iwl_find_station(priv, addr); @@ -324,7 +324,7 @@ static void iwl_remove_sta_callback(struct iwl_priv *priv, { struct iwl_rem_sta_cmd *rm_sta = (struct iwl_rem_sta_cmd *)cmd->cmd.payload; - const char *addr = rm_sta->addr; + const u8 *addr = rm_sta->addr; if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c index 777584d76a8..1e41ad0fcad 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.c +++ b/drivers/net/wireless/iwmc3200wifi/commands.c @@ -973,6 +973,10 @@ int iwm_send_pmkid_update(struct iwm_priv *iwm, memset(&update, 0, sizeof(struct iwm_umac_pmkid_update)); + update.hdr.oid = UMAC_WIFI_IF_CMD_PMKID_UPDATE; + update.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_pmkid_update) - + sizeof(struct iwm_umac_wifi_if)); + update.command = cpu_to_le32(command); if (pmksa->bssid) memcpy(&update.bssid, pmksa->bssid, ETH_ALEN); diff --git a/drivers/net/wireless/iwmc3200wifi/commands.h b/drivers/net/wireless/iwmc3200wifi/commands.h index 06af0552cd7..3dfd9f0e900 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.h +++ b/drivers/net/wireless/iwmc3200wifi/commands.h @@ -463,6 +463,7 @@ struct iwm_umac_cmd_stop_resume_tx { #define IWM_CMD_PMKID_FLUSH 3 struct iwm_umac_pmkid_update { + struct iwm_umac_wifi_if hdr; __le32 command; u8 bssid[ETH_ALEN]; __le16 reserved; diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 59d49159cf2..59f92105b0c 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -3157,8 +3157,10 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw, /* Clear unsupported feature flags */ *total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC; - if (mwl8k_fw_lock(hw)) + if (mwl8k_fw_lock(hw)) { + kfree(cmd); return; + } if (priv->sniffer_enabled) { mwl8k_enable_sniffer(hw, 0); diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index a15962a19b2..a72f7c2577d 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c @@ -197,6 +197,14 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index, i %= ring_limit; continue; } + + if (unlikely(len > priv->common.rx_mtu)) { + if (net_ratelimit()) + dev_err(&priv->pdev->dev, "rx'd frame size " + "exceeds length threshold.\n"); + + len = priv->common.rx_mtu; + } skb_put(skb, len); if (p54_rx(dev, skb)) { diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 27bf887f145..9deae41cb78 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -340,7 +340,7 @@ static int rt2800_blink_set(struct led_classdev *led_cdev, rt2x00_set_field32(®, LED_CFG_OFF_PERIOD, *delay_off); rt2x00_set_field32(®, LED_CFG_SLOW_BLINK_PERIOD, 3); rt2x00_set_field32(®, LED_CFG_R_LED_MODE, 3); - rt2x00_set_field32(®, LED_CFG_G_LED_MODE, 12); + rt2x00_set_field32(®, LED_CFG_G_LED_MODE, 3); rt2x00_set_field32(®, LED_CFG_Y_LED_MODE, 3); rt2x00_set_field32(®, LED_CFG_LED_POLAR, 1); rt2800_register_write(led->rt2x00dev, LED_CFG, reg); diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 4d841c07c97..dcfc8c25d1a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -113,6 +113,12 @@ ( ((unsigned long)((__skb)->data + (__header))) & 3 ) /* + * Constants for extra TX headroom for alignment purposes. + */ +#define RT2X00_ALIGN_SIZE 4 /* Only whole frame needs alignment */ +#define RT2X00_L2PAD_SIZE 8 /* Both header & payload need alignment */ + +/* * Standard timing and size defines. * These values should follow the ieee80211 specifications. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 06c43ca39bf..265e66dba55 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -686,7 +686,17 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) /* * Initialize extra TX headroom required. */ - rt2x00dev->hw->extra_tx_headroom = rt2x00dev->ops->extra_tx_headroom; + rt2x00dev->hw->extra_tx_headroom = + max_t(unsigned int, IEEE80211_TX_STATUS_HEADROOM, + rt2x00dev->ops->extra_tx_headroom); + + /* + * Take TX headroom required for alignment into account. + */ + if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) + rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE; + else if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) + rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE; /* * Register HW. diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 239afc7a9c0..9915a09141e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -104,7 +104,7 @@ void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) * is also mapped to the DMA so it can be used for transfering * additional descriptor information to the hardware. */ - skb_push(skb, rt2x00dev->hw->extra_tx_headroom); + skb_push(skb, rt2x00dev->ops->extra_tx_headroom); skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE); @@ -112,7 +112,7 @@ void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) /* * Restore data pointer to original location again. */ - skb_pull(skb, rt2x00dev->hw->extra_tx_headroom); + skb_pull(skb, rt2x00dev->ops->extra_tx_headroom); skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; } @@ -134,7 +134,7 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) * by the driver, but it was actually mapped to DMA. */ dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, - skb->len + rt2x00dev->hw->extra_tx_headroom, + skb->len + rt2x00dev->ops->extra_tx_headroom, DMA_TO_DEVICE); skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; } diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 8ebf5c33955..f14deb0c851 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -987,12 +987,13 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw, changed_flags &= SUPPORTED_FIF_FLAGS; *new_flags &= SUPPORTED_FIF_FLAGS; - /* changed_flags is always populated but this driver - * doesn't support all FIF flags so its possible we don't - * need to do anything */ - if (!changed_flags) - return; - + /* + * If multicast parameter (as returned by zd_op_prepare_multicast) + * has changed, no bit in changed_flags is set. To handle this + * situation, we do not return if changed_flags is 0. If we do so, + * we will have some issue with IPv6 which uses multicast for link + * layer address resolution. + */ if (*new_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) zd_mc_add_all(&hash); diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index ac19ecd19cf..72d3e437e19 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -62,6 +62,7 @@ static struct usb_device_id usb_ids[] = { { USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 }, /* ZD1211B */ { USB_DEVICE(0x0053, 0x5301), .driver_info = DEVICE_ZD1211B }, + { USB_DEVICE(0x0409, 0x0248), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x0411, 0x00da), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x0471, 0x1236), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B }, |