diff options
Diffstat (limited to 'drivers/net')
42 files changed, 581 insertions, 223 deletions
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index a580db29e503..26e7129332ab 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c | |||
| @@ -83,6 +83,11 @@ | |||
| 83 | #define INSTRUCTION_LOAD_TXB(n) (0x40 + 2 * (n)) | 83 | #define INSTRUCTION_LOAD_TXB(n) (0x40 + 2 * (n)) |
| 84 | #define INSTRUCTION_READ_RXB(n) (((n) == 0) ? 0x90 : 0x94) | 84 | #define INSTRUCTION_READ_RXB(n) (((n) == 0) ? 0x90 : 0x94) |
| 85 | #define INSTRUCTION_RESET 0xC0 | 85 | #define INSTRUCTION_RESET 0xC0 |
| 86 | #define RTS_TXB0 0x01 | ||
| 87 | #define RTS_TXB1 0x02 | ||
| 88 | #define RTS_TXB2 0x04 | ||
| 89 | #define INSTRUCTION_RTS(n) (0x80 | ((n) & 0x07)) | ||
| 90 | |||
| 86 | 91 | ||
| 87 | /* MPC251x registers */ | 92 | /* MPC251x registers */ |
| 88 | #define CANSTAT 0x0e | 93 | #define CANSTAT 0x0e |
| @@ -397,6 +402,7 @@ static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf, | |||
| 397 | static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame, | 402 | static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame, |
| 398 | int tx_buf_idx) | 403 | int tx_buf_idx) |
| 399 | { | 404 | { |
| 405 | struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); | ||
| 400 | u32 sid, eid, exide, rtr; | 406 | u32 sid, eid, exide, rtr; |
| 401 | u8 buf[SPI_TRANSFER_BUF_LEN]; | 407 | u8 buf[SPI_TRANSFER_BUF_LEN]; |
| 402 | 408 | ||
| @@ -418,7 +424,10 @@ static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame, | |||
| 418 | buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc; | 424 | buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc; |
| 419 | memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc); | 425 | memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc); |
| 420 | mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx); | 426 | mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx); |
| 421 | mcp251x_write_reg(spi, TXBCTRL(tx_buf_idx), TXBCTRL_TXREQ); | 427 | |
| 428 | /* use INSTRUCTION_RTS, to avoid "repeated frame problem" */ | ||
| 429 | priv->spi_tx_buf[0] = INSTRUCTION_RTS(1 << tx_buf_idx); | ||
| 430 | mcp251x_spi_trans(priv->spi, 1); | ||
| 422 | } | 431 | } |
| 423 | 432 | ||
| 424 | static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, | 433 | static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 21b553229ea4..dfd86a55f1dc 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | |||
| @@ -710,17 +710,15 @@ static inline u16 bnx2x_tx_avail(struct bnx2x *bp, | |||
| 710 | prod = txdata->tx_bd_prod; | 710 | prod = txdata->tx_bd_prod; |
| 711 | cons = txdata->tx_bd_cons; | 711 | cons = txdata->tx_bd_cons; |
| 712 | 712 | ||
| 713 | /* NUM_TX_RINGS = number of "next-page" entries | 713 | used = SUB_S16(prod, cons); |
| 714 | It will be used as a threshold */ | ||
| 715 | used = SUB_S16(prod, cons) + (s16)NUM_TX_RINGS; | ||
| 716 | 714 | ||
| 717 | #ifdef BNX2X_STOP_ON_ERROR | 715 | #ifdef BNX2X_STOP_ON_ERROR |
| 718 | WARN_ON(used < 0); | 716 | WARN_ON(used < 0); |
| 719 | WARN_ON(used > bp->tx_ring_size); | 717 | WARN_ON(used > txdata->tx_ring_size); |
| 720 | WARN_ON((bp->tx_ring_size - used) > MAX_TX_AVAIL); | 718 | WARN_ON((txdata->tx_ring_size - used) > MAX_TX_AVAIL); |
| 721 | #endif | 719 | #endif |
| 722 | 720 | ||
| 723 | return (s16)(bp->tx_ring_size) - used; | 721 | return (s16)(txdata->tx_ring_size) - used; |
| 724 | } | 722 | } |
| 725 | 723 | ||
| 726 | static inline int bnx2x_tx_queue_has_work(struct bnx2x_fp_txdata *txdata) | 724 | static inline int bnx2x_tx_queue_has_work(struct bnx2x_fp_txdata *txdata) |
| @@ -1088,6 +1086,7 @@ static inline void bnx2x_init_txdata(struct bnx2x *bp, | |||
| 1088 | txdata->txq_index = txq_index; | 1086 | txdata->txq_index = txq_index; |
| 1089 | txdata->tx_cons_sb = tx_cons_sb; | 1087 | txdata->tx_cons_sb = tx_cons_sb; |
| 1090 | txdata->parent_fp = fp; | 1088 | txdata->parent_fp = fp; |
| 1089 | txdata->tx_ring_size = IS_FCOE_FP(fp) ? MAX_TX_AVAIL : bp->tx_ring_size; | ||
| 1091 | 1090 | ||
| 1092 | DP(NETIF_MSG_IFUP, "created tx data cid %d, txq %d\n", | 1091 | DP(NETIF_MSG_IFUP, "created tx data cid %d, txq %d\n", |
| 1093 | txdata->cid, txdata->txq_index); | 1092 | txdata->cid, txdata->txq_index); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h index 3e4cff9b1ebe..b926f58e983b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h | |||
| @@ -401,11 +401,11 @@ static const struct reg_addr reg_addrs[] = { | |||
| 401 | { 0x70000, 8, RI_ALL_ONLINE }, | 401 | { 0x70000, 8, RI_ALL_ONLINE }, |
| 402 | { 0x70020, 8184, RI_ALL_OFFLINE }, | 402 | { 0x70020, 8184, RI_ALL_OFFLINE }, |
| 403 | { 0x78000, 8192, RI_E3E3B0_OFFLINE }, | 403 | { 0x78000, 8192, RI_E3E3B0_OFFLINE }, |
| 404 | { 0x85000, 3, RI_ALL_ONLINE }, | 404 | { 0x85000, 3, RI_ALL_OFFLINE }, |
| 405 | { 0x8501c, 7, RI_ALL_ONLINE }, | 405 | { 0x8501c, 7, RI_ALL_OFFLINE }, |
| 406 | { 0x85048, 1, RI_ALL_ONLINE }, | 406 | { 0x85048, 1, RI_ALL_OFFLINE }, |
| 407 | { 0x85200, 32, RI_ALL_ONLINE }, | 407 | { 0x85200, 32, RI_ALL_OFFLINE }, |
| 408 | { 0xb0000, 16384, RI_E1H_ONLINE }, | 408 | { 0xb0000, 16384, RI_E1H_OFFLINE }, |
| 409 | { 0xc1000, 7, RI_ALL_ONLINE }, | 409 | { 0xc1000, 7, RI_ALL_ONLINE }, |
| 410 | { 0xc103c, 2, RI_E2E3E3B0_ONLINE }, | 410 | { 0xc103c, 2, RI_E2E3E3B0_ONLINE }, |
| 411 | { 0xc1800, 2, RI_ALL_ONLINE }, | 411 | { 0xc1800, 2, RI_ALL_ONLINE }, |
| @@ -581,17 +581,12 @@ static const struct reg_addr reg_addrs[] = { | |||
| 581 | { 0x140188, 3, RI_E1E1HE2E3_ONLINE }, | 581 | { 0x140188, 3, RI_E1E1HE2E3_ONLINE }, |
| 582 | { 0x140194, 13, RI_ALL_ONLINE }, | 582 | { 0x140194, 13, RI_ALL_ONLINE }, |
| 583 | { 0x140200, 6, RI_E1E1HE2E3_ONLINE }, | 583 | { 0x140200, 6, RI_E1E1HE2E3_ONLINE }, |
| 584 | { 0x140220, 4, RI_E2E3_ONLINE }, | ||
| 585 | { 0x140240, 4, RI_E2E3_ONLINE }, | ||
| 586 | { 0x140260, 4, RI_E2E3_ONLINE }, | 584 | { 0x140260, 4, RI_E2E3_ONLINE }, |
| 587 | { 0x140280, 4, RI_E2E3_ONLINE }, | 585 | { 0x140280, 4, RI_E2E3_ONLINE }, |
| 588 | { 0x1402a0, 4, RI_E2E3_ONLINE }, | ||
| 589 | { 0x1402c0, 4, RI_E2E3_ONLINE }, | ||
| 590 | { 0x1402e0, 2, RI_E2E3_ONLINE }, | 586 | { 0x1402e0, 2, RI_E2E3_ONLINE }, |
| 591 | { 0x1402e8, 2, RI_E2E3E3B0_ONLINE }, | 587 | { 0x1402e8, 2, RI_E2E3E3B0_ONLINE }, |
| 592 | { 0x1402f0, 9, RI_E2E3_ONLINE }, | 588 | { 0x1402f0, 9, RI_E2E3_ONLINE }, |
| 593 | { 0x140314, 44, RI_E3B0_ONLINE }, | 589 | { 0x140314, 44, RI_E3B0_ONLINE }, |
| 594 | { 0x1403d0, 70, RI_E3B0_ONLINE }, | ||
| 595 | { 0x144000, 4, RI_E1E1H_ONLINE }, | 590 | { 0x144000, 4, RI_E1E1H_ONLINE }, |
| 596 | { 0x148000, 4, RI_E1E1H_ONLINE }, | 591 | { 0x148000, 4, RI_E1E1H_ONLINE }, |
| 597 | { 0x14c000, 4, RI_E1E1H_ONLINE }, | 592 | { 0x14c000, 4, RI_E1E1H_ONLINE }, |
| @@ -704,7 +699,6 @@ static const struct reg_addr reg_addrs[] = { | |||
| 704 | { 0x180398, 1, RI_E2E3E3B0_ONLINE }, | 699 | { 0x180398, 1, RI_E2E3E3B0_ONLINE }, |
| 705 | { 0x1803a0, 5, RI_E2E3E3B0_ONLINE }, | 700 | { 0x1803a0, 5, RI_E2E3E3B0_ONLINE }, |
| 706 | { 0x1803b4, 2, RI_E3E3B0_ONLINE }, | 701 | { 0x1803b4, 2, RI_E3E3B0_ONLINE }, |
| 707 | { 0x180400, 1, RI_ALL_ONLINE }, | ||
| 708 | { 0x180404, 255, RI_E1E1H_OFFLINE }, | 702 | { 0x180404, 255, RI_E1E1H_OFFLINE }, |
| 709 | { 0x181000, 4, RI_ALL_ONLINE }, | 703 | { 0x181000, 4, RI_ALL_ONLINE }, |
| 710 | { 0x181010, 1020, RI_ALL_OFFLINE }, | 704 | { 0x181010, 1020, RI_ALL_OFFLINE }, |
| @@ -800,9 +794,9 @@ static const struct reg_addr reg_addrs[] = { | |||
| 800 | { 0x1b905c, 1, RI_E3E3B0_ONLINE }, | 794 | { 0x1b905c, 1, RI_E3E3B0_ONLINE }, |
| 801 | { 0x1b9064, 1, RI_E3B0_ONLINE }, | 795 | { 0x1b9064, 1, RI_E3B0_ONLINE }, |
| 802 | { 0x1b9080, 10, RI_E3B0_ONLINE }, | 796 | { 0x1b9080, 10, RI_E3B0_ONLINE }, |
| 803 | { 0x1b9400, 14, RI_E2E3E3B0_ONLINE }, | 797 | { 0x1b9400, 14, RI_E2E3E3B0_OFFLINE }, |
| 804 | { 0x1b943c, 19, RI_E2E3E3B0_ONLINE }, | 798 | { 0x1b943c, 19, RI_E2E3E3B0_OFFLINE }, |
| 805 | { 0x1b9490, 10, RI_E2E3E3B0_ONLINE }, | 799 | { 0x1b9490, 10, RI_E2E3E3B0_OFFLINE }, |
| 806 | { 0x1c0000, 2, RI_ALL_ONLINE }, | 800 | { 0x1c0000, 2, RI_ALL_ONLINE }, |
| 807 | { 0x200000, 65, RI_ALL_ONLINE }, | 801 | { 0x200000, 65, RI_ALL_ONLINE }, |
| 808 | { 0x20014c, 2, RI_E1HE2E3E3B0_ONLINE }, | 802 | { 0x20014c, 2, RI_E1HE2E3E3B0_ONLINE }, |
| @@ -814,7 +808,6 @@ static const struct reg_addr reg_addrs[] = { | |||
| 814 | { 0x200398, 1, RI_E2E3E3B0_ONLINE }, | 808 | { 0x200398, 1, RI_E2E3E3B0_ONLINE }, |
| 815 | { 0x2003a0, 1, RI_E2E3E3B0_ONLINE }, | 809 | { 0x2003a0, 1, RI_E2E3E3B0_ONLINE }, |
| 816 | { 0x2003a8, 2, RI_E2E3E3B0_ONLINE }, | 810 | { 0x2003a8, 2, RI_E2E3E3B0_ONLINE }, |
| 817 | { 0x200400, 1, RI_ALL_ONLINE }, | ||
| 818 | { 0x200404, 255, RI_E1E1H_OFFLINE }, | 811 | { 0x200404, 255, RI_E1E1H_OFFLINE }, |
| 819 | { 0x202000, 4, RI_ALL_ONLINE }, | 812 | { 0x202000, 4, RI_ALL_ONLINE }, |
| 820 | { 0x202010, 2044, RI_ALL_OFFLINE }, | 813 | { 0x202010, 2044, RI_ALL_OFFLINE }, |
| @@ -921,7 +914,6 @@ static const struct reg_addr reg_addrs[] = { | |||
| 921 | { 0x280398, 1, RI_E2E3E3B0_ONLINE }, | 914 | { 0x280398, 1, RI_E2E3E3B0_ONLINE }, |
| 922 | { 0x2803a0, 1, RI_E2E3E3B0_ONLINE }, | 915 | { 0x2803a0, 1, RI_E2E3E3B0_ONLINE }, |
| 923 | { 0x2803a8, 2, RI_E2E3E3B0_ONLINE }, | 916 | { 0x2803a8, 2, RI_E2E3E3B0_ONLINE }, |
| 924 | { 0x280400, 1, RI_ALL_ONLINE }, | ||
| 925 | { 0x280404, 255, RI_E1E1H_OFFLINE }, | 917 | { 0x280404, 255, RI_E1E1H_OFFLINE }, |
| 926 | { 0x282000, 4, RI_ALL_ONLINE }, | 918 | { 0x282000, 4, RI_ALL_ONLINE }, |
| 927 | { 0x282010, 2044, RI_ALL_OFFLINE }, | 919 | { 0x282010, 2044, RI_ALL_OFFLINE }, |
| @@ -1031,7 +1023,6 @@ static const struct reg_addr reg_addrs[] = { | |||
| 1031 | { 0x300398, 1, RI_E2E3E3B0_ONLINE }, | 1023 | { 0x300398, 1, RI_E2E3E3B0_ONLINE }, |
| 1032 | { 0x3003a0, 1, RI_E2E3E3B0_ONLINE }, | 1024 | { 0x3003a0, 1, RI_E2E3E3B0_ONLINE }, |
| 1033 | { 0x3003a8, 2, RI_E2E3E3B0_ONLINE }, | 1025 | { 0x3003a8, 2, RI_E2E3E3B0_ONLINE }, |
| 1034 | { 0x300400, 1, RI_ALL_ONLINE }, | ||
| 1035 | { 0x300404, 255, RI_E1E1H_OFFLINE }, | 1026 | { 0x300404, 255, RI_E1E1H_OFFLINE }, |
| 1036 | { 0x302000, 4, RI_ALL_ONLINE }, | 1027 | { 0x302000, 4, RI_ALL_ONLINE }, |
| 1037 | { 0x302010, 2044, RI_ALL_OFFLINE }, | 1028 | { 0x302010, 2044, RI_ALL_OFFLINE }, |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index c37a68d68090..ebf40cd7aa10 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | |||
| @@ -775,7 +775,7 @@ static void bnx2x_get_regs(struct net_device *dev, | |||
| 775 | struct bnx2x *bp = netdev_priv(dev); | 775 | struct bnx2x *bp = netdev_priv(dev); |
| 776 | struct dump_hdr dump_hdr = {0}; | 776 | struct dump_hdr dump_hdr = {0}; |
| 777 | 777 | ||
| 778 | regs->version = 0; | 778 | regs->version = 1; |
| 779 | memset(p, 0, regs->len); | 779 | memset(p, 0, regs->len); |
| 780 | 780 | ||
| 781 | if (!netif_running(bp->dev)) | 781 | if (!netif_running(bp->dev)) |
| @@ -1587,6 +1587,12 @@ static int bnx2x_set_pauseparam(struct net_device *dev, | |||
| 1587 | bp->link_params.req_flow_ctrl[cfg_idx] = | 1587 | bp->link_params.req_flow_ctrl[cfg_idx] = |
| 1588 | BNX2X_FLOW_CTRL_AUTO; | 1588 | BNX2X_FLOW_CTRL_AUTO; |
| 1589 | } | 1589 | } |
| 1590 | bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_NONE; | ||
| 1591 | if (epause->rx_pause) | ||
| 1592 | bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_RX; | ||
| 1593 | |||
| 1594 | if (epause->tx_pause) | ||
| 1595 | bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_TX; | ||
| 1590 | } | 1596 | } |
| 1591 | 1597 | ||
| 1592 | DP(BNX2X_MSG_ETHTOOL, | 1598 | DP(BNX2X_MSG_ETHTOOL, |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index f4beb46c4709..b046beb435b2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | |||
| @@ -2667,9 +2667,11 @@ int bnx2x_update_pfc(struct link_params *params, | |||
| 2667 | return bnx2x_status; | 2667 | return bnx2x_status; |
| 2668 | 2668 | ||
| 2669 | DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n"); | 2669 | DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n"); |
| 2670 | if (CHIP_IS_E3(bp)) | 2670 | |
| 2671 | bnx2x_update_pfc_xmac(params, vars, 0); | 2671 | if (CHIP_IS_E3(bp)) { |
| 2672 | else { | 2672 | if (vars->mac_type == MAC_TYPE_XMAC) |
| 2673 | bnx2x_update_pfc_xmac(params, vars, 0); | ||
| 2674 | } else { | ||
| 2673 | val = REG_RD(bp, MISC_REG_RESET_REG_2); | 2675 | val = REG_RD(bp, MISC_REG_RESET_REG_2); |
| 2674 | if ((val & | 2676 | if ((val & |
| 2675 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) | 2677 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) |
| @@ -5432,7 +5434,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |||
| 5432 | switch (speed_mask) { | 5434 | switch (speed_mask) { |
| 5433 | case GP_STATUS_10M: | 5435 | case GP_STATUS_10M: |
| 5434 | vars->line_speed = SPEED_10; | 5436 | vars->line_speed = SPEED_10; |
| 5435 | if (vars->duplex == DUPLEX_FULL) | 5437 | if (is_duplex == DUPLEX_FULL) |
| 5436 | vars->link_status |= LINK_10TFD; | 5438 | vars->link_status |= LINK_10TFD; |
| 5437 | else | 5439 | else |
| 5438 | vars->link_status |= LINK_10THD; | 5440 | vars->link_status |= LINK_10THD; |
| @@ -5440,7 +5442,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |||
| 5440 | 5442 | ||
| 5441 | case GP_STATUS_100M: | 5443 | case GP_STATUS_100M: |
| 5442 | vars->line_speed = SPEED_100; | 5444 | vars->line_speed = SPEED_100; |
| 5443 | if (vars->duplex == DUPLEX_FULL) | 5445 | if (is_duplex == DUPLEX_FULL) |
| 5444 | vars->link_status |= LINK_100TXFD; | 5446 | vars->link_status |= LINK_100TXFD; |
| 5445 | else | 5447 | else |
| 5446 | vars->link_status |= LINK_100TXHD; | 5448 | vars->link_status |= LINK_100TXHD; |
| @@ -5449,7 +5451,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |||
| 5449 | case GP_STATUS_1G: | 5451 | case GP_STATUS_1G: |
| 5450 | case GP_STATUS_1G_KX: | 5452 | case GP_STATUS_1G_KX: |
| 5451 | vars->line_speed = SPEED_1000; | 5453 | vars->line_speed = SPEED_1000; |
| 5452 | if (vars->duplex == DUPLEX_FULL) | 5454 | if (is_duplex == DUPLEX_FULL) |
| 5453 | vars->link_status |= LINK_1000TFD; | 5455 | vars->link_status |= LINK_1000TFD; |
| 5454 | else | 5456 | else |
| 5455 | vars->link_status |= LINK_1000THD; | 5457 | vars->link_status |= LINK_1000THD; |
| @@ -5457,7 +5459,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |||
| 5457 | 5459 | ||
| 5458 | case GP_STATUS_2_5G: | 5460 | case GP_STATUS_2_5G: |
| 5459 | vars->line_speed = SPEED_2500; | 5461 | vars->line_speed = SPEED_2500; |
| 5460 | if (vars->duplex == DUPLEX_FULL) | 5462 | if (is_duplex == DUPLEX_FULL) |
| 5461 | vars->link_status |= LINK_2500TFD; | 5463 | vars->link_status |= LINK_2500TFD; |
| 5462 | else | 5464 | else |
| 5463 | vars->link_status |= LINK_2500THD; | 5465 | vars->link_status |= LINK_2500THD; |
| @@ -5531,6 +5533,7 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, | |||
| 5531 | 5533 | ||
| 5532 | if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { | 5534 | if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { |
| 5533 | if (SINGLE_MEDIA_DIRECT(params)) { | 5535 | if (SINGLE_MEDIA_DIRECT(params)) { |
| 5536 | vars->duplex = duplex; | ||
| 5534 | bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status); | 5537 | bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status); |
| 5535 | if (phy->req_line_speed == SPEED_AUTO_NEG) | 5538 | if (phy->req_line_speed == SPEED_AUTO_NEG) |
| 5536 | bnx2x_xgxs_an_resolve(phy, params, vars, | 5539 | bnx2x_xgxs_an_resolve(phy, params, vars, |
| @@ -5625,6 +5628,7 @@ static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy, | |||
| 5625 | LINK_STATUS_PARALLEL_DETECTION_USED; | 5628 | LINK_STATUS_PARALLEL_DETECTION_USED; |
| 5626 | } | 5629 | } |
| 5627 | bnx2x_ext_phy_resolve_fc(phy, params, vars); | 5630 | bnx2x_ext_phy_resolve_fc(phy, params, vars); |
| 5631 | vars->duplex = duplex; | ||
| 5628 | } | 5632 | } |
| 5629 | } | 5633 | } |
| 5630 | 5634 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 21054987257a..211753e01f81 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
| @@ -7561,8 +7561,14 @@ int bnx2x_set_mac_one(struct bnx2x *bp, u8 *mac, | |||
| 7561 | } | 7561 | } |
| 7562 | 7562 | ||
| 7563 | rc = bnx2x_config_vlan_mac(bp, &ramrod_param); | 7563 | rc = bnx2x_config_vlan_mac(bp, &ramrod_param); |
| 7564 | if (rc < 0) | 7564 | |
| 7565 | if (rc == -EEXIST) { | ||
| 7566 | DP(BNX2X_MSG_SP, "Failed to schedule ADD operations: %d\n", rc); | ||
| 7567 | /* do not treat adding same MAC as error */ | ||
| 7568 | rc = 0; | ||
| 7569 | } else if (rc < 0) | ||
| 7565 | BNX2X_ERR("%s MAC failed\n", (set ? "Set" : "Del")); | 7570 | BNX2X_ERR("%s MAC failed\n", (set ? "Set" : "Del")); |
| 7571 | |||
| 7566 | return rc; | 7572 | return rc; |
| 7567 | } | 7573 | } |
| 7568 | 7574 | ||
| @@ -10294,13 +10300,11 @@ static void __devinit bnx2x_get_fcoe_info(struct bnx2x *bp) | |||
| 10294 | dev_info.port_hw_config[port]. | 10300 | dev_info.port_hw_config[port]. |
| 10295 | fcoe_wwn_node_name_lower); | 10301 | fcoe_wwn_node_name_lower); |
| 10296 | } else if (!IS_MF_SD(bp)) { | 10302 | } else if (!IS_MF_SD(bp)) { |
| 10297 | u32 cfg = MF_CFG_RD(bp, func_ext_config[func].func_cfg); | ||
| 10298 | |||
| 10299 | /* | 10303 | /* |
| 10300 | * Read the WWN info only if the FCoE feature is enabled for | 10304 | * Read the WWN info only if the FCoE feature is enabled for |
| 10301 | * this function. | 10305 | * this function. |
| 10302 | */ | 10306 | */ |
| 10303 | if (cfg & MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD) | 10307 | if (BNX2X_MF_EXT_PROTOCOL_FCOE(bp) && !CHIP_IS_E1x(bp)) |
| 10304 | bnx2x_get_ext_wwn_info(bp, func); | 10308 | bnx2x_get_ext_wwn_info(bp, func); |
| 10305 | 10309 | ||
| 10306 | } else if (IS_MF_FCOE_SD(bp)) | 10310 | } else if (IS_MF_FCOE_SD(bp)) |
| @@ -11073,7 +11077,14 @@ static int bnx2x_set_uc_list(struct bnx2x *bp) | |||
| 11073 | netdev_for_each_uc_addr(ha, dev) { | 11077 | netdev_for_each_uc_addr(ha, dev) { |
| 11074 | rc = bnx2x_set_mac_one(bp, bnx2x_uc_addr(ha), mac_obj, true, | 11078 | rc = bnx2x_set_mac_one(bp, bnx2x_uc_addr(ha), mac_obj, true, |
| 11075 | BNX2X_UC_LIST_MAC, &ramrod_flags); | 11079 | BNX2X_UC_LIST_MAC, &ramrod_flags); |
| 11076 | if (rc < 0) { | 11080 | if (rc == -EEXIST) { |
| 11081 | DP(BNX2X_MSG_SP, | ||
| 11082 | "Failed to schedule ADD operations: %d\n", rc); | ||
| 11083 | /* do not treat adding same MAC as error */ | ||
| 11084 | rc = 0; | ||
| 11085 | |||
| 11086 | } else if (rc < 0) { | ||
| 11087 | |||
| 11077 | BNX2X_ERR("Failed to schedule ADD operations: %d\n", | 11088 | BNX2X_ERR("Failed to schedule ADD operations: %d\n", |
| 11078 | rc); | 11089 | rc); |
| 11079 | return rc; | 11090 | return rc; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index 332db64dd5be..a1d0446b39b3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c | |||
| @@ -101,6 +101,11 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp) | |||
| 101 | if (CHIP_REV_IS_SLOW(bp)) | 101 | if (CHIP_REV_IS_SLOW(bp)) |
| 102 | return; | 102 | return; |
| 103 | 103 | ||
| 104 | /* Update MCP's statistics if possible */ | ||
| 105 | if (bp->func_stx) | ||
| 106 | memcpy(bnx2x_sp(bp, func_stats), &bp->func_stats, | ||
| 107 | sizeof(bp->func_stats)); | ||
| 108 | |||
| 104 | /* loader */ | 109 | /* loader */ |
| 105 | if (bp->executer_idx) { | 110 | if (bp->executer_idx) { |
| 106 | int loader_idx = PMF_DMAE_C(bp); | 111 | int loader_idx = PMF_DMAE_C(bp); |
| @@ -128,8 +133,6 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp) | |||
| 128 | 133 | ||
| 129 | } else if (bp->func_stx) { | 134 | } else if (bp->func_stx) { |
| 130 | *stats_comp = 0; | 135 | *stats_comp = 0; |
| 131 | memcpy(bnx2x_sp(bp, func_stats), &bp->func_stats, | ||
| 132 | sizeof(bp->func_stats)); | ||
| 133 | bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp)); | 136 | bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp)); |
| 134 | } | 137 | } |
| 135 | } | 138 | } |
| @@ -1151,9 +1154,11 @@ static void bnx2x_stats_update(struct bnx2x *bp) | |||
| 1151 | if (bp->port.pmf) | 1154 | if (bp->port.pmf) |
| 1152 | bnx2x_hw_stats_update(bp); | 1155 | bnx2x_hw_stats_update(bp); |
| 1153 | 1156 | ||
| 1154 | if (bnx2x_storm_stats_update(bp) && (bp->stats_pending++ == 3)) { | 1157 | if (bnx2x_storm_stats_update(bp)) { |
| 1155 | BNX2X_ERR("storm stats were not updated for 3 times\n"); | 1158 | if (bp->stats_pending++ == 3) { |
| 1156 | bnx2x_panic(); | 1159 | BNX2X_ERR("storm stats were not updated for 3 times\n"); |
| 1160 | bnx2x_panic(); | ||
| 1161 | } | ||
| 1157 | return; | 1162 | return; |
| 1158 | } | 1163 | } |
| 1159 | 1164 | ||
diff --git a/drivers/net/ethernet/i825xx/znet.c b/drivers/net/ethernet/i825xx/znet.c index bd1f1ef91e19..ba4e0cea3506 100644 --- a/drivers/net/ethernet/i825xx/znet.c +++ b/drivers/net/ethernet/i825xx/znet.c | |||
| @@ -139,8 +139,11 @@ struct znet_private { | |||
| 139 | /* Only one can be built-in;-> */ | 139 | /* Only one can be built-in;-> */ |
| 140 | static struct net_device *znet_dev; | 140 | static struct net_device *znet_dev; |
| 141 | 141 | ||
| 142 | #define NETIDBLK_MAGIC "NETIDBLK" | ||
| 143 | #define NETIDBLK_MAGIC_SIZE 8 | ||
| 144 | |||
| 142 | struct netidblk { | 145 | struct netidblk { |
| 143 | char magic[8]; /* The magic number (string) "NETIDBLK" */ | 146 | char magic[NETIDBLK_MAGIC_SIZE]; /* The magic number (string) "NETIDBLK" */ |
| 144 | unsigned char netid[8]; /* The physical station address */ | 147 | unsigned char netid[8]; /* The physical station address */ |
| 145 | char nettype, globalopt; | 148 | char nettype, globalopt; |
| 146 | char vendor[8]; /* The machine vendor and product name. */ | 149 | char vendor[8]; /* The machine vendor and product name. */ |
| @@ -373,14 +376,16 @@ static int __init znet_probe (void) | |||
| 373 | struct znet_private *znet; | 376 | struct znet_private *znet; |
| 374 | struct net_device *dev; | 377 | struct net_device *dev; |
| 375 | char *p; | 378 | char *p; |
| 379 | char *plast = phys_to_virt(0x100000 - NETIDBLK_MAGIC_SIZE); | ||
| 376 | int err = -ENOMEM; | 380 | int err = -ENOMEM; |
| 377 | 381 | ||
| 378 | /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */ | 382 | /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */ |
| 379 | for(p = (char *)phys_to_virt(0xf0000); p < (char *)phys_to_virt(0x100000); p++) | 383 | for(p = (char *)phys_to_virt(0xf0000); p <= plast; p++) |
| 380 | if (*p == 'N' && strncmp(p, "NETIDBLK", 8) == 0) | 384 | if (*p == 'N' && |
| 385 | strncmp(p, NETIDBLK_MAGIC, NETIDBLK_MAGIC_SIZE) == 0) | ||
| 381 | break; | 386 | break; |
| 382 | 387 | ||
| 383 | if (p >= (char *)phys_to_virt(0x100000)) { | 388 | if (p > plast) { |
| 384 | if (znet_debug > 1) | 389 | if (znet_debug > 1) |
| 385 | printk(KERN_INFO "No Z-Note ethernet adaptor found.\n"); | 390 | printk(KERN_INFO "No Z-Note ethernet adaptor found.\n"); |
| 386 | return -ENODEV; | 391 | return -ENODEV; |
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index 9010cea68bc3..b68d28a130e6 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c | |||
| @@ -472,14 +472,9 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) | |||
| 472 | } | 472 | } |
| 473 | 473 | ||
| 474 | if (adapter->rx_queue.queue_addr != NULL) { | 474 | if (adapter->rx_queue.queue_addr != NULL) { |
| 475 | if (!dma_mapping_error(dev, adapter->rx_queue.queue_dma)) { | 475 | dma_free_coherent(dev, adapter->rx_queue.queue_len, |
| 476 | dma_unmap_single(dev, | 476 | adapter->rx_queue.queue_addr, |
| 477 | adapter->rx_queue.queue_dma, | 477 | adapter->rx_queue.queue_dma); |
| 478 | adapter->rx_queue.queue_len, | ||
| 479 | DMA_BIDIRECTIONAL); | ||
| 480 | adapter->rx_queue.queue_dma = DMA_ERROR_CODE; | ||
| 481 | } | ||
| 482 | kfree(adapter->rx_queue.queue_addr); | ||
| 483 | adapter->rx_queue.queue_addr = NULL; | 478 | adapter->rx_queue.queue_addr = NULL; |
| 484 | } | 479 | } |
| 485 | 480 | ||
| @@ -556,10 +551,13 @@ static int ibmveth_open(struct net_device *netdev) | |||
| 556 | goto err_out; | 551 | goto err_out; |
| 557 | } | 552 | } |
| 558 | 553 | ||
| 554 | dev = &adapter->vdev->dev; | ||
| 555 | |||
| 559 | adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) * | 556 | adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) * |
| 560 | rxq_entries; | 557 | rxq_entries; |
| 561 | adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len, | 558 | adapter->rx_queue.queue_addr = |
| 562 | GFP_KERNEL); | 559 | dma_alloc_coherent(dev, adapter->rx_queue.queue_len, |
| 560 | &adapter->rx_queue.queue_dma, GFP_KERNEL); | ||
| 563 | 561 | ||
| 564 | if (!adapter->rx_queue.queue_addr) { | 562 | if (!adapter->rx_queue.queue_addr) { |
| 565 | netdev_err(netdev, "unable to allocate rx queue pages\n"); | 563 | netdev_err(netdev, "unable to allocate rx queue pages\n"); |
| @@ -567,19 +565,13 @@ static int ibmveth_open(struct net_device *netdev) | |||
| 567 | goto err_out; | 565 | goto err_out; |
| 568 | } | 566 | } |
| 569 | 567 | ||
| 570 | dev = &adapter->vdev->dev; | ||
| 571 | |||
| 572 | adapter->buffer_list_dma = dma_map_single(dev, | 568 | adapter->buffer_list_dma = dma_map_single(dev, |
| 573 | adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL); | 569 | adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL); |
| 574 | adapter->filter_list_dma = dma_map_single(dev, | 570 | adapter->filter_list_dma = dma_map_single(dev, |
| 575 | adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL); | 571 | adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL); |
| 576 | adapter->rx_queue.queue_dma = dma_map_single(dev, | ||
| 577 | adapter->rx_queue.queue_addr, | ||
| 578 | adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL); | ||
| 579 | 572 | ||
| 580 | if ((dma_mapping_error(dev, adapter->buffer_list_dma)) || | 573 | if ((dma_mapping_error(dev, adapter->buffer_list_dma)) || |
| 581 | (dma_mapping_error(dev, adapter->filter_list_dma)) || | 574 | (dma_mapping_error(dev, adapter->filter_list_dma))) { |
| 582 | (dma_mapping_error(dev, adapter->rx_queue.queue_dma))) { | ||
| 583 | netdev_err(netdev, "unable to map filter or buffer list " | 575 | netdev_err(netdev, "unable to map filter or buffer list " |
| 584 | "pages\n"); | 576 | "pages\n"); |
| 585 | rc = -ENOMEM; | 577 | rc = -ENOMEM; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 827b72dfce99..2f816c6aed72 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
| @@ -1234,13 +1234,13 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
| 1234 | mlx4_info(dev, "non-primary physical function, skipping.\n"); | 1234 | mlx4_info(dev, "non-primary physical function, skipping.\n"); |
| 1235 | else | 1235 | else |
| 1236 | mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); | 1236 | mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); |
| 1237 | goto unmap_bf; | 1237 | return err; |
| 1238 | } | 1238 | } |
| 1239 | 1239 | ||
| 1240 | err = mlx4_load_fw(dev); | 1240 | err = mlx4_load_fw(dev); |
| 1241 | if (err) { | 1241 | if (err) { |
| 1242 | mlx4_err(dev, "Failed to start FW, aborting.\n"); | 1242 | mlx4_err(dev, "Failed to start FW, aborting.\n"); |
| 1243 | goto unmap_bf; | 1243 | return err; |
| 1244 | } | 1244 | } |
| 1245 | 1245 | ||
| 1246 | mlx4_cfg.log_pg_sz_m = 1; | 1246 | mlx4_cfg.log_pg_sz_m = 1; |
| @@ -1304,7 +1304,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
| 1304 | err = mlx4_init_slave(dev); | 1304 | err = mlx4_init_slave(dev); |
| 1305 | if (err) { | 1305 | if (err) { |
| 1306 | mlx4_err(dev, "Failed to initialize slave\n"); | 1306 | mlx4_err(dev, "Failed to initialize slave\n"); |
| 1307 | goto unmap_bf; | 1307 | return err; |
| 1308 | } | 1308 | } |
| 1309 | 1309 | ||
| 1310 | err = mlx4_slave_cap(dev); | 1310 | err = mlx4_slave_cap(dev); |
| @@ -1324,7 +1324,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
| 1324 | err = mlx4_QUERY_ADAPTER(dev, &adapter); | 1324 | err = mlx4_QUERY_ADAPTER(dev, &adapter); |
| 1325 | if (err) { | 1325 | if (err) { |
| 1326 | mlx4_err(dev, "QUERY_ADAPTER command failed, aborting.\n"); | 1326 | mlx4_err(dev, "QUERY_ADAPTER command failed, aborting.\n"); |
| 1327 | goto err_close; | 1327 | goto unmap_bf; |
| 1328 | } | 1328 | } |
| 1329 | 1329 | ||
| 1330 | priv->eq_table.inta_pin = adapter.inta_pin; | 1330 | priv->eq_table.inta_pin = adapter.inta_pin; |
| @@ -1332,6 +1332,9 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
| 1332 | 1332 | ||
| 1333 | return 0; | 1333 | return 0; |
| 1334 | 1334 | ||
| 1335 | unmap_bf: | ||
| 1336 | unmap_bf_area(dev); | ||
| 1337 | |||
| 1335 | err_close: | 1338 | err_close: |
| 1336 | mlx4_close_hca(dev); | 1339 | mlx4_close_hca(dev); |
| 1337 | 1340 | ||
| @@ -1344,8 +1347,6 @@ err_stop_fw: | |||
| 1344 | mlx4_UNMAP_FA(dev); | 1347 | mlx4_UNMAP_FA(dev); |
| 1345 | mlx4_free_icm(dev, priv->fw.fw_icm, 0); | 1348 | mlx4_free_icm(dev, priv->fw.fw_icm, 0); |
| 1346 | } | 1349 | } |
| 1347 | unmap_bf: | ||
| 1348 | unmap_bf_area(dev); | ||
| 1349 | return err; | 1350 | return err; |
| 1350 | } | 1351 | } |
| 1351 | 1352 | ||
| @@ -1996,7 +1997,8 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 1996 | } | 1997 | } |
| 1997 | 1998 | ||
| 1998 | slave_start: | 1999 | slave_start: |
| 1999 | if (mlx4_cmd_init(dev)) { | 2000 | err = mlx4_cmd_init(dev); |
| 2001 | if (err) { | ||
| 2000 | mlx4_err(dev, "Failed to init command interface, aborting.\n"); | 2002 | mlx4_err(dev, "Failed to init command interface, aborting.\n"); |
| 2001 | goto err_sriov; | 2003 | goto err_sriov; |
| 2002 | } | 2004 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index a018ea2a43de..e151c21baf2b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c | |||
| @@ -137,11 +137,11 @@ static int mlx4_GID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, | |||
| 137 | return err; | 137 | return err; |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 pf_num, | 140 | static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 port, |
| 141 | enum mlx4_steer_type steer, | 141 | enum mlx4_steer_type steer, |
| 142 | u32 qpn) | 142 | u32 qpn) |
| 143 | { | 143 | { |
| 144 | struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[pf_num]; | 144 | struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[port - 1]; |
| 145 | struct mlx4_promisc_qp *pqp; | 145 | struct mlx4_promisc_qp *pqp; |
| 146 | 146 | ||
| 147 | list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { | 147 | list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { |
| @@ -182,7 +182,7 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 port, | |||
| 182 | /* If the given qpn is also a promisc qp, | 182 | /* If the given qpn is also a promisc qp, |
| 183 | * it should be inserted to duplicates list | 183 | * it should be inserted to duplicates list |
| 184 | */ | 184 | */ |
| 185 | pqp = get_promisc_qp(dev, 0, steer, qpn); | 185 | pqp = get_promisc_qp(dev, port, steer, qpn); |
| 186 | if (pqp) { | 186 | if (pqp) { |
| 187 | dqp = kmalloc(sizeof *dqp, GFP_KERNEL); | 187 | dqp = kmalloc(sizeof *dqp, GFP_KERNEL); |
| 188 | if (!dqp) { | 188 | if (!dqp) { |
| @@ -256,7 +256,7 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 port, | |||
| 256 | 256 | ||
| 257 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 257 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
| 258 | 258 | ||
| 259 | pqp = get_promisc_qp(dev, 0, steer, qpn); | 259 | pqp = get_promisc_qp(dev, port, steer, qpn); |
| 260 | if (!pqp) | 260 | if (!pqp) |
| 261 | return 0; /* nothing to do */ | 261 | return 0; /* nothing to do */ |
| 262 | 262 | ||
| @@ -302,7 +302,7 @@ static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port, | |||
| 302 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 302 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
| 303 | 303 | ||
| 304 | /* if qp is not promisc, it cannot be duplicated */ | 304 | /* if qp is not promisc, it cannot be duplicated */ |
| 305 | if (!get_promisc_qp(dev, 0, steer, qpn)) | 305 | if (!get_promisc_qp(dev, port, steer, qpn)) |
| 306 | return false; | 306 | return false; |
| 307 | 307 | ||
| 308 | /* The qp is promisc qp so it is a duplicate on this index | 308 | /* The qp is promisc qp so it is a duplicate on this index |
| @@ -352,7 +352,7 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port, | |||
| 352 | members_count = be32_to_cpu(mgm->members_count) & 0xffffff; | 352 | members_count = be32_to_cpu(mgm->members_count) & 0xffffff; |
| 353 | for (i = 0; i < members_count; i++) { | 353 | for (i = 0; i < members_count; i++) { |
| 354 | qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK; | 354 | qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK; |
| 355 | if (!get_promisc_qp(dev, 0, steer, qpn) && qpn != tqpn) { | 355 | if (!get_promisc_qp(dev, port, steer, qpn) && qpn != tqpn) { |
| 356 | /* the qp is not promisc, the entry can't be removed */ | 356 | /* the qp is not promisc, the entry can't be removed */ |
| 357 | goto out; | 357 | goto out; |
| 358 | } | 358 | } |
| @@ -398,7 +398,7 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port, | |||
| 398 | 398 | ||
| 399 | mutex_lock(&priv->mcg_table.mutex); | 399 | mutex_lock(&priv->mcg_table.mutex); |
| 400 | 400 | ||
| 401 | if (get_promisc_qp(dev, 0, steer, qpn)) { | 401 | if (get_promisc_qp(dev, port, steer, qpn)) { |
| 402 | err = 0; /* Noting to do, already exists */ | 402 | err = 0; /* Noting to do, already exists */ |
| 403 | goto out_mutex; | 403 | goto out_mutex; |
| 404 | } | 404 | } |
| @@ -503,7 +503,7 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port, | |||
| 503 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 503 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
| 504 | mutex_lock(&priv->mcg_table.mutex); | 504 | mutex_lock(&priv->mcg_table.mutex); |
| 505 | 505 | ||
| 506 | pqp = get_promisc_qp(dev, 0, steer, qpn); | 506 | pqp = get_promisc_qp(dev, port, steer, qpn); |
| 507 | if (unlikely(!pqp)) { | 507 | if (unlikely(!pqp)) { |
| 508 | mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn); | 508 | mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn); |
| 509 | /* nothing to do */ | 509 | /* nothing to do */ |
| @@ -650,13 +650,6 @@ static int find_entry(struct mlx4_dev *dev, u8 port, | |||
| 650 | return err; | 650 | return err; |
| 651 | } | 651 | } |
| 652 | 652 | ||
| 653 | struct mlx4_net_trans_rule_hw_ctrl { | ||
| 654 | __be32 ctrl; | ||
| 655 | __be32 vf_vep_port; | ||
| 656 | __be32 qpn; | ||
| 657 | __be32 reserved; | ||
| 658 | }; | ||
| 659 | |||
| 660 | static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl, | 653 | static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl, |
| 661 | struct mlx4_net_trans_rule_hw_ctrl *hw) | 654 | struct mlx4_net_trans_rule_hw_ctrl *hw) |
| 662 | { | 655 | { |
| @@ -680,87 +673,18 @@ static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl, | |||
| 680 | hw->qpn = cpu_to_be32(ctrl->qpn); | 673 | hw->qpn = cpu_to_be32(ctrl->qpn); |
| 681 | } | 674 | } |
| 682 | 675 | ||
| 683 | struct mlx4_net_trans_rule_hw_ib { | 676 | const u16 __sw_id_hw[] = { |
| 684 | u8 size; | 677 | [MLX4_NET_TRANS_RULE_ID_ETH] = 0xE001, |
| 685 | u8 rsvd1; | 678 | [MLX4_NET_TRANS_RULE_ID_IB] = 0xE005, |
| 686 | __be16 id; | 679 | [MLX4_NET_TRANS_RULE_ID_IPV6] = 0xE003, |
| 687 | u32 rsvd2; | 680 | [MLX4_NET_TRANS_RULE_ID_IPV4] = 0xE002, |
| 688 | __be32 qpn; | 681 | [MLX4_NET_TRANS_RULE_ID_TCP] = 0xE004, |
| 689 | __be32 qpn_mask; | 682 | [MLX4_NET_TRANS_RULE_ID_UDP] = 0xE006 |
| 690 | u8 dst_gid[16]; | ||
| 691 | u8 dst_gid_msk[16]; | ||
| 692 | } __packed; | ||
| 693 | |||
| 694 | struct mlx4_net_trans_rule_hw_eth { | ||
| 695 | u8 size; | ||
| 696 | u8 rsvd; | ||
| 697 | __be16 id; | ||
| 698 | u8 rsvd1[6]; | ||
| 699 | u8 dst_mac[6]; | ||
| 700 | u16 rsvd2; | ||
| 701 | u8 dst_mac_msk[6]; | ||
| 702 | u16 rsvd3; | ||
| 703 | u8 src_mac[6]; | ||
| 704 | u16 rsvd4; | ||
| 705 | u8 src_mac_msk[6]; | ||
| 706 | u8 rsvd5; | ||
| 707 | u8 ether_type_enable; | ||
| 708 | __be16 ether_type; | ||
| 709 | __be16 vlan_id_msk; | ||
| 710 | __be16 vlan_id; | ||
| 711 | } __packed; | ||
| 712 | |||
| 713 | struct mlx4_net_trans_rule_hw_tcp_udp { | ||
| 714 | u8 size; | ||
| 715 | u8 rsvd; | ||
| 716 | __be16 id; | ||
| 717 | __be16 rsvd1[3]; | ||
| 718 | __be16 dst_port; | ||
| 719 | __be16 rsvd2; | ||
| 720 | __be16 dst_port_msk; | ||
| 721 | __be16 rsvd3; | ||
| 722 | __be16 src_port; | ||
| 723 | __be16 rsvd4; | ||
| 724 | __be16 src_port_msk; | ||
| 725 | } __packed; | ||
| 726 | |||
| 727 | struct mlx4_net_trans_rule_hw_ipv4 { | ||
| 728 | u8 size; | ||
| 729 | u8 rsvd; | ||
| 730 | __be16 id; | ||
| 731 | __be32 rsvd1; | ||
| 732 | __be32 dst_ip; | ||
| 733 | __be32 dst_ip_msk; | ||
| 734 | __be32 src_ip; | ||
| 735 | __be32 src_ip_msk; | ||
| 736 | } __packed; | ||
| 737 | |||
| 738 | struct _rule_hw { | ||
| 739 | union { | ||
| 740 | struct { | ||
| 741 | u8 size; | ||
| 742 | u8 rsvd; | ||
| 743 | __be16 id; | ||
| 744 | }; | ||
| 745 | struct mlx4_net_trans_rule_hw_eth eth; | ||
| 746 | struct mlx4_net_trans_rule_hw_ib ib; | ||
| 747 | struct mlx4_net_trans_rule_hw_ipv4 ipv4; | ||
| 748 | struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp; | ||
| 749 | }; | ||
| 750 | }; | 683 | }; |
| 751 | 684 | ||
| 752 | static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec, | 685 | static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec, |
| 753 | struct _rule_hw *rule_hw) | 686 | struct _rule_hw *rule_hw) |
| 754 | { | 687 | { |
| 755 | static const u16 __sw_id_hw[] = { | ||
| 756 | [MLX4_NET_TRANS_RULE_ID_ETH] = 0xE001, | ||
| 757 | [MLX4_NET_TRANS_RULE_ID_IB] = 0xE005, | ||
| 758 | [MLX4_NET_TRANS_RULE_ID_IPV6] = 0xE003, | ||
| 759 | [MLX4_NET_TRANS_RULE_ID_IPV4] = 0xE002, | ||
| 760 | [MLX4_NET_TRANS_RULE_ID_TCP] = 0xE004, | ||
| 761 | [MLX4_NET_TRANS_RULE_ID_UDP] = 0xE006 | ||
| 762 | }; | ||
| 763 | |||
| 764 | static const size_t __rule_hw_sz[] = { | 688 | static const size_t __rule_hw_sz[] = { |
| 765 | [MLX4_NET_TRANS_RULE_ID_ETH] = | 689 | [MLX4_NET_TRANS_RULE_ID_ETH] = |
| 766 | sizeof(struct mlx4_net_trans_rule_hw_eth), | 690 | sizeof(struct mlx4_net_trans_rule_hw_eth), |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 4d9df8f2a126..dba69d98734a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
| @@ -690,6 +690,82 @@ struct mlx4_steer { | |||
| 690 | struct list_head steer_entries[MLX4_NUM_STEERS]; | 690 | struct list_head steer_entries[MLX4_NUM_STEERS]; |
| 691 | }; | 691 | }; |
| 692 | 692 | ||
| 693 | struct mlx4_net_trans_rule_hw_ctrl { | ||
| 694 | __be32 ctrl; | ||
| 695 | __be32 vf_vep_port; | ||
| 696 | __be32 qpn; | ||
| 697 | __be32 reserved; | ||
| 698 | }; | ||
| 699 | |||
| 700 | struct mlx4_net_trans_rule_hw_ib { | ||
| 701 | u8 size; | ||
| 702 | u8 rsvd1; | ||
| 703 | __be16 id; | ||
| 704 | u32 rsvd2; | ||
| 705 | __be32 qpn; | ||
| 706 | __be32 qpn_mask; | ||
| 707 | u8 dst_gid[16]; | ||
| 708 | u8 dst_gid_msk[16]; | ||
| 709 | } __packed; | ||
| 710 | |||
| 711 | struct mlx4_net_trans_rule_hw_eth { | ||
| 712 | u8 size; | ||
| 713 | u8 rsvd; | ||
| 714 | __be16 id; | ||
| 715 | u8 rsvd1[6]; | ||
| 716 | u8 dst_mac[6]; | ||
| 717 | u16 rsvd2; | ||
| 718 | u8 dst_mac_msk[6]; | ||
| 719 | u16 rsvd3; | ||
| 720 | u8 src_mac[6]; | ||
| 721 | u16 rsvd4; | ||
| 722 | u8 src_mac_msk[6]; | ||
| 723 | u8 rsvd5; | ||
| 724 | u8 ether_type_enable; | ||
| 725 | __be16 ether_type; | ||
| 726 | __be16 vlan_id_msk; | ||
| 727 | __be16 vlan_id; | ||
| 728 | } __packed; | ||
| 729 | |||
| 730 | struct mlx4_net_trans_rule_hw_tcp_udp { | ||
| 731 | u8 size; | ||
| 732 | u8 rsvd; | ||
| 733 | __be16 id; | ||
| 734 | __be16 rsvd1[3]; | ||
| 735 | __be16 dst_port; | ||
| 736 | __be16 rsvd2; | ||
| 737 | __be16 dst_port_msk; | ||
| 738 | __be16 rsvd3; | ||
| 739 | __be16 src_port; | ||
| 740 | __be16 rsvd4; | ||
| 741 | __be16 src_port_msk; | ||
| 742 | } __packed; | ||
| 743 | |||
| 744 | struct mlx4_net_trans_rule_hw_ipv4 { | ||
| 745 | u8 size; | ||
| 746 | u8 rsvd; | ||
| 747 | __be16 id; | ||
| 748 | __be32 rsvd1; | ||
| 749 | __be32 dst_ip; | ||
| 750 | __be32 dst_ip_msk; | ||
| 751 | __be32 src_ip; | ||
| 752 | __be32 src_ip_msk; | ||
| 753 | } __packed; | ||
| 754 | |||
| 755 | struct _rule_hw { | ||
| 756 | union { | ||
| 757 | struct { | ||
| 758 | u8 size; | ||
| 759 | u8 rsvd; | ||
| 760 | __be16 id; | ||
| 761 | }; | ||
| 762 | struct mlx4_net_trans_rule_hw_eth eth; | ||
| 763 | struct mlx4_net_trans_rule_hw_ib ib; | ||
| 764 | struct mlx4_net_trans_rule_hw_ipv4 ipv4; | ||
| 765 | struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp; | ||
| 766 | }; | ||
| 767 | }; | ||
| 768 | |||
| 693 | struct mlx4_priv { | 769 | struct mlx4_priv { |
| 694 | struct mlx4_dev dev; | 770 | struct mlx4_dev dev; |
| 695 | 771 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 94ceddd17ab2..293c9e820c49 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | #include <linux/mlx4/cmd.h> | 42 | #include <linux/mlx4/cmd.h> |
| 43 | #include <linux/mlx4/qp.h> | 43 | #include <linux/mlx4/qp.h> |
| 44 | #include <linux/if_ether.h> | 44 | #include <linux/if_ether.h> |
| 45 | #include <linux/etherdevice.h> | ||
| 45 | 46 | ||
| 46 | #include "mlx4.h" | 47 | #include "mlx4.h" |
| 47 | #include "fw.h" | 48 | #include "fw.h" |
| @@ -2776,18 +2777,133 @@ ex_put: | |||
| 2776 | return err; | 2777 | return err; |
| 2777 | } | 2778 | } |
| 2778 | 2779 | ||
| 2780 | /* | ||
| 2781 | * MAC validation for Flow Steering rules. | ||
| 2782 | * VF can attach rules only with a mac address which is assigned to it. | ||
| 2783 | */ | ||
| 2784 | static int validate_eth_header_mac(int slave, struct _rule_hw *eth_header, | ||
| 2785 | struct list_head *rlist) | ||
| 2786 | { | ||
| 2787 | struct mac_res *res, *tmp; | ||
| 2788 | __be64 be_mac; | ||
| 2789 | |||
| 2790 | /* make sure it isn't multicast or broadcast mac*/ | ||
| 2791 | if (!is_multicast_ether_addr(eth_header->eth.dst_mac) && | ||
| 2792 | !is_broadcast_ether_addr(eth_header->eth.dst_mac)) { | ||
| 2793 | list_for_each_entry_safe(res, tmp, rlist, list) { | ||
| 2794 | be_mac = cpu_to_be64(res->mac << 16); | ||
| 2795 | if (!memcmp(&be_mac, eth_header->eth.dst_mac, ETH_ALEN)) | ||
| 2796 | return 0; | ||
| 2797 | } | ||
| 2798 | pr_err("MAC %pM doesn't belong to VF %d, Steering rule rejected\n", | ||
| 2799 | eth_header->eth.dst_mac, slave); | ||
| 2800 | return -EINVAL; | ||
| 2801 | } | ||
| 2802 | return 0; | ||
| 2803 | } | ||
| 2804 | |||
| 2805 | /* | ||
| 2806 | * In case of missing eth header, append eth header with a MAC address | ||
| 2807 | * assigned to the VF. | ||
| 2808 | */ | ||
| 2809 | static int add_eth_header(struct mlx4_dev *dev, int slave, | ||
| 2810 | struct mlx4_cmd_mailbox *inbox, | ||
| 2811 | struct list_head *rlist, int header_id) | ||
| 2812 | { | ||
| 2813 | struct mac_res *res, *tmp; | ||
| 2814 | u8 port; | ||
| 2815 | struct mlx4_net_trans_rule_hw_ctrl *ctrl; | ||
| 2816 | struct mlx4_net_trans_rule_hw_eth *eth_header; | ||
| 2817 | struct mlx4_net_trans_rule_hw_ipv4 *ip_header; | ||
| 2818 | struct mlx4_net_trans_rule_hw_tcp_udp *l4_header; | ||
| 2819 | __be64 be_mac = 0; | ||
| 2820 | __be64 mac_msk = cpu_to_be64(MLX4_MAC_MASK << 16); | ||
| 2821 | |||
| 2822 | ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; | ||
| 2823 | port = be32_to_cpu(ctrl->vf_vep_port) & 0xff; | ||
| 2824 | eth_header = (struct mlx4_net_trans_rule_hw_eth *)(ctrl + 1); | ||
| 2825 | |||
| 2826 | /* Clear a space in the inbox for eth header */ | ||
| 2827 | switch (header_id) { | ||
| 2828 | case MLX4_NET_TRANS_RULE_ID_IPV4: | ||
| 2829 | ip_header = | ||
| 2830 | (struct mlx4_net_trans_rule_hw_ipv4 *)(eth_header + 1); | ||
| 2831 | memmove(ip_header, eth_header, | ||
| 2832 | sizeof(*ip_header) + sizeof(*l4_header)); | ||
| 2833 | break; | ||
| 2834 | case MLX4_NET_TRANS_RULE_ID_TCP: | ||
| 2835 | case MLX4_NET_TRANS_RULE_ID_UDP: | ||
| 2836 | l4_header = (struct mlx4_net_trans_rule_hw_tcp_udp *) | ||
| 2837 | (eth_header + 1); | ||
| 2838 | memmove(l4_header, eth_header, sizeof(*l4_header)); | ||
| 2839 | break; | ||
| 2840 | default: | ||
| 2841 | return -EINVAL; | ||
| 2842 | } | ||
| 2843 | list_for_each_entry_safe(res, tmp, rlist, list) { | ||
| 2844 | if (port == res->port) { | ||
| 2845 | be_mac = cpu_to_be64(res->mac << 16); | ||
| 2846 | break; | ||
| 2847 | } | ||
| 2848 | } | ||
| 2849 | if (!be_mac) { | ||
| 2850 | pr_err("Failed adding eth header to FS rule, Can't find matching MAC for port %d .\n", | ||
| 2851 | port); | ||
| 2852 | return -EINVAL; | ||
| 2853 | } | ||
| 2854 | |||
| 2855 | memset(eth_header, 0, sizeof(*eth_header)); | ||
| 2856 | eth_header->size = sizeof(*eth_header) >> 2; | ||
| 2857 | eth_header->id = cpu_to_be16(__sw_id_hw[MLX4_NET_TRANS_RULE_ID_ETH]); | ||
| 2858 | memcpy(eth_header->dst_mac, &be_mac, ETH_ALEN); | ||
| 2859 | memcpy(eth_header->dst_mac_msk, &mac_msk, ETH_ALEN); | ||
| 2860 | |||
| 2861 | return 0; | ||
| 2862 | |||
| 2863 | } | ||
| 2864 | |||
| 2779 | int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | 2865 | int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, |
| 2780 | struct mlx4_vhcr *vhcr, | 2866 | struct mlx4_vhcr *vhcr, |
| 2781 | struct mlx4_cmd_mailbox *inbox, | 2867 | struct mlx4_cmd_mailbox *inbox, |
| 2782 | struct mlx4_cmd_mailbox *outbox, | 2868 | struct mlx4_cmd_mailbox *outbox, |
| 2783 | struct mlx4_cmd_info *cmd) | 2869 | struct mlx4_cmd_info *cmd) |
| 2784 | { | 2870 | { |
| 2871 | |||
| 2872 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
| 2873 | struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; | ||
| 2874 | struct list_head *rlist = &tracker->slave_list[slave].res_list[RES_MAC]; | ||
| 2785 | int err; | 2875 | int err; |
| 2876 | struct mlx4_net_trans_rule_hw_ctrl *ctrl; | ||
| 2877 | struct _rule_hw *rule_header; | ||
| 2878 | int header_id; | ||
| 2786 | 2879 | ||
| 2787 | if (dev->caps.steering_mode != | 2880 | if (dev->caps.steering_mode != |
| 2788 | MLX4_STEERING_MODE_DEVICE_MANAGED) | 2881 | MLX4_STEERING_MODE_DEVICE_MANAGED) |
| 2789 | return -EOPNOTSUPP; | 2882 | return -EOPNOTSUPP; |
| 2790 | 2883 | ||
| 2884 | ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; | ||
| 2885 | rule_header = (struct _rule_hw *)(ctrl + 1); | ||
| 2886 | header_id = map_hw_to_sw_id(be16_to_cpu(rule_header->id)); | ||
| 2887 | |||
| 2888 | switch (header_id) { | ||
| 2889 | case MLX4_NET_TRANS_RULE_ID_ETH: | ||
| 2890 | if (validate_eth_header_mac(slave, rule_header, rlist)) | ||
| 2891 | return -EINVAL; | ||
| 2892 | break; | ||
| 2893 | case MLX4_NET_TRANS_RULE_ID_IPV4: | ||
| 2894 | case MLX4_NET_TRANS_RULE_ID_TCP: | ||
| 2895 | case MLX4_NET_TRANS_RULE_ID_UDP: | ||
| 2896 | pr_warn("Can't attach FS rule without L2 headers, adding L2 header.\n"); | ||
| 2897 | if (add_eth_header(dev, slave, inbox, rlist, header_id)) | ||
| 2898 | return -EINVAL; | ||
| 2899 | vhcr->in_modifier += | ||
| 2900 | sizeof(struct mlx4_net_trans_rule_hw_eth) >> 2; | ||
| 2901 | break; | ||
| 2902 | default: | ||
| 2903 | pr_err("Corrupted mailbox.\n"); | ||
| 2904 | return -EINVAL; | ||
| 2905 | } | ||
| 2906 | |||
| 2791 | err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param, | 2907 | err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param, |
| 2792 | vhcr->in_modifier, 0, | 2908 | vhcr->in_modifier, 0, |
| 2793 | MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, | 2909 | MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, |
diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c index bb8c8222122b..4d15bf413bdc 100644 --- a/drivers/net/ethernet/seeq/sgiseeq.c +++ b/drivers/net/ethernet/seeq/sgiseeq.c | |||
| @@ -751,6 +751,7 @@ static int __devinit sgiseeq_probe(struct platform_device *pdev) | |||
| 751 | sp->srings = sr; | 751 | sp->srings = sr; |
| 752 | sp->rx_desc = sp->srings->rxvector; | 752 | sp->rx_desc = sp->srings->rxvector; |
| 753 | sp->tx_desc = sp->srings->txvector; | 753 | sp->tx_desc = sp->srings->txvector; |
| 754 | spin_lock_init(&sp->tx_lock); | ||
| 754 | 755 | ||
| 755 | /* A couple calculations now, saves many cycles later. */ | 756 | /* A couple calculations now, saves many cycles later. */ |
| 756 | setup_rx_ring(dev, sp->rx_desc, SEEQ_RX_BUFFERS); | 757 | setup_rx_ring(dev, sp->rx_desc, SEEQ_RX_BUFFERS); |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index adfab3fc5478..b1ba68f1a049 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
| @@ -297,7 +297,7 @@ static int qmi_wwan_suspend(struct usb_interface *intf, pm_message_t message) | |||
| 297 | if (ret < 0) | 297 | if (ret < 0) |
| 298 | goto err; | 298 | goto err; |
| 299 | 299 | ||
| 300 | if (info->subdriver && info->subdriver->suspend) | 300 | if (intf == info->control && info->subdriver && info->subdriver->suspend) |
| 301 | ret = info->subdriver->suspend(intf, message); | 301 | ret = info->subdriver->suspend(intf, message); |
| 302 | if (ret < 0) | 302 | if (ret < 0) |
| 303 | usbnet_resume(intf); | 303 | usbnet_resume(intf); |
| @@ -310,13 +310,14 @@ static int qmi_wwan_resume(struct usb_interface *intf) | |||
| 310 | struct usbnet *dev = usb_get_intfdata(intf); | 310 | struct usbnet *dev = usb_get_intfdata(intf); |
| 311 | struct qmi_wwan_state *info = (void *)&dev->data; | 311 | struct qmi_wwan_state *info = (void *)&dev->data; |
| 312 | int ret = 0; | 312 | int ret = 0; |
| 313 | bool callsub = (intf == info->control && info->subdriver && info->subdriver->resume); | ||
| 313 | 314 | ||
| 314 | if (info->subdriver && info->subdriver->resume) | 315 | if (callsub) |
| 315 | ret = info->subdriver->resume(intf); | 316 | ret = info->subdriver->resume(intf); |
| 316 | if (ret < 0) | 317 | if (ret < 0) |
| 317 | goto err; | 318 | goto err; |
| 318 | ret = usbnet_resume(intf); | 319 | ret = usbnet_resume(intf); |
| 319 | if (ret < 0 && info->subdriver && info->subdriver->resume && info->subdriver->suspend) | 320 | if (ret < 0 && callsub && info->subdriver->suspend) |
| 320 | info->subdriver->suspend(intf, PMSG_SUSPEND); | 321 | info->subdriver->suspend(intf, PMSG_SUSPEND); |
| 321 | err: | 322 | err: |
| 322 | return ret; | 323 | return ret; |
| @@ -398,7 +399,6 @@ static const struct usb_device_id products[] = { | |||
| 398 | /* 4. Gobi 1000 devices */ | 399 | /* 4. Gobi 1000 devices */ |
| 399 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 400 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
| 400 | {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ | 401 | {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ |
| 401 | {QMI_GOBI1K_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ | ||
| 402 | {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ | 402 | {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ |
| 403 | {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ | 403 | {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ |
| 404 | {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ | 404 | {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ |
| @@ -440,6 +440,7 @@ static const struct usb_device_id products[] = { | |||
| 440 | {QMI_GOBI_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ | 440 | {QMI_GOBI_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ |
| 441 | {QMI_GOBI_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ | 441 | {QMI_GOBI_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ |
| 442 | {QMI_GOBI_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ | 442 | {QMI_GOBI_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ |
| 443 | {QMI_GOBI_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ | ||
| 443 | {QMI_GOBI_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ | 444 | {QMI_GOBI_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ |
| 444 | {QMI_GOBI_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ | 445 | {QMI_GOBI_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ |
| 445 | {QMI_GOBI_DEVICE(0x1199, 0x901b)}, /* Sierra Wireless MC7770 */ | 446 | {QMI_GOBI_DEVICE(0x1199, 0x901b)}, /* Sierra Wireless MC7770 */ |
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index 7be49ea60b6d..8e22417fa6c1 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c | |||
| @@ -656,7 +656,7 @@ static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap) | |||
| 656 | return -EIO; | 656 | return -EIO; |
| 657 | } | 657 | } |
| 658 | 658 | ||
| 659 | *datap = *attrdata; | 659 | *datap = le16_to_cpu(*attrdata); |
| 660 | 660 | ||
| 661 | kfree(attrdata); | 661 | kfree(attrdata); |
| 662 | return result; | 662 | return result; |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index fd4b26d46fd5..fc9f578a1e25 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
| @@ -1201,19 +1201,26 @@ deferred: | |||
| 1201 | } | 1201 | } |
| 1202 | EXPORT_SYMBOL_GPL(usbnet_start_xmit); | 1202 | EXPORT_SYMBOL_GPL(usbnet_start_xmit); |
| 1203 | 1203 | ||
| 1204 | static void rx_alloc_submit(struct usbnet *dev, gfp_t flags) | 1204 | static int rx_alloc_submit(struct usbnet *dev, gfp_t flags) |
| 1205 | { | 1205 | { |
| 1206 | struct urb *urb; | 1206 | struct urb *urb; |
| 1207 | int i; | 1207 | int i; |
| 1208 | int ret = 0; | ||
| 1208 | 1209 | ||
| 1209 | /* don't refill the queue all at once */ | 1210 | /* don't refill the queue all at once */ |
| 1210 | for (i = 0; i < 10 && dev->rxq.qlen < RX_QLEN(dev); i++) { | 1211 | for (i = 0; i < 10 && dev->rxq.qlen < RX_QLEN(dev); i++) { |
| 1211 | urb = usb_alloc_urb(0, flags); | 1212 | urb = usb_alloc_urb(0, flags); |
| 1212 | if (urb != NULL) { | 1213 | if (urb != NULL) { |
| 1213 | if (rx_submit(dev, urb, flags) == -ENOLINK) | 1214 | ret = rx_submit(dev, urb, flags); |
| 1214 | return; | 1215 | if (ret) |
| 1216 | goto err; | ||
| 1217 | } else { | ||
| 1218 | ret = -ENOMEM; | ||
| 1219 | goto err; | ||
| 1215 | } | 1220 | } |
| 1216 | } | 1221 | } |
| 1222 | err: | ||
| 1223 | return ret; | ||
| 1217 | } | 1224 | } |
| 1218 | 1225 | ||
| 1219 | /*-------------------------------------------------------------------------*/ | 1226 | /*-------------------------------------------------------------------------*/ |
| @@ -1257,7 +1264,8 @@ static void usbnet_bh (unsigned long param) | |||
| 1257 | int temp = dev->rxq.qlen; | 1264 | int temp = dev->rxq.qlen; |
| 1258 | 1265 | ||
| 1259 | if (temp < RX_QLEN(dev)) { | 1266 | if (temp < RX_QLEN(dev)) { |
| 1260 | rx_alloc_submit(dev, GFP_ATOMIC); | 1267 | if (rx_alloc_submit(dev, GFP_ATOMIC) == -ENOLINK) |
| 1268 | return; | ||
| 1261 | if (temp != dev->rxq.qlen) | 1269 | if (temp != dev->rxq.qlen) |
| 1262 | netif_dbg(dev, link, dev->net, | 1270 | netif_dbg(dev, link, dev->net, |
| 1263 | "rxqlen %d --> %d\n", | 1271 | "rxqlen %d --> %d\n", |
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index aaaca9aa2293..3f575afd8cfc 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 12 | 12 | ||
| 13 | #include <linux/module.h> | ||
| 13 | #include <linux/bitops.h> | 14 | #include <linux/bitops.h> |
| 14 | #include <linux/cdev.h> | 15 | #include <linux/cdev.h> |
| 15 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 2c9f7d7ed4cc..0ed3846f9cbb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c | |||
| @@ -142,6 +142,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) | |||
| 142 | }; | 142 | }; |
| 143 | int training_power; | 143 | int training_power; |
| 144 | int i, val; | 144 | int i, val; |
| 145 | u32 am2pm_mask = ah->paprd_ratemask; | ||
| 145 | 146 | ||
| 146 | if (IS_CHAN_2GHZ(ah->curchan)) | 147 | if (IS_CHAN_2GHZ(ah->curchan)) |
| 147 | training_power = ar9003_get_training_power_2g(ah); | 148 | training_power = ar9003_get_training_power_2g(ah); |
| @@ -158,10 +159,13 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) | |||
| 158 | } | 159 | } |
| 159 | ah->paprd_training_power = training_power; | 160 | ah->paprd_training_power = training_power; |
| 160 | 161 | ||
| 162 | if (AR_SREV_9330(ah)) | ||
| 163 | am2pm_mask = 0; | ||
| 164 | |||
| 161 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, | 165 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, |
| 162 | ah->paprd_ratemask); | 166 | ah->paprd_ratemask); |
| 163 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, | 167 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, |
| 164 | ah->paprd_ratemask); | 168 | am2pm_mask); |
| 165 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, | 169 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, |
| 166 | ah->paprd_ratemask_ht40); | 170 | ah->paprd_ratemask_ht40); |
| 167 | 171 | ||
| @@ -782,6 +786,102 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) | |||
| 782 | } | 786 | } |
| 783 | EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); | 787 | EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); |
| 784 | 788 | ||
| 789 | static bool ar9003_paprd_retrain_pa_in(struct ath_hw *ah, | ||
| 790 | struct ath9k_hw_cal_data *caldata, | ||
| 791 | int chain) | ||
| 792 | { | ||
| 793 | u32 *pa_in = caldata->pa_table[chain]; | ||
| 794 | int capdiv_offset, quick_drop_offset; | ||
| 795 | int capdiv2g, quick_drop; | ||
| 796 | int count = 0; | ||
| 797 | int i; | ||
| 798 | |||
| 799 | if (!AR_SREV_9485(ah) && !AR_SREV_9330(ah)) | ||
| 800 | return false; | ||
| 801 | |||
| 802 | capdiv2g = REG_READ_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, | ||
| 803 | AR_PHY_65NM_CH0_TXRF3_CAPDIV2G); | ||
| 804 | |||
| 805 | quick_drop = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, | ||
| 806 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP); | ||
| 807 | |||
| 808 | if (quick_drop) | ||
| 809 | quick_drop -= 0x40; | ||
| 810 | |||
| 811 | for (i = 0; i < NUM_BIN + 1; i++) { | ||
| 812 | if (pa_in[i] == 1400) | ||
| 813 | count++; | ||
| 814 | } | ||
| 815 | |||
| 816 | if (AR_SREV_9485(ah)) { | ||
| 817 | if (pa_in[23] < 800) { | ||
| 818 | capdiv_offset = (int)((1000 - pa_in[23] + 75) / 150); | ||
| 819 | capdiv2g += capdiv_offset; | ||
| 820 | if (capdiv2g > 7) { | ||
| 821 | capdiv2g = 7; | ||
| 822 | if (pa_in[23] < 600) { | ||
| 823 | quick_drop++; | ||
| 824 | if (quick_drop > 0) | ||
| 825 | quick_drop = 0; | ||
| 826 | } | ||
| 827 | } | ||
| 828 | } else if (pa_in[23] == 1400) { | ||
| 829 | quick_drop_offset = min_t(int, count / 3, 2); | ||
| 830 | quick_drop += quick_drop_offset; | ||
| 831 | capdiv2g += quick_drop_offset / 2; | ||
| 832 | |||
| 833 | if (capdiv2g > 7) | ||
| 834 | capdiv2g = 7; | ||
| 835 | |||
| 836 | if (quick_drop > 0) { | ||
| 837 | quick_drop = 0; | ||
| 838 | capdiv2g -= quick_drop_offset; | ||
| 839 | if (capdiv2g < 0) | ||
| 840 | capdiv2g = 0; | ||
| 841 | } | ||
| 842 | } else { | ||
| 843 | return false; | ||
| 844 | } | ||
| 845 | } else if (AR_SREV_9330(ah)) { | ||
| 846 | if (pa_in[23] < 1000) { | ||
| 847 | capdiv_offset = (1000 - pa_in[23]) / 100; | ||
| 848 | capdiv2g += capdiv_offset; | ||
| 849 | if (capdiv_offset > 3) { | ||
| 850 | capdiv_offset = 1; | ||
| 851 | quick_drop--; | ||
| 852 | } | ||
| 853 | |||
| 854 | capdiv2g += capdiv_offset; | ||
| 855 | if (capdiv2g > 6) | ||
| 856 | capdiv2g = 6; | ||
| 857 | if (quick_drop < -4) | ||
| 858 | quick_drop = -4; | ||
| 859 | } else if (pa_in[23] == 1400) { | ||
| 860 | if (count > 3) { | ||
| 861 | quick_drop++; | ||
| 862 | capdiv2g -= count / 4; | ||
| 863 | if (quick_drop > -2) | ||
| 864 | quick_drop = -2; | ||
| 865 | } else { | ||
| 866 | capdiv2g--; | ||
| 867 | } | ||
| 868 | |||
| 869 | if (capdiv2g < 0) | ||
| 870 | capdiv2g = 0; | ||
| 871 | } else { | ||
| 872 | return false; | ||
| 873 | } | ||
| 874 | } | ||
| 875 | |||
| 876 | REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, | ||
| 877 | AR_PHY_65NM_CH0_TXRF3_CAPDIV2G, capdiv2g); | ||
| 878 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, | ||
| 879 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, | ||
| 880 | quick_drop); | ||
| 881 | |||
| 882 | return true; | ||
| 883 | } | ||
| 884 | |||
| 785 | int ar9003_paprd_create_curve(struct ath_hw *ah, | 885 | int ar9003_paprd_create_curve(struct ath_hw *ah, |
| 786 | struct ath9k_hw_cal_data *caldata, int chain) | 886 | struct ath9k_hw_cal_data *caldata, int chain) |
| 787 | { | 887 | { |
| @@ -817,6 +917,9 @@ int ar9003_paprd_create_curve(struct ath_hw *ah, | |||
| 817 | if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain)) | 917 | if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain)) |
| 818 | status = -2; | 918 | status = -2; |
| 819 | 919 | ||
| 920 | if (ar9003_paprd_retrain_pa_in(ah, caldata, chain)) | ||
| 921 | status = -EINPROGRESS; | ||
| 922 | |||
| 820 | REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, | 923 | REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, |
| 821 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); | 924 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); |
| 822 | 925 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 7bfbaf065a43..84d3d4956861 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
| @@ -625,6 +625,10 @@ | |||
| 625 | #define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0) | 625 | #define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0) |
| 626 | #define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc) | 626 | #define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc) |
| 627 | 627 | ||
| 628 | #define AR_PHY_65NM_CH0_TXRF3 0x16048 | ||
| 629 | #define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G 0x0000001e | ||
| 630 | #define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G_S 1 | ||
| 631 | |||
| 628 | #define AR_PHY_65NM_CH0_SYNTH4 0x1608c | 632 | #define AR_PHY_65NM_CH0_SYNTH4 0x1608c |
| 629 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002) | 633 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002) |
| 630 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1) | 634 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1) |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index bacdb8fb4ef4..9f83f71742a5 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
| @@ -341,7 +341,8 @@ void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc) | |||
| 341 | { | 341 | { |
| 342 | struct ath_btcoex *btcoex = &sc->btcoex; | 342 | struct ath_btcoex *btcoex = &sc->btcoex; |
| 343 | 343 | ||
| 344 | ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); | 344 | if (btcoex->hw_timer_enabled) |
| 345 | ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); | ||
| 345 | } | 346 | } |
| 346 | 347 | ||
| 347 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) | 348 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 60b6a9daff7e..48af40151d23 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
| @@ -463,9 +463,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
| 463 | ah->config.spurchans[i][1] = AR_NO_SPUR; | 463 | ah->config.spurchans[i][1] = AR_NO_SPUR; |
| 464 | } | 464 | } |
| 465 | 465 | ||
| 466 | /* PAPRD needs some more work to be enabled */ | ||
| 467 | ah->config.paprd_disable = 1; | ||
| 468 | |||
| 469 | ah->config.rx_intr_mitigation = true; | 466 | ah->config.rx_intr_mitigation = true; |
| 470 | ah->config.pcieSerDesWrite = true; | 467 | ah->config.pcieSerDesWrite = true; |
| 471 | 468 | ||
| @@ -978,9 +975,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | |||
| 978 | else | 975 | else |
| 979 | imr_reg |= AR_IMR_TXOK; | 976 | imr_reg |= AR_IMR_TXOK; |
| 980 | 977 | ||
| 981 | if (opmode == NL80211_IFTYPE_AP) | ||
| 982 | imr_reg |= AR_IMR_MIB; | ||
| 983 | |||
| 984 | ENABLE_REGWRITE_BUFFER(ah); | 978 | ENABLE_REGWRITE_BUFFER(ah); |
| 985 | 979 | ||
| 986 | REG_WRITE(ah, AR_IMR, imr_reg); | 980 | REG_WRITE(ah, AR_IMR, imr_reg); |
| @@ -1778,6 +1772,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
| 1778 | /* Operating channel changed, reset channel calibration data */ | 1772 | /* Operating channel changed, reset channel calibration data */ |
| 1779 | memset(caldata, 0, sizeof(*caldata)); | 1773 | memset(caldata, 0, sizeof(*caldata)); |
| 1780 | ath9k_init_nfcal_hist_buffer(ah, chan); | 1774 | ath9k_init_nfcal_hist_buffer(ah, chan); |
| 1775 | } else if (caldata) { | ||
| 1776 | caldata->paprd_packet_sent = false; | ||
| 1781 | } | 1777 | } |
| 1782 | ah->noise = ath9k_hw_getchan_noise(ah, chan); | 1778 | ah->noise = ath9k_hw_getchan_noise(ah, chan); |
| 1783 | 1779 | ||
| @@ -2502,7 +2498,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
| 2502 | pCap->tx_desc_len = sizeof(struct ar9003_txc); | 2498 | pCap->tx_desc_len = sizeof(struct ar9003_txc); |
| 2503 | pCap->txs_len = sizeof(struct ar9003_txs); | 2499 | pCap->txs_len = sizeof(struct ar9003_txs); |
| 2504 | if (!ah->config.paprd_disable && | 2500 | if (!ah->config.paprd_disable && |
| 2505 | ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) | 2501 | ah->eep_ops->get_eeprom(ah, EEP_PAPRD) && |
| 2502 | !AR_SREV_9462(ah)) | ||
| 2506 | pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; | 2503 | pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; |
| 2507 | } else { | 2504 | } else { |
| 2508 | pCap->tx_desc_len = sizeof(struct ath_desc); | 2505 | pCap->tx_desc_len = sizeof(struct ath_desc); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index ce7332c64efb..6599a75f01fe 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
| @@ -405,6 +405,7 @@ struct ath9k_hw_cal_data { | |||
| 405 | int8_t iCoff; | 405 | int8_t iCoff; |
| 406 | int8_t qCoff; | 406 | int8_t qCoff; |
| 407 | bool rtt_done; | 407 | bool rtt_done; |
| 408 | bool paprd_packet_sent; | ||
| 408 | bool paprd_done; | 409 | bool paprd_done; |
| 409 | bool nfcal_pending; | 410 | bool nfcal_pending; |
| 410 | bool nfcal_interference; | 411 | bool nfcal_interference; |
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index d4549e9aac5c..825a29cc9313 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c | |||
| @@ -254,8 +254,9 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
| 254 | int chain_ok = 0; | 254 | int chain_ok = 0; |
| 255 | int chain; | 255 | int chain; |
| 256 | int len = 1800; | 256 | int len = 1800; |
| 257 | int ret; | ||
| 257 | 258 | ||
| 258 | if (!caldata) | 259 | if (!caldata || !caldata->paprd_packet_sent || caldata->paprd_done) |
| 259 | return; | 260 | return; |
| 260 | 261 | ||
| 261 | ath9k_ps_wakeup(sc); | 262 | ath9k_ps_wakeup(sc); |
| @@ -282,13 +283,6 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
| 282 | continue; | 283 | continue; |
| 283 | 284 | ||
| 284 | chain_ok = 0; | 285 | chain_ok = 0; |
| 285 | |||
| 286 | ath_dbg(common, CALIBRATE, | ||
| 287 | "Sending PAPRD frame for thermal measurement on chain %d\n", | ||
| 288 | chain); | ||
| 289 | if (!ath_paprd_send_frame(sc, skb, chain)) | ||
| 290 | goto fail_paprd; | ||
| 291 | |||
| 292 | ar9003_paprd_setup_gain_table(ah, chain); | 286 | ar9003_paprd_setup_gain_table(ah, chain); |
| 293 | 287 | ||
| 294 | ath_dbg(common, CALIBRATE, | 288 | ath_dbg(common, CALIBRATE, |
| @@ -302,7 +296,13 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
| 302 | break; | 296 | break; |
| 303 | } | 297 | } |
| 304 | 298 | ||
| 305 | if (ar9003_paprd_create_curve(ah, caldata, chain)) { | 299 | ret = ar9003_paprd_create_curve(ah, caldata, chain); |
| 300 | if (ret == -EINPROGRESS) { | ||
| 301 | ath_dbg(common, CALIBRATE, | ||
| 302 | "PAPRD curve on chain %d needs to be re-trained\n", | ||
| 303 | chain); | ||
| 304 | break; | ||
| 305 | } else if (ret) { | ||
| 306 | ath_dbg(common, CALIBRATE, | 306 | ath_dbg(common, CALIBRATE, |
| 307 | "PAPRD create curve failed on chain %d\n", | 307 | "PAPRD create curve failed on chain %d\n", |
| 308 | chain); | 308 | chain); |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 2c9da6b2ecb1..0d4155aec48d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -2018,6 +2018,9 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
| 2018 | 2018 | ||
| 2019 | ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); | 2019 | ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); |
| 2020 | 2020 | ||
| 2021 | if (sc->sc_ah->caldata) | ||
| 2022 | sc->sc_ah->caldata->paprd_packet_sent = true; | ||
| 2023 | |||
| 2021 | if (!(tx_flags & ATH_TX_ERROR)) | 2024 | if (!(tx_flags & ATH_TX_ERROR)) |
| 2022 | /* Frame was ACKed */ | 2025 | /* Frame was ACKed */ |
| 2023 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | 2026 | tx_info->flags |= IEEE80211_TX_STAT_ACK; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index a299d42da8e7..58f89fa9c9f8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c | |||
| @@ -519,7 +519,7 @@ static void brcmf_usb_tx_complete(struct urb *urb) | |||
| 519 | else | 519 | else |
| 520 | devinfo->bus_pub.bus->dstats.tx_errors++; | 520 | devinfo->bus_pub.bus->dstats.tx_errors++; |
| 521 | 521 | ||
| 522 | dev_kfree_skb(req->skb); | 522 | brcmu_pkt_buf_free_skb(req->skb); |
| 523 | req->skb = NULL; | 523 | req->skb = NULL; |
| 524 | brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); | 524 | brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); |
| 525 | 525 | ||
| @@ -540,7 +540,7 @@ static void brcmf_usb_rx_complete(struct urb *urb) | |||
| 540 | devinfo->bus_pub.bus->dstats.rx_packets++; | 540 | devinfo->bus_pub.bus->dstats.rx_packets++; |
| 541 | } else { | 541 | } else { |
| 542 | devinfo->bus_pub.bus->dstats.rx_errors++; | 542 | devinfo->bus_pub.bus->dstats.rx_errors++; |
| 543 | dev_kfree_skb(skb); | 543 | brcmu_pkt_buf_free_skb(skb); |
| 544 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | 544 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); |
| 545 | return; | 545 | return; |
| 546 | } | 546 | } |
| @@ -550,13 +550,15 @@ static void brcmf_usb_rx_complete(struct urb *urb) | |||
| 550 | if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { | 550 | if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { |
| 551 | brcmf_dbg(ERROR, "rx protocol error\n"); | 551 | brcmf_dbg(ERROR, "rx protocol error\n"); |
| 552 | brcmu_pkt_buf_free_skb(skb); | 552 | brcmu_pkt_buf_free_skb(skb); |
| 553 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | ||
| 553 | devinfo->bus_pub.bus->dstats.rx_errors++; | 554 | devinfo->bus_pub.bus->dstats.rx_errors++; |
| 554 | } else { | 555 | } else { |
| 555 | brcmf_rx_packet(devinfo->dev, ifidx, skb); | 556 | brcmf_rx_packet(devinfo->dev, ifidx, skb); |
| 556 | brcmf_usb_rx_refill(devinfo, req); | 557 | brcmf_usb_rx_refill(devinfo, req); |
| 557 | } | 558 | } |
| 558 | } else { | 559 | } else { |
| 559 | dev_kfree_skb(skb); | 560 | brcmu_pkt_buf_free_skb(skb); |
| 561 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | ||
| 560 | } | 562 | } |
| 561 | return; | 563 | return; |
| 562 | 564 | ||
| @@ -581,14 +583,13 @@ static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo, | |||
| 581 | usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe, | 583 | usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe, |
| 582 | skb->data, skb_tailroom(skb), brcmf_usb_rx_complete, | 584 | skb->data, skb_tailroom(skb), brcmf_usb_rx_complete, |
| 583 | req); | 585 | req); |
| 584 | req->urb->transfer_flags |= URB_ZERO_PACKET; | ||
| 585 | req->devinfo = devinfo; | 586 | req->devinfo = devinfo; |
| 587 | brcmf_usb_enq(devinfo, &devinfo->rx_postq, req); | ||
| 586 | 588 | ||
| 587 | ret = usb_submit_urb(req->urb, GFP_ATOMIC); | 589 | ret = usb_submit_urb(req->urb, GFP_ATOMIC); |
| 588 | if (ret == 0) { | 590 | if (ret) { |
| 589 | brcmf_usb_enq(devinfo, &devinfo->rx_postq, req); | 591 | brcmf_usb_del_fromq(devinfo, req); |
| 590 | } else { | 592 | brcmu_pkt_buf_free_skb(req->skb); |
| 591 | dev_kfree_skb(req->skb); | ||
| 592 | req->skb = NULL; | 593 | req->skb = NULL; |
| 593 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | 594 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); |
| 594 | } | 595 | } |
| @@ -683,23 +684,22 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) | |||
| 683 | 684 | ||
| 684 | req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq); | 685 | req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq); |
| 685 | if (!req) { | 686 | if (!req) { |
| 687 | brcmu_pkt_buf_free_skb(skb); | ||
| 686 | brcmf_dbg(ERROR, "no req to send\n"); | 688 | brcmf_dbg(ERROR, "no req to send\n"); |
| 687 | return -ENOMEM; | 689 | return -ENOMEM; |
| 688 | } | 690 | } |
| 689 | if (!req->urb) { | ||
| 690 | brcmf_dbg(ERROR, "no urb for req %p\n", req); | ||
| 691 | return -ENOBUFS; | ||
| 692 | } | ||
| 693 | 691 | ||
| 694 | req->skb = skb; | 692 | req->skb = skb; |
| 695 | req->devinfo = devinfo; | 693 | req->devinfo = devinfo; |
| 696 | usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe, | 694 | usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe, |
| 697 | skb->data, skb->len, brcmf_usb_tx_complete, req); | 695 | skb->data, skb->len, brcmf_usb_tx_complete, req); |
| 698 | req->urb->transfer_flags |= URB_ZERO_PACKET; | 696 | req->urb->transfer_flags |= URB_ZERO_PACKET; |
| 697 | brcmf_usb_enq(devinfo, &devinfo->tx_postq, req); | ||
| 699 | ret = usb_submit_urb(req->urb, GFP_ATOMIC); | 698 | ret = usb_submit_urb(req->urb, GFP_ATOMIC); |
| 700 | if (!ret) { | 699 | if (ret) { |
| 701 | brcmf_usb_enq(devinfo, &devinfo->tx_postq, req); | 700 | brcmf_dbg(ERROR, "brcmf_usb_tx usb_submit_urb FAILED\n"); |
| 702 | } else { | 701 | brcmf_usb_del_fromq(devinfo, req); |
| 702 | brcmu_pkt_buf_free_skb(req->skb); | ||
| 703 | req->skb = NULL; | 703 | req->skb = NULL; |
| 704 | brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); | 704 | brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); |
| 705 | } | 705 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 28c5fbb4af26..c36e92312443 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
| @@ -1876,16 +1876,17 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, | |||
| 1876 | } | 1876 | } |
| 1877 | 1877 | ||
| 1878 | if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) { | 1878 | if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) { |
| 1879 | scb_val.val = cpu_to_le32(0); | 1879 | memset(&scb_val, 0, sizeof(scb_val)); |
| 1880 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val, | 1880 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val, |
| 1881 | sizeof(struct brcmf_scb_val_le)); | 1881 | sizeof(struct brcmf_scb_val_le)); |
| 1882 | if (err) | 1882 | if (err) { |
| 1883 | WL_ERR("Could not get rssi (%d)\n", err); | 1883 | WL_ERR("Could not get rssi (%d)\n", err); |
| 1884 | 1884 | } else { | |
| 1885 | rssi = le32_to_cpu(scb_val.val); | 1885 | rssi = le32_to_cpu(scb_val.val); |
| 1886 | sinfo->filled |= STATION_INFO_SIGNAL; | 1886 | sinfo->filled |= STATION_INFO_SIGNAL; |
| 1887 | sinfo->signal = rssi; | 1887 | sinfo->signal = rssi; |
| 1888 | WL_CONN("RSSI %d dBm\n", rssi); | 1888 | WL_CONN("RSSI %d dBm\n", rssi); |
| 1889 | } | ||
| 1889 | } | 1890 | } |
| 1890 | 1891 | ||
| 1891 | done: | 1892 | done: |
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index e970897f6ab5..4cb234349fbf 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
| @@ -1326,6 +1326,11 @@ static int if_sdio_suspend(struct device *dev) | |||
| 1326 | 1326 | ||
| 1327 | mmc_pm_flag_t flags = sdio_get_host_pm_caps(func); | 1327 | mmc_pm_flag_t flags = sdio_get_host_pm_caps(func); |
| 1328 | 1328 | ||
| 1329 | /* If we're powered off anyway, just let the mmc layer remove the | ||
| 1330 | * card. */ | ||
| 1331 | if (!lbs_iface_active(card->priv)) | ||
| 1332 | return -ENOSYS; | ||
| 1333 | |||
| 1329 | dev_info(dev, "%s: suspend: PM flags = 0x%x\n", | 1334 | dev_info(dev, "%s: suspend: PM flags = 0x%x\n", |
| 1330 | sdio_func_id(func), flags); | 1335 | sdio_func_id(func), flags); |
| 1331 | 1336 | ||
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index c68adec3cc8b..565527aee0ea 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
| @@ -170,7 +170,20 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, | |||
| 170 | cmd_code = le16_to_cpu(host_cmd->command); | 170 | cmd_code = le16_to_cpu(host_cmd->command); |
| 171 | cmd_size = le16_to_cpu(host_cmd->size); | 171 | cmd_size = le16_to_cpu(host_cmd->size); |
| 172 | 172 | ||
| 173 | skb_trim(cmd_node->cmd_skb, cmd_size); | 173 | /* Adjust skb length */ |
| 174 | if (cmd_node->cmd_skb->len > cmd_size) | ||
| 175 | /* | ||
| 176 | * cmd_size is less than sizeof(struct host_cmd_ds_command). | ||
| 177 | * Trim off the unused portion. | ||
| 178 | */ | ||
| 179 | skb_trim(cmd_node->cmd_skb, cmd_size); | ||
| 180 | else if (cmd_node->cmd_skb->len < cmd_size) | ||
| 181 | /* | ||
| 182 | * cmd_size is larger than sizeof(struct host_cmd_ds_command) | ||
| 183 | * because we have appended custom IE TLV. Increase skb length | ||
| 184 | * accordingly. | ||
| 185 | */ | ||
| 186 | skb_put(cmd_node->cmd_skb, cmd_size - cmd_node->cmd_skb->len); | ||
| 174 | 187 | ||
| 175 | do_gettimeofday(&tstamp); | 188 | do_gettimeofday(&tstamp); |
| 176 | dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d," | 189 | dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d," |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 8b9dbd76a252..64328af496f5 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
| @@ -1611,6 +1611,7 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
| 1611 | static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 1611 | static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
| 1612 | { | 1612 | { |
| 1613 | int retval; | 1613 | int retval; |
| 1614 | u32 reg; | ||
| 1614 | 1615 | ||
| 1615 | /* | 1616 | /* |
| 1616 | * Allocate eeprom data. | 1617 | * Allocate eeprom data. |
| @@ -1624,6 +1625,14 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
| 1624 | return retval; | 1625 | return retval; |
| 1625 | 1626 | ||
| 1626 | /* | 1627 | /* |
| 1628 | * Enable rfkill polling by setting GPIO direction of the | ||
| 1629 | * rfkill switch GPIO pin correctly. | ||
| 1630 | */ | ||
| 1631 | rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); | ||
| 1632 | rt2x00_set_field32(®, GPIOCSR_BIT8, 1); | ||
| 1633 | rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); | ||
| 1634 | |||
| 1635 | /* | ||
| 1627 | * Initialize hw specifications. | 1636 | * Initialize hw specifications. |
| 1628 | */ | 1637 | */ |
| 1629 | retval = rt2400pci_probe_hw_mode(rt2x00dev); | 1638 | retval = rt2400pci_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h index d3a4a68cc439..7564ae992b73 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.h +++ b/drivers/net/wireless/rt2x00/rt2400pci.h | |||
| @@ -670,6 +670,7 @@ | |||
| 670 | #define GPIOCSR_BIT5 FIELD32(0x00000020) | 670 | #define GPIOCSR_BIT5 FIELD32(0x00000020) |
| 671 | #define GPIOCSR_BIT6 FIELD32(0x00000040) | 671 | #define GPIOCSR_BIT6 FIELD32(0x00000040) |
| 672 | #define GPIOCSR_BIT7 FIELD32(0x00000080) | 672 | #define GPIOCSR_BIT7 FIELD32(0x00000080) |
| 673 | #define GPIOCSR_BIT8 FIELD32(0x00000100) | ||
| 673 | 674 | ||
| 674 | /* | 675 | /* |
| 675 | * BBPPCSR: BBP Pin control register. | 676 | * BBPPCSR: BBP Pin control register. |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index d2cf8a4bc8b5..3de0406735f6 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
| @@ -1929,6 +1929,7 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
| 1929 | static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 1929 | static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
| 1930 | { | 1930 | { |
| 1931 | int retval; | 1931 | int retval; |
| 1932 | u32 reg; | ||
| 1932 | 1933 | ||
| 1933 | /* | 1934 | /* |
| 1934 | * Allocate eeprom data. | 1935 | * Allocate eeprom data. |
| @@ -1942,6 +1943,14 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
| 1942 | return retval; | 1943 | return retval; |
| 1943 | 1944 | ||
| 1944 | /* | 1945 | /* |
| 1946 | * Enable rfkill polling by setting GPIO direction of the | ||
| 1947 | * rfkill switch GPIO pin correctly. | ||
| 1948 | */ | ||
| 1949 | rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); | ||
| 1950 | rt2x00_set_field32(®, GPIOCSR_DIR0, 1); | ||
| 1951 | rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); | ||
| 1952 | |||
| 1953 | /* | ||
| 1945 | * Initialize hw specifications. | 1954 | * Initialize hw specifications. |
| 1946 | */ | 1955 | */ |
| 1947 | retval = rt2500pci_probe_hw_mode(rt2x00dev); | 1956 | retval = rt2500pci_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 3aae36bb0a9e..89fee311d8fd 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
| @@ -283,7 +283,7 @@ static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
| 283 | u16 reg; | 283 | u16 reg; |
| 284 | 284 | ||
| 285 | rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); | 285 | rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); |
| 286 | return rt2x00_get_field32(reg, MAC_CSR19_BIT7); | 286 | return rt2x00_get_field16(reg, MAC_CSR19_BIT7); |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | #ifdef CONFIG_RT2X00_LIB_LEDS | 289 | #ifdef CONFIG_RT2X00_LIB_LEDS |
| @@ -1768,6 +1768,7 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
| 1768 | static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | 1768 | static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) |
| 1769 | { | 1769 | { |
| 1770 | int retval; | 1770 | int retval; |
| 1771 | u16 reg; | ||
| 1771 | 1772 | ||
| 1772 | /* | 1773 | /* |
| 1773 | * Allocate eeprom data. | 1774 | * Allocate eeprom data. |
| @@ -1781,6 +1782,14 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
| 1781 | return retval; | 1782 | return retval; |
| 1782 | 1783 | ||
| 1783 | /* | 1784 | /* |
| 1785 | * Enable rfkill polling by setting GPIO direction of the | ||
| 1786 | * rfkill switch GPIO pin correctly. | ||
| 1787 | */ | ||
| 1788 | rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); | ||
| 1789 | rt2x00_set_field16(®, MAC_CSR19_BIT8, 0); | ||
| 1790 | rt2500usb_register_write(rt2x00dev, MAC_CSR19, reg); | ||
| 1791 | |||
| 1792 | /* | ||
| 1784 | * Initialize hw specifications. | 1793 | * Initialize hw specifications. |
| 1785 | */ | 1794 | */ |
| 1786 | retval = rt2500usb_probe_hw_mode(rt2x00dev); | 1795 | retval = rt2500usb_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index b493306a7eed..196bd5103e4f 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/drivers/net/wireless/rt2x00/rt2500usb.h | |||
| @@ -189,14 +189,15 @@ | |||
| 189 | * MAC_CSR19: GPIO control register. | 189 | * MAC_CSR19: GPIO control register. |
| 190 | */ | 190 | */ |
| 191 | #define MAC_CSR19 0x0426 | 191 | #define MAC_CSR19 0x0426 |
| 192 | #define MAC_CSR19_BIT0 FIELD32(0x0001) | 192 | #define MAC_CSR19_BIT0 FIELD16(0x0001) |
| 193 | #define MAC_CSR19_BIT1 FIELD32(0x0002) | 193 | #define MAC_CSR19_BIT1 FIELD16(0x0002) |
| 194 | #define MAC_CSR19_BIT2 FIELD32(0x0004) | 194 | #define MAC_CSR19_BIT2 FIELD16(0x0004) |
| 195 | #define MAC_CSR19_BIT3 FIELD32(0x0008) | 195 | #define MAC_CSR19_BIT3 FIELD16(0x0008) |
| 196 | #define MAC_CSR19_BIT4 FIELD32(0x0010) | 196 | #define MAC_CSR19_BIT4 FIELD16(0x0010) |
| 197 | #define MAC_CSR19_BIT5 FIELD32(0x0020) | 197 | #define MAC_CSR19_BIT5 FIELD16(0x0020) |
| 198 | #define MAC_CSR19_BIT6 FIELD32(0x0040) | 198 | #define MAC_CSR19_BIT6 FIELD16(0x0040) |
| 199 | #define MAC_CSR19_BIT7 FIELD32(0x0080) | 199 | #define MAC_CSR19_BIT7 FIELD16(0x0080) |
| 200 | #define MAC_CSR19_BIT8 FIELD16(0x0100) | ||
| 200 | 201 | ||
| 201 | /* | 202 | /* |
| 202 | * MAC_CSR20: LED control register. | 203 | * MAC_CSR20: LED control register. |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index cb8c2aca54e4..b93516d832fb 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
| @@ -4089,6 +4089,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
| 4089 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | 4089 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); |
| 4090 | msleep(1); | 4090 | msleep(1); |
| 4091 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); | 4091 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); |
| 4092 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0); | ||
| 4092 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); | 4093 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); |
| 4093 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | 4094 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); |
| 4094 | } | 4095 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 98aa426a3564..4765bbd654cd 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
| @@ -983,6 +983,7 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 983 | static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 983 | static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
| 984 | { | 984 | { |
| 985 | int retval; | 985 | int retval; |
| 986 | u32 reg; | ||
| 986 | 987 | ||
| 987 | /* | 988 | /* |
| 988 | * Allocate eeprom data. | 989 | * Allocate eeprom data. |
| @@ -996,6 +997,14 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
| 996 | return retval; | 997 | return retval; |
| 997 | 998 | ||
| 998 | /* | 999 | /* |
| 1000 | * Enable rfkill polling by setting GPIO direction of the | ||
| 1001 | * rfkill switch GPIO pin correctly. | ||
| 1002 | */ | ||
| 1003 | rt2x00pci_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); | ||
| 1004 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT2, 1); | ||
| 1005 | rt2x00pci_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); | ||
| 1006 | |||
| 1007 | /* | ||
| 999 | * Initialize hw specifications. | 1008 | * Initialize hw specifications. |
| 1000 | */ | 1009 | */ |
| 1001 | retval = rt2800_probe_hw_mode(rt2x00dev); | 1010 | retval = rt2800_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 6cf336595e25..6b4226b71618 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
| @@ -667,8 +667,16 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
| 667 | skb_pull(entry->skb, RXINFO_DESC_SIZE); | 667 | skb_pull(entry->skb, RXINFO_DESC_SIZE); |
| 668 | 668 | ||
| 669 | /* | 669 | /* |
| 670 | * FIXME: we need to check for rx_pkt_len validity | 670 | * Check for rx_pkt_len validity. Return if invalid, leaving |
| 671 | * rxdesc->size zeroed out by the upper level. | ||
| 671 | */ | 672 | */ |
| 673 | if (unlikely(rx_pkt_len == 0 || | ||
| 674 | rx_pkt_len > entry->queue->data_size)) { | ||
| 675 | ERROR(entry->queue->rt2x00dev, | ||
| 676 | "Bad frame size %d, forcing to 0\n", rx_pkt_len); | ||
| 677 | return; | ||
| 678 | } | ||
| 679 | |||
| 672 | rxd = (__le32 *)(entry->skb->data + rx_pkt_len); | 680 | rxd = (__le32 *)(entry->skb->data + rx_pkt_len); |
| 673 | 681 | ||
| 674 | /* | 682 | /* |
| @@ -736,6 +744,7 @@ static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 736 | static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | 744 | static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) |
| 737 | { | 745 | { |
| 738 | int retval; | 746 | int retval; |
| 747 | u32 reg; | ||
| 739 | 748 | ||
| 740 | /* | 749 | /* |
| 741 | * Allocate eeprom data. | 750 | * Allocate eeprom data. |
| @@ -749,6 +758,14 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
| 749 | return retval; | 758 | return retval; |
| 750 | 759 | ||
| 751 | /* | 760 | /* |
| 761 | * Enable rfkill polling by setting GPIO direction of the | ||
| 762 | * rfkill switch GPIO pin correctly. | ||
| 763 | */ | ||
| 764 | rt2x00usb_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); | ||
| 765 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT2, 1); | ||
| 766 | rt2x00usb_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); | ||
| 767 | |||
| 768 | /* | ||
| 752 | * Initialize hw specifications. | 769 | * Initialize hw specifications. |
| 753 | */ | 770 | */ |
| 754 | retval = rt2800_probe_hw_mode(rt2x00dev); | 771 | retval = rt2800_probe_hw_mode(rt2x00dev); |
| @@ -1157,6 +1174,8 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
| 1157 | { USB_DEVICE(0x1690, 0x0744) }, | 1174 | { USB_DEVICE(0x1690, 0x0744) }, |
| 1158 | { USB_DEVICE(0x1690, 0x0761) }, | 1175 | { USB_DEVICE(0x1690, 0x0761) }, |
| 1159 | { USB_DEVICE(0x1690, 0x0764) }, | 1176 | { USB_DEVICE(0x1690, 0x0764) }, |
| 1177 | /* ASUS */ | ||
| 1178 | { USB_DEVICE(0x0b05, 0x179d) }, | ||
| 1160 | /* Cisco */ | 1179 | /* Cisco */ |
| 1161 | { USB_DEVICE(0x167b, 0x4001) }, | 1180 | { USB_DEVICE(0x167b, 0x4001) }, |
| 1162 | /* EnGenius */ | 1181 | /* EnGenius */ |
| @@ -1222,7 +1241,6 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
| 1222 | { USB_DEVICE(0x0b05, 0x1760) }, | 1241 | { USB_DEVICE(0x0b05, 0x1760) }, |
| 1223 | { USB_DEVICE(0x0b05, 0x1761) }, | 1242 | { USB_DEVICE(0x0b05, 0x1761) }, |
| 1224 | { USB_DEVICE(0x0b05, 0x1790) }, | 1243 | { USB_DEVICE(0x0b05, 0x1790) }, |
| 1225 | { USB_DEVICE(0x0b05, 0x179d) }, | ||
| 1226 | /* AzureWave */ | 1244 | /* AzureWave */ |
| 1227 | { USB_DEVICE(0x13d3, 0x3262) }, | 1245 | { USB_DEVICE(0x13d3, 0x3262) }, |
| 1228 | { USB_DEVICE(0x13d3, 0x3284) }, | 1246 | { USB_DEVICE(0x13d3, 0x3284) }, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index a6b88bd4a1a5..3f07e36f462b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
| @@ -629,7 +629,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp) | |||
| 629 | */ | 629 | */ |
| 630 | if (unlikely(rxdesc.size == 0 || | 630 | if (unlikely(rxdesc.size == 0 || |
| 631 | rxdesc.size > entry->queue->data_size)) { | 631 | rxdesc.size > entry->queue->data_size)) { |
| 632 | WARNING(rt2x00dev, "Wrong frame size %d max %d.\n", | 632 | ERROR(rt2x00dev, "Wrong frame size %d max %d.\n", |
| 633 | rxdesc.size, entry->queue->data_size); | 633 | rxdesc.size, entry->queue->data_size); |
| 634 | dev_kfree_skb(entry->skb); | 634 | dev_kfree_skb(entry->skb); |
| 635 | goto renew_skb; | 635 | goto renew_skb; |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 3f7bc5cadf9a..b8ec96163922 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
| @@ -2832,6 +2832,7 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
| 2832 | static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 2832 | static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
| 2833 | { | 2833 | { |
| 2834 | int retval; | 2834 | int retval; |
| 2835 | u32 reg; | ||
| 2835 | 2836 | ||
| 2836 | /* | 2837 | /* |
| 2837 | * Disable power saving. | 2838 | * Disable power saving. |
| @@ -2850,6 +2851,14 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
| 2850 | return retval; | 2851 | return retval; |
| 2851 | 2852 | ||
| 2852 | /* | 2853 | /* |
| 2854 | * Enable rfkill polling by setting GPIO direction of the | ||
| 2855 | * rfkill switch GPIO pin correctly. | ||
| 2856 | */ | ||
| 2857 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); | ||
| 2858 | rt2x00_set_field32(®, MAC_CSR13_BIT13, 1); | ||
| 2859 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); | ||
| 2860 | |||
| 2861 | /* | ||
| 2853 | * Initialize hw specifications. | 2862 | * Initialize hw specifications. |
| 2854 | */ | 2863 | */ |
| 2855 | retval = rt61pci_probe_hw_mode(rt2x00dev); | 2864 | retval = rt61pci_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index e3cd6db76b0e..8f3da5a56766 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h | |||
| @@ -372,6 +372,7 @@ struct hw_pairwise_ta_entry { | |||
| 372 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) | 372 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) |
| 373 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) | 373 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) |
| 374 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) | 374 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) |
| 375 | #define MAC_CSR13_BIT13 FIELD32(0x00002000) | ||
| 375 | 376 | ||
| 376 | /* | 377 | /* |
| 377 | * MAC_CSR14: LED control register. | 378 | * MAC_CSR14: LED control register. |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index ba6e434b859d..248436c13ce0 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
| @@ -2177,6 +2177,7 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
| 2177 | static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | 2177 | static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) |
| 2178 | { | 2178 | { |
| 2179 | int retval; | 2179 | int retval; |
| 2180 | u32 reg; | ||
| 2180 | 2181 | ||
| 2181 | /* | 2182 | /* |
| 2182 | * Allocate eeprom data. | 2183 | * Allocate eeprom data. |
| @@ -2190,6 +2191,14 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
| 2190 | return retval; | 2191 | return retval; |
| 2191 | 2192 | ||
| 2192 | /* | 2193 | /* |
| 2194 | * Enable rfkill polling by setting GPIO direction of the | ||
| 2195 | * rfkill switch GPIO pin correctly. | ||
| 2196 | */ | ||
| 2197 | rt2x00usb_register_read(rt2x00dev, MAC_CSR13, ®); | ||
| 2198 | rt2x00_set_field32(®, MAC_CSR13_BIT15, 0); | ||
| 2199 | rt2x00usb_register_write(rt2x00dev, MAC_CSR13, reg); | ||
| 2200 | |||
| 2201 | /* | ||
| 2193 | * Initialize hw specifications. | 2202 | * Initialize hw specifications. |
| 2194 | */ | 2203 | */ |
| 2195 | retval = rt73usb_probe_hw_mode(rt2x00dev); | 2204 | retval = rt73usb_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index 9f6b470414d3..df1cc116b83b 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h | |||
| @@ -282,6 +282,9 @@ struct hw_pairwise_ta_entry { | |||
| 282 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) | 282 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) |
| 283 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) | 283 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) |
| 284 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) | 284 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) |
| 285 | #define MAC_CSR13_BIT13 FIELD32(0x00002000) | ||
| 286 | #define MAC_CSR13_BIT14 FIELD32(0x00004000) | ||
| 287 | #define MAC_CSR13_BIT15 FIELD32(0x00008000) | ||
| 285 | 288 | ||
| 286 | /* | 289 | /* |
| 287 | * MAC_CSR14: LED control register. | 290 | * MAC_CSR14: LED control register. |
