diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-30 15:37:35 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-30 15:37:35 -0500 |
| commit | c3bf4906fba0d8871572b3f50fc036aade093e4d (patch) | |
| tree | 90d673b38febfa503085bba10515f6bc51b490a0 | |
| parent | f39edadd1533713a5ed8ba31887ea6c93d137083 (diff) | |
| parent | 7f9d3577e2603ca279c3176b696eba392f21cbe2 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (74 commits)
Revert "b43: Enforce DMA descriptor memory constraints"
iwmc3200wifi: fix array out-of-boundary access
wl1251: timeout one too soon in wl1251_boot_run_firmware()
mac80211: fix propagation of failed hardware reconfigurations
mac80211: fix race with suspend and dynamic_ps_disable_work
ath9k: fix missed error codes in the tx status check
ath9k: wake hardware during AMPDU TX actions
ath9k: wake hardware for interface IBSS/AP/Mesh removal
ath9k: fix suspend by waking device prior to stop
cfg80211: fix error path in cfg80211_wext_siwscan
wl1271_cmd.c: cleanup char => u8
iwlwifi: Storage class should be before const qualifier
ath9k: Storage class should be before const qualifier
cfg80211: fix race between deauth and assoc response
wireless: remove remaining qual code
rt2x00: Add USB ID for Linksys WUSB 600N rev 2.
ath5k: fix SWI calibration interrupt storm
mac80211: fix ibss join with fixed-bssid
libertas: Remove carrier signaling from the scan code
orinoco: fix GFP_KERNEL in orinoco_set_key with interrupts disabled
...
90 files changed, 863 insertions, 813 deletions
diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index fbc231153e55..77cf0901a441 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c | |||
| @@ -56,6 +56,7 @@ static const char version[] = | |||
| 56 | #include <linux/errno.h> | 56 | #include <linux/errno.h> |
| 57 | #include <linux/netdevice.h> | 57 | #include <linux/netdevice.h> |
| 58 | #include <linux/etherdevice.h> | 58 | #include <linux/etherdevice.h> |
| 59 | #include <linux/if_ether.h> | ||
| 59 | #include <linux/skbuff.h> | 60 | #include <linux/skbuff.h> |
| 60 | #include <linux/slab.h> | 61 | #include <linux/slab.h> |
| 61 | #include <linux/init.h> | 62 | #include <linux/init.h> |
| @@ -734,8 +735,7 @@ static void init_82586_mem(struct net_device *dev) | |||
| 734 | memcpy_toio(lp->base, init_words + 5, sizeof(init_words) - 10); | 735 | memcpy_toio(lp->base, init_words + 5, sizeof(init_words) - 10); |
| 735 | 736 | ||
| 736 | /* Fill in the station address. */ | 737 | /* Fill in the station address. */ |
| 737 | memcpy_toio(lp->base+SA_OFFSET, dev->dev_addr, | 738 | memcpy_toio(lp->base+SA_OFFSET, dev->dev_addr, ETH_ALEN); |
| 738 | sizeof(dev->dev_addr)); | ||
| 739 | 739 | ||
| 740 | /* The Tx-block list is written as needed. We just set up the values. */ | 740 | /* The Tx-block list is written as needed. We just set up the values. */ |
| 741 | lp->tx_cmd_link = IDLELOOP + 4; | 741 | lp->tx_cmd_link = IDLELOOP + 4; |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index e58a65391ad2..dd9a09c72dff 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
| @@ -2346,6 +2346,7 @@ config GELIC_NET | |||
| 2346 | 2346 | ||
| 2347 | config GELIC_WIRELESS | 2347 | config GELIC_WIRELESS |
| 2348 | bool "PS3 Wireless support" | 2348 | bool "PS3 Wireless support" |
| 2349 | depends on WLAN | ||
| 2349 | depends on GELIC_NET | 2350 | depends on GELIC_NET |
| 2350 | select WIRELESS_EXT | 2351 | select WIRELESS_EXT |
| 2351 | help | 2352 | help |
| @@ -2358,6 +2359,7 @@ config GELIC_WIRELESS | |||
| 2358 | config GELIC_WIRELESS_OLD_PSK_INTERFACE | 2359 | config GELIC_WIRELESS_OLD_PSK_INTERFACE |
| 2359 | bool "PS3 Wireless private PSK interface (OBSOLETE)" | 2360 | bool "PS3 Wireless private PSK interface (OBSOLETE)" |
| 2360 | depends on GELIC_WIRELESS | 2361 | depends on GELIC_WIRELESS |
| 2362 | select WEXT_PRIV | ||
| 2361 | help | 2363 | help |
| 2362 | This option retains the obsolete private interface to pass | 2364 | This option retains the obsolete private interface to pass |
| 2363 | the PSK from user space programs to the driver. The PSK | 2365 | the PSK from user space programs to the driver. The PSK |
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 9e56014d27ed..9fd8e5ecd5d7 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h | |||
| @@ -275,6 +275,7 @@ struct be_adapter { | |||
| 275 | u32 tx_fc; /* Tx flow control */ | 275 | u32 tx_fc; /* Tx flow control */ |
| 276 | int link_speed; | 276 | int link_speed; |
| 277 | u8 port_type; | 277 | u8 port_type; |
| 278 | u8 transceiver; | ||
| 278 | }; | 279 | }; |
| 279 | 280 | ||
| 280 | extern const struct ethtool_ops be_ethtool_ops; | 281 | extern const struct ethtool_ops be_ethtool_ops; |
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 1b68bd98dc0c..102ade134165 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
| @@ -1479,6 +1479,41 @@ err: | |||
| 1479 | return status; | 1479 | return status; |
| 1480 | } | 1480 | } |
| 1481 | 1481 | ||
| 1482 | int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, | ||
| 1483 | u8 loopback_type, u8 enable) | ||
| 1484 | { | ||
| 1485 | struct be_mcc_wrb *wrb; | ||
| 1486 | struct be_cmd_req_set_lmode *req; | ||
| 1487 | int status; | ||
| 1488 | |||
| 1489 | spin_lock_bh(&adapter->mcc_lock); | ||
| 1490 | |||
| 1491 | wrb = wrb_from_mccq(adapter); | ||
| 1492 | if (!wrb) { | ||
| 1493 | status = -EBUSY; | ||
| 1494 | goto err; | ||
| 1495 | } | ||
| 1496 | |||
| 1497 | req = embedded_payload(wrb); | ||
| 1498 | |||
| 1499 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, | ||
| 1500 | OPCODE_LOWLEVEL_SET_LOOPBACK_MODE); | ||
| 1501 | |||
| 1502 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL, | ||
| 1503 | OPCODE_LOWLEVEL_SET_LOOPBACK_MODE, | ||
| 1504 | sizeof(*req)); | ||
| 1505 | |||
| 1506 | req->src_port = port_num; | ||
| 1507 | req->dest_port = port_num; | ||
| 1508 | req->loopback_type = loopback_type; | ||
| 1509 | req->loopback_state = enable; | ||
| 1510 | |||
| 1511 | status = be_mcc_notify_wait(adapter); | ||
| 1512 | err: | ||
| 1513 | spin_unlock_bh(&adapter->mcc_lock); | ||
| 1514 | return status; | ||
| 1515 | } | ||
| 1516 | |||
| 1482 | int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, | 1517 | int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, |
| 1483 | u32 loopback_type, u32 pkt_size, u32 num_pkts, u64 pattern) | 1518 | u32 loopback_type, u32 pkt_size, u32 num_pkts, u64 pattern) |
| 1484 | { | 1519 | { |
| @@ -1501,6 +1536,7 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, | |||
| 1501 | 1536 | ||
| 1502 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL, | 1537 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL, |
| 1503 | OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req)); | 1538 | OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req)); |
| 1539 | req->hdr.timeout = 4; | ||
| 1504 | 1540 | ||
| 1505 | req->pattern = cpu_to_le64(pattern); | 1541 | req->pattern = cpu_to_le64(pattern); |
| 1506 | req->src_port = cpu_to_le32(port_num); | 1542 | req->src_port = cpu_to_le32(port_num); |
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 92b87ef156ed..c002b8391b4d 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h | |||
| @@ -155,6 +155,7 @@ struct be_mcc_mailbox { | |||
| 155 | 155 | ||
| 156 | #define OPCODE_LOWLEVEL_HOST_DDR_DMA 17 | 156 | #define OPCODE_LOWLEVEL_HOST_DDR_DMA 17 |
| 157 | #define OPCODE_LOWLEVEL_LOOPBACK_TEST 18 | 157 | #define OPCODE_LOWLEVEL_LOOPBACK_TEST 18 |
| 158 | #define OPCODE_LOWLEVEL_SET_LOOPBACK_MODE 19 | ||
| 158 | 159 | ||
| 159 | struct be_cmd_req_hdr { | 160 | struct be_cmd_req_hdr { |
| 160 | u8 opcode; /* dword 0 */ | 161 | u8 opcode; /* dword 0 */ |
| @@ -821,6 +822,19 @@ struct be_cmd_resp_loopback_test { | |||
| 821 | u32 ticks_compl; | 822 | u32 ticks_compl; |
| 822 | }; | 823 | }; |
| 823 | 824 | ||
| 825 | struct be_cmd_req_set_lmode { | ||
| 826 | struct be_cmd_req_hdr hdr; | ||
| 827 | u8 src_port; | ||
| 828 | u8 dest_port; | ||
| 829 | u8 loopback_type; | ||
| 830 | u8 loopback_state; | ||
| 831 | }; | ||
| 832 | |||
| 833 | struct be_cmd_resp_set_lmode { | ||
| 834 | struct be_cmd_resp_hdr resp_hdr; | ||
| 835 | u8 rsvd0[4]; | ||
| 836 | }; | ||
| 837 | |||
| 824 | /********************** DDR DMA test *********************/ | 838 | /********************** DDR DMA test *********************/ |
| 825 | struct be_cmd_req_ddrdma_test { | 839 | struct be_cmd_req_ddrdma_test { |
| 826 | struct be_cmd_req_hdr hdr; | 840 | struct be_cmd_req_hdr hdr; |
| @@ -912,3 +926,5 @@ extern int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, | |||
| 912 | u32 num_pkts, u64 pattern); | 926 | u32 num_pkts, u64 pattern); |
| 913 | extern int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern, | 927 | extern int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern, |
| 914 | u32 byte_cnt, struct be_dma_mem *cmd); | 928 | u32 byte_cnt, struct be_dma_mem *cmd); |
| 929 | extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, | ||
| 930 | u8 loopback_type, u8 enable); | ||
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 298b92cbd689..5d001c4deac1 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c | |||
| @@ -118,6 +118,7 @@ static const char et_self_tests[][ETH_GSTRING_LEN] = { | |||
| 118 | #define BE_MAC_LOOPBACK 0x0 | 118 | #define BE_MAC_LOOPBACK 0x0 |
| 119 | #define BE_PHY_LOOPBACK 0x1 | 119 | #define BE_PHY_LOOPBACK 0x1 |
| 120 | #define BE_ONE_PORT_EXT_LOOPBACK 0x2 | 120 | #define BE_ONE_PORT_EXT_LOOPBACK 0x2 |
| 121 | #define BE_NO_LOOPBACK 0xff | ||
| 121 | 122 | ||
| 122 | static void | 123 | static void |
| 123 | be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) | 124 | be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) |
| @@ -339,28 +340,50 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
| 339 | 340 | ||
| 340 | status = be_cmd_read_port_type(adapter, adapter->port_num, | 341 | status = be_cmd_read_port_type(adapter, adapter->port_num, |
| 341 | &connector); | 342 | &connector); |
| 342 | switch (connector) { | 343 | if (!status) { |
| 343 | case 7: | 344 | switch (connector) { |
| 344 | ecmd->port = PORT_FIBRE; | 345 | case 7: |
| 345 | break; | 346 | ecmd->port = PORT_FIBRE; |
| 346 | default: | 347 | ecmd->transceiver = XCVR_EXTERNAL; |
| 347 | ecmd->port = PORT_TP; | 348 | break; |
| 348 | break; | 349 | case 0: |
| 350 | ecmd->port = PORT_TP; | ||
| 351 | ecmd->transceiver = XCVR_EXTERNAL; | ||
| 352 | break; | ||
| 353 | default: | ||
| 354 | ecmd->port = PORT_TP; | ||
| 355 | ecmd->transceiver = XCVR_INTERNAL; | ||
| 356 | break; | ||
| 357 | } | ||
| 358 | } else { | ||
| 359 | ecmd->port = PORT_AUI; | ||
| 360 | ecmd->transceiver = XCVR_INTERNAL; | ||
| 349 | } | 361 | } |
| 350 | 362 | ||
| 351 | /* Save for future use */ | 363 | /* Save for future use */ |
| 352 | adapter->link_speed = ecmd->speed; | 364 | adapter->link_speed = ecmd->speed; |
| 353 | adapter->port_type = ecmd->port; | 365 | adapter->port_type = ecmd->port; |
| 366 | adapter->transceiver = ecmd->transceiver; | ||
| 354 | } else { | 367 | } else { |
| 355 | ecmd->speed = adapter->link_speed; | 368 | ecmd->speed = adapter->link_speed; |
| 356 | ecmd->port = adapter->port_type; | 369 | ecmd->port = adapter->port_type; |
| 370 | ecmd->transceiver = adapter->transceiver; | ||
| 357 | } | 371 | } |
| 358 | 372 | ||
| 359 | ecmd->duplex = DUPLEX_FULL; | 373 | ecmd->duplex = DUPLEX_FULL; |
| 360 | ecmd->autoneg = AUTONEG_DISABLE; | 374 | ecmd->autoneg = AUTONEG_DISABLE; |
| 361 | ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_TP); | ||
| 362 | ecmd->phy_address = adapter->port_num; | 375 | ecmd->phy_address = adapter->port_num; |
| 363 | ecmd->transceiver = XCVR_INTERNAL; | 376 | switch (ecmd->port) { |
| 377 | case PORT_FIBRE: | ||
| 378 | ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); | ||
| 379 | break; | ||
| 380 | case PORT_TP: | ||
| 381 | ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_TP); | ||
| 382 | break; | ||
| 383 | case PORT_AUI: | ||
| 384 | ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_AUI); | ||
| 385 | break; | ||
| 386 | } | ||
| 364 | 387 | ||
| 365 | return 0; | 388 | return 0; |
| 366 | } | 389 | } |
| @@ -489,6 +512,19 @@ err: | |||
| 489 | return ret; | 512 | return ret; |
| 490 | } | 513 | } |
| 491 | 514 | ||
| 515 | static u64 be_loopback_test(struct be_adapter *adapter, u8 loopback_type, | ||
| 516 | u64 *status) | ||
| 517 | { | ||
| 518 | be_cmd_set_loopback(adapter, adapter->port_num, | ||
| 519 | loopback_type, 1); | ||
| 520 | *status = be_cmd_loopback_test(adapter, adapter->port_num, | ||
| 521 | loopback_type, 1500, | ||
| 522 | 2, 0xabc); | ||
| 523 | be_cmd_set_loopback(adapter, adapter->port_num, | ||
| 524 | BE_NO_LOOPBACK, 1); | ||
| 525 | return *status; | ||
| 526 | } | ||
| 527 | |||
| 492 | static void | 528 | static void |
| 493 | be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) | 529 | be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) |
| 494 | { | 530 | { |
| @@ -497,23 +533,18 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) | |||
| 497 | memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM); | 533 | memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM); |
| 498 | 534 | ||
| 499 | if (test->flags & ETH_TEST_FL_OFFLINE) { | 535 | if (test->flags & ETH_TEST_FL_OFFLINE) { |
| 500 | data[0] = be_cmd_loopback_test(adapter, adapter->port_num, | 536 | if (be_loopback_test(adapter, BE_MAC_LOOPBACK, |
| 501 | BE_MAC_LOOPBACK, 1500, | 537 | &data[0]) != 0) { |
| 502 | 2, 0xabc); | ||
| 503 | if (data[0] != 0) | ||
| 504 | test->flags |= ETH_TEST_FL_FAILED; | 538 | test->flags |= ETH_TEST_FL_FAILED; |
| 505 | 539 | } | |
| 506 | data[1] = be_cmd_loopback_test(adapter, adapter->port_num, | 540 | if (be_loopback_test(adapter, BE_PHY_LOOPBACK, |
| 507 | BE_PHY_LOOPBACK, 1500, | 541 | &data[1]) != 0) { |
| 508 | 2, 0xabc); | ||
| 509 | if (data[1] != 0) | ||
| 510 | test->flags |= ETH_TEST_FL_FAILED; | 542 | test->flags |= ETH_TEST_FL_FAILED; |
| 511 | 543 | } | |
| 512 | data[2] = be_cmd_loopback_test(adapter, adapter->port_num, | 544 | if (be_loopback_test(adapter, BE_ONE_PORT_EXT_LOOPBACK, |
| 513 | BE_ONE_PORT_EXT_LOOPBACK, | 545 | &data[2]) != 0) { |
| 514 | 1500, 2, 0xabc); | ||
| 515 | if (data[2] != 0) | ||
| 516 | test->flags |= ETH_TEST_FL_FAILED; | 546 | test->flags |= ETH_TEST_FL_FAILED; |
| 547 | } | ||
| 517 | 548 | ||
| 518 | data[3] = be_test_ddr_dma(adapter); | 549 | data[3] = be_test_ddr_dma(adapter); |
| 519 | if (data[3] != 0) | 550 | if (data[3] != 0) |
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 77ba13520d87..306c2b8165e2 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c | |||
| @@ -7593,6 +7593,8 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
| 7593 | if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) { | 7593 | if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) { |
| 7594 | bnx2x_set_iscsi_eth_mac_addr(bp, 1); | 7594 | bnx2x_set_iscsi_eth_mac_addr(bp, 1); |
| 7595 | bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; | 7595 | bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; |
| 7596 | bnx2x_init_sb(bp, bp->cnic_sb, bp->cnic_sb_mapping, | ||
| 7597 | CNIC_SB_ID(bp)); | ||
| 7596 | } | 7598 | } |
| 7597 | mutex_unlock(&bp->cnic_mutex); | 7599 | mutex_unlock(&bp->cnic_mutex); |
| 7598 | #endif | 7600 | #endif |
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 0fb7a4964e75..822f586d72af 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
| @@ -1580,7 +1580,7 @@ static void ad_agg_selection_logic(struct aggregator *agg) | |||
| 1580 | // check if any partner replys | 1580 | // check if any partner replys |
| 1581 | if (best->is_individual) { | 1581 | if (best->is_individual) { |
| 1582 | pr_warning("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n", | 1582 | pr_warning("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n", |
| 1583 | best->slave->dev->master->name); | 1583 | best->slave ? best->slave->dev->master->name : "NULL"); |
| 1584 | } | 1584 | } |
| 1585 | 1585 | ||
| 1586 | best->is_active = 1; | 1586 | best->is_active = 1; |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index e0620d084644..8bd3c9f17532 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
| @@ -143,7 +143,6 @@ void gfar_start(struct net_device *dev); | |||
| 143 | static void gfar_clear_exact_match(struct net_device *dev); | 143 | static void gfar_clear_exact_match(struct net_device *dev); |
| 144 | static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr); | 144 | static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr); |
| 145 | static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 145 | static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
| 146 | u16 gfar_select_queue(struct net_device *dev, struct sk_buff *skb); | ||
| 147 | 146 | ||
| 148 | MODULE_AUTHOR("Freescale Semiconductor, Inc"); | 147 | MODULE_AUTHOR("Freescale Semiconductor, Inc"); |
| 149 | MODULE_DESCRIPTION("Gianfar Ethernet Driver"); | 148 | MODULE_DESCRIPTION("Gianfar Ethernet Driver"); |
| @@ -455,7 +454,6 @@ static const struct net_device_ops gfar_netdev_ops = { | |||
| 455 | .ndo_set_multicast_list = gfar_set_multi, | 454 | .ndo_set_multicast_list = gfar_set_multi, |
| 456 | .ndo_tx_timeout = gfar_timeout, | 455 | .ndo_tx_timeout = gfar_timeout, |
| 457 | .ndo_do_ioctl = gfar_ioctl, | 456 | .ndo_do_ioctl = gfar_ioctl, |
| 458 | .ndo_select_queue = gfar_select_queue, | ||
| 459 | .ndo_get_stats = gfar_get_stats, | 457 | .ndo_get_stats = gfar_get_stats, |
| 460 | .ndo_vlan_rx_register = gfar_vlan_rx_register, | 458 | .ndo_vlan_rx_register = gfar_vlan_rx_register, |
| 461 | .ndo_set_mac_address = eth_mac_addr, | 459 | .ndo_set_mac_address = eth_mac_addr, |
| @@ -506,10 +504,6 @@ static inline int gfar_uses_fcb(struct gfar_private *priv) | |||
| 506 | return priv->vlgrp || priv->rx_csum_enable; | 504 | return priv->vlgrp || priv->rx_csum_enable; |
| 507 | } | 505 | } |
| 508 | 506 | ||
| 509 | u16 gfar_select_queue(struct net_device *dev, struct sk_buff *skb) | ||
| 510 | { | ||
| 511 | return skb_get_queue_mapping(skb); | ||
| 512 | } | ||
| 513 | static void free_tx_pointers(struct gfar_private *priv) | 507 | static void free_tx_pointers(struct gfar_private *priv) |
| 514 | { | 508 | { |
| 515 | int i = 0; | 509 | int i = 0; |
| @@ -2470,10 +2464,11 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, | |||
| 2470 | fcb = (struct rxfcb *)skb->data; | 2464 | fcb = (struct rxfcb *)skb->data; |
| 2471 | 2465 | ||
| 2472 | /* Remove the FCB from the skb */ | 2466 | /* Remove the FCB from the skb */ |
| 2473 | skb_set_queue_mapping(skb, fcb->rq); | ||
| 2474 | /* Remove the padded bytes, if there are any */ | 2467 | /* Remove the padded bytes, if there are any */ |
| 2475 | if (amount_pull) | 2468 | if (amount_pull) { |
| 2469 | skb_record_rx_queue(skb, fcb->rq); | ||
| 2476 | skb_pull(skb, amount_pull); | 2470 | skb_pull(skb, amount_pull); |
| 2471 | } | ||
| 2477 | 2472 | ||
| 2478 | if (priv->rx_csum_enable) | 2473 | if (priv->rx_csum_enable) |
| 2479 | gfar_rx_checksum(skb, fcb); | 2474 | gfar_rx_checksum(skb, fcb); |
| @@ -2554,7 +2549,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) | |||
| 2554 | /* Remove the FCS from the packet length */ | 2549 | /* Remove the FCS from the packet length */ |
| 2555 | skb_put(skb, pkt_len); | 2550 | skb_put(skb, pkt_len); |
| 2556 | rx_queue->stats.rx_bytes += pkt_len; | 2551 | rx_queue->stats.rx_bytes += pkt_len; |
| 2557 | 2552 | skb_record_rx_queue(skb, rx_queue->qindex); | |
| 2558 | gfar_process_frame(dev, skb, amount_pull); | 2553 | gfar_process_frame(dev, skb, amount_pull); |
| 2559 | 2554 | ||
| 2560 | } else { | 2555 | } else { |
diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index 090a6d3af112..052c74091d91 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c | |||
| @@ -87,6 +87,7 @@ History: | |||
| 87 | #include <linux/module.h> | 87 | #include <linux/module.h> |
| 88 | #include <linux/netdevice.h> | 88 | #include <linux/netdevice.h> |
| 89 | #include <linux/etherdevice.h> | 89 | #include <linux/etherdevice.h> |
| 90 | #include <linux/if_ether.h> | ||
| 90 | #include <linux/skbuff.h> | 91 | #include <linux/skbuff.h> |
| 91 | #include <linux/bitops.h> | 92 | #include <linux/bitops.h> |
| 92 | 93 | ||
| @@ -988,7 +989,7 @@ static int __devinit ibmlana_init_one(struct device *kdev) | |||
| 988 | 989 | ||
| 989 | /* copy out MAC address */ | 990 | /* copy out MAC address */ |
| 990 | 991 | ||
| 991 | for (z = 0; z < sizeof(dev->dev_addr); z++) | 992 | for (z = 0; z < ETH_ALEN; z++) |
| 992 | dev->dev_addr[z] = inb(dev->base_addr + MACADDRPROM + z); | 993 | dev->dev_addr[z] = inb(dev->base_addr + MACADDRPROM + z); |
| 993 | 994 | ||
| 994 | /* print config */ | 995 | /* print config */ |
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index e8e9e9194a88..c505b50d1fa3 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c | |||
| @@ -1096,9 +1096,7 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw) | |||
| 1096 | hw_dbg("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg); | 1096 | hw_dbg("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg); |
| 1097 | } else { | 1097 | } else { |
| 1098 | /* Set PCS register for forced link */ | 1098 | /* Set PCS register for forced link */ |
| 1099 | reg |= E1000_PCS_LCTL_FSD | /* Force Speed */ | 1099 | reg |= E1000_PCS_LCTL_FSD; /* Force Speed */ |
| 1100 | E1000_PCS_LCTL_FORCE_LINK | /* Force Link */ | ||
| 1101 | E1000_PCS_LCTL_FLV_LINK_UP; /* Force link value up */ | ||
| 1102 | 1100 | ||
| 1103 | hw_dbg("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg); | 1101 | hw_dbg("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg); |
| 1104 | } | 1102 | } |
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c index 5c9d73e9bb8d..3670a66401b8 100644 --- a/drivers/net/igb/e1000_phy.c +++ b/drivers/net/igb/e1000_phy.c | |||
| @@ -457,15 +457,6 @@ s32 igb_copper_link_setup_82580(struct e1000_hw *hw) | |||
| 457 | phy_data |= I82580_CFG_ENABLE_DOWNSHIFT; | 457 | phy_data |= I82580_CFG_ENABLE_DOWNSHIFT; |
| 458 | 458 | ||
| 459 | ret_val = phy->ops.write_reg(hw, I82580_CFG_REG, phy_data); | 459 | ret_val = phy->ops.write_reg(hw, I82580_CFG_REG, phy_data); |
| 460 | if (ret_val) | ||
| 461 | goto out; | ||
| 462 | |||
| 463 | /* Set number of link attempts before downshift */ | ||
| 464 | ret_val = phy->ops.read_reg(hw, I82580_CTRL_REG, &phy_data); | ||
| 465 | if (ret_val) | ||
| 466 | goto out; | ||
| 467 | phy_data &= ~I82580_CTRL_DOWNSHIFT_MASK; | ||
| 468 | ret_val = phy->ops.write_reg(hw, I82580_CTRL_REG, phy_data); | ||
| 469 | 460 | ||
| 470 | out: | 461 | out: |
| 471 | return ret_val; | 462 | return ret_val; |
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index ac9d5272650d..f771a6c08777 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c | |||
| @@ -1795,7 +1795,7 @@ static int igb_wol_exclusion(struct igb_adapter *adapter, | |||
| 1795 | /* dual port cards only support WoL on port A from now on | 1795 | /* dual port cards only support WoL on port A from now on |
| 1796 | * unless it was enabled in the eeprom for port B | 1796 | * unless it was enabled in the eeprom for port B |
| 1797 | * so exclude FUNC_1 ports from having WoL enabled */ | 1797 | * so exclude FUNC_1 ports from having WoL enabled */ |
| 1798 | if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1 && | 1798 | if ((rd32(E1000_STATUS) & E1000_STATUS_FUNC_MASK) && |
| 1799 | !adapter->eeprom_wol) { | 1799 | !adapter->eeprom_wol) { |
| 1800 | wol->supported = 0; | 1800 | wol->supported = 0; |
| 1801 | break; | 1801 | break; |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 78963a0e128d..933c64ff2465 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
| @@ -1306,13 +1306,8 @@ void igb_reset(struct igb_adapter *adapter) | |||
| 1306 | hwm = min(((pba << 10) * 9 / 10), | 1306 | hwm = min(((pba << 10) * 9 / 10), |
| 1307 | ((pba << 10) - 2 * adapter->max_frame_size)); | 1307 | ((pba << 10) - 2 * adapter->max_frame_size)); |
| 1308 | 1308 | ||
| 1309 | if (mac->type < e1000_82576) { | 1309 | fc->high_water = hwm & 0xFFF0; /* 16-byte granularity */ |
| 1310 | fc->high_water = hwm & 0xFFF8; /* 8-byte granularity */ | 1310 | fc->low_water = fc->high_water - 16; |
| 1311 | fc->low_water = fc->high_water - 8; | ||
| 1312 | } else { | ||
| 1313 | fc->high_water = hwm & 0xFFF0; /* 16-byte granularity */ | ||
| 1314 | fc->low_water = fc->high_water - 16; | ||
| 1315 | } | ||
| 1316 | fc->pause_time = 0xFFFF; | 1311 | fc->pause_time = 0xFFFF; |
| 1317 | fc->send_xon = 1; | 1312 | fc->send_xon = 1; |
| 1318 | fc->current_mode = fc->requested_mode; | 1313 | fc->current_mode = fc->requested_mode; |
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index e9dd95f136aa..0dbd0320023a 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c | |||
| @@ -2763,7 +2763,8 @@ static int __devinit igbvf_probe(struct pci_dev *pdev, | |||
| 2763 | err = hw->mac.ops.reset_hw(hw); | 2763 | err = hw->mac.ops.reset_hw(hw); |
| 2764 | if (err) { | 2764 | if (err) { |
| 2765 | dev_info(&pdev->dev, | 2765 | dev_info(&pdev->dev, |
| 2766 | "PF still in reset state, assigning new address\n"); | 2766 | "PF still in reset state, assigning new address." |
| 2767 | " Is the PF interface up?\n"); | ||
| 2767 | random_ether_addr(hw->mac.addr); | 2768 | random_ether_addr(hw->mac.addr); |
| 2768 | } else { | 2769 | } else { |
| 2769 | err = hw->mac.ops.read_mac_addr(hw); | 2770 | err = hw->mac.ops.read_mac_addr(hw); |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index bd64387563f0..1a2ea621e371 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
| @@ -4373,6 +4373,11 @@ static int ixgbe_resume(struct pci_dev *pdev) | |||
| 4373 | 4373 | ||
| 4374 | pci_set_power_state(pdev, PCI_D0); | 4374 | pci_set_power_state(pdev, PCI_D0); |
| 4375 | pci_restore_state(pdev); | 4375 | pci_restore_state(pdev); |
| 4376 | /* | ||
| 4377 | * pci_restore_state clears dev->state_saved so call | ||
| 4378 | * pci_save_state to restore it. | ||
| 4379 | */ | ||
| 4380 | pci_save_state(pdev); | ||
| 4376 | 4381 | ||
| 4377 | err = pci_enable_device_mem(pdev); | 4382 | err = pci_enable_device_mem(pdev); |
| 4378 | if (err) { | 4383 | if (err) { |
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index dcc67a35e8f2..e154677ff706 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c | |||
| @@ -45,6 +45,7 @@ static const char *const version = | |||
| 45 | #include <linux/crc32.h> | 45 | #include <linux/crc32.h> |
| 46 | #include <linux/netdevice.h> | 46 | #include <linux/netdevice.h> |
| 47 | #include <linux/etherdevice.h> | 47 | #include <linux/etherdevice.h> |
| 48 | #include <linux/if_ether.h> | ||
| 48 | #include <linux/skbuff.h> | 49 | #include <linux/skbuff.h> |
| 49 | #include <linux/spinlock.h> | 50 | #include <linux/spinlock.h> |
| 50 | #include <linux/moduleparam.h> | 51 | #include <linux/moduleparam.h> |
| @@ -1765,7 +1766,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) | |||
| 1765 | 1766 | ||
| 1766 | /* if the ethernet address is not valid, force to 00:00:00:00:00:00 */ | 1767 | /* if the ethernet address is not valid, force to 00:00:00:00:00:00 */ |
| 1767 | if (!is_valid_ether_addr(dev->perm_addr)) | 1768 | if (!is_valid_ether_addr(dev->perm_addr)) |
| 1768 | memset(dev->dev_addr, 0, sizeof(dev->dev_addr)); | 1769 | memset(dev->dev_addr, 0, ETH_ALEN); |
| 1769 | 1770 | ||
| 1770 | if (pcnet32_debug & NETIF_MSG_PROBE) { | 1771 | if (pcnet32_debug & NETIF_MSG_PROBE) { |
| 1771 | printk(" %pM", dev->dev_addr); | 1772 | printk(" %pM", dev->dev_addr); |
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index f983e3b507cc..103e8b0e2a0d 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
| @@ -741,14 +741,14 @@ static int efx_probe_port(struct efx_nic *efx) | |||
| 741 | 741 | ||
| 742 | EFX_LOG(efx, "create port\n"); | 742 | EFX_LOG(efx, "create port\n"); |
| 743 | 743 | ||
| 744 | if (phy_flash_cfg) | ||
| 745 | efx->phy_mode = PHY_MODE_SPECIAL; | ||
| 746 | |||
| 744 | /* Connect up MAC/PHY operations table */ | 747 | /* Connect up MAC/PHY operations table */ |
| 745 | rc = efx->type->probe_port(efx); | 748 | rc = efx->type->probe_port(efx); |
| 746 | if (rc) | 749 | if (rc) |
| 747 | goto err; | 750 | goto err; |
| 748 | 751 | ||
| 749 | if (phy_flash_cfg) | ||
| 750 | efx->phy_mode = PHY_MODE_SPECIAL; | ||
| 751 | |||
| 752 | /* Sanity check MAC address */ | 752 | /* Sanity check MAC address */ |
| 753 | if (is_valid_ether_addr(efx->mac_address)) { | 753 | if (is_valid_ether_addr(efx->mac_address)) { |
| 754 | memcpy(efx->net_dev->dev_addr, efx->mac_address, ETH_ALEN); | 754 | memcpy(efx->net_dev->dev_addr, efx->mac_address, ETH_ALEN); |
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 17afcd26e870..9d009c46e962 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c | |||
| @@ -925,6 +925,7 @@ static int falcon_probe_port(struct efx_nic *efx) | |||
| 925 | 925 | ||
| 926 | static void falcon_remove_port(struct efx_nic *efx) | 926 | static void falcon_remove_port(struct efx_nic *efx) |
| 927 | { | 927 | { |
| 928 | efx->phy_op->remove(efx); | ||
| 928 | efx_nic_free_buffer(efx, &efx->stats_buffer); | 929 | efx_nic_free_buffer(efx, &efx->stats_buffer); |
| 929 | } | 930 | } |
| 930 | 931 | ||
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index 3da933f8f079..8ccab2c67a20 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c | |||
| @@ -111,16 +111,12 @@ static void falcon_mask_status_intr(struct efx_nic *efx, bool enable) | |||
| 111 | efx_writeo(efx, ®, FR_AB_XM_MGT_INT_MASK); | 111 | efx_writeo(efx, ®, FR_AB_XM_MGT_INT_MASK); |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | /* Get status of XAUI link */ | 114 | static bool falcon_xgxs_link_ok(struct efx_nic *efx) |
| 115 | static bool falcon_xaui_link_ok(struct efx_nic *efx) | ||
| 116 | { | 115 | { |
| 117 | efx_oword_t reg; | 116 | efx_oword_t reg; |
| 118 | bool align_done, link_ok = false; | 117 | bool align_done, link_ok = false; |
| 119 | int sync_status; | 118 | int sync_status; |
| 120 | 119 | ||
| 121 | if (LOOPBACK_INTERNAL(efx)) | ||
| 122 | return true; | ||
| 123 | |||
| 124 | /* Read link status */ | 120 | /* Read link status */ |
| 125 | efx_reado(efx, ®, FR_AB_XX_CORE_STAT); | 121 | efx_reado(efx, ®, FR_AB_XX_CORE_STAT); |
| 126 | 122 | ||
| @@ -135,14 +131,24 @@ static bool falcon_xaui_link_ok(struct efx_nic *efx) | |||
| 135 | EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_DISPERR, FFE_AB_XX_STAT_ALL_LANES); | 131 | EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_DISPERR, FFE_AB_XX_STAT_ALL_LANES); |
| 136 | efx_writeo(efx, ®, FR_AB_XX_CORE_STAT); | 132 | efx_writeo(efx, ®, FR_AB_XX_CORE_STAT); |
| 137 | 133 | ||
| 138 | /* If the link is up, then check the phy side of the xaui link */ | ||
| 139 | if (efx->link_state.up && link_ok) | ||
| 140 | if (efx->mdio.mmds & (1 << MDIO_MMD_PHYXS)) | ||
| 141 | link_ok = efx_mdio_phyxgxs_lane_sync(efx); | ||
| 142 | |||
| 143 | return link_ok; | 134 | return link_ok; |
| 144 | } | 135 | } |
| 145 | 136 | ||
| 137 | static bool falcon_xmac_link_ok(struct efx_nic *efx) | ||
| 138 | { | ||
| 139 | /* | ||
| 140 | * Check MAC's XGXS link status except when using XGMII loopback | ||
| 141 | * which bypasses the XGXS block. | ||
| 142 | * If possible, check PHY's XGXS link status except when using | ||
| 143 | * MAC loopback. | ||
| 144 | */ | ||
| 145 | return (efx->loopback_mode == LOOPBACK_XGMII || | ||
| 146 | falcon_xgxs_link_ok(efx)) && | ||
| 147 | (!(efx->mdio.mmds & (1 << MDIO_MMD_PHYXS)) || | ||
| 148 | LOOPBACK_INTERNAL(efx) || | ||
| 149 | efx_mdio_phyxgxs_lane_sync(efx)); | ||
| 150 | } | ||
| 151 | |||
| 146 | void falcon_reconfigure_xmac_core(struct efx_nic *efx) | 152 | void falcon_reconfigure_xmac_core(struct efx_nic *efx) |
| 147 | { | 153 | { |
| 148 | unsigned int max_frame_len; | 154 | unsigned int max_frame_len; |
| @@ -245,9 +251,9 @@ static void falcon_reconfigure_xgxs_core(struct efx_nic *efx) | |||
| 245 | 251 | ||
| 246 | 252 | ||
| 247 | /* Try to bring up the Falcon side of the Falcon-Phy XAUI link */ | 253 | /* Try to bring up the Falcon side of the Falcon-Phy XAUI link */ |
| 248 | static bool falcon_check_xaui_link_up(struct efx_nic *efx, int tries) | 254 | static bool falcon_xmac_link_ok_retry(struct efx_nic *efx, int tries) |
| 249 | { | 255 | { |
| 250 | bool mac_up = falcon_xaui_link_ok(efx); | 256 | bool mac_up = falcon_xmac_link_ok(efx); |
| 251 | 257 | ||
| 252 | if (LOOPBACK_MASK(efx) & LOOPBACKS_EXTERNAL(efx) & LOOPBACKS_WS || | 258 | if (LOOPBACK_MASK(efx) & LOOPBACKS_EXTERNAL(efx) & LOOPBACKS_WS || |
| 253 | efx_phy_mode_disabled(efx->phy_mode)) | 259 | efx_phy_mode_disabled(efx->phy_mode)) |
| @@ -261,7 +267,7 @@ static bool falcon_check_xaui_link_up(struct efx_nic *efx, int tries) | |||
| 261 | falcon_reset_xaui(efx); | 267 | falcon_reset_xaui(efx); |
| 262 | udelay(200); | 268 | udelay(200); |
| 263 | 269 | ||
| 264 | mac_up = falcon_xaui_link_ok(efx); | 270 | mac_up = falcon_xmac_link_ok(efx); |
| 265 | --tries; | 271 | --tries; |
| 266 | } | 272 | } |
| 267 | 273 | ||
| @@ -272,7 +278,7 @@ static bool falcon_check_xaui_link_up(struct efx_nic *efx, int tries) | |||
| 272 | 278 | ||
| 273 | static bool falcon_xmac_check_fault(struct efx_nic *efx) | 279 | static bool falcon_xmac_check_fault(struct efx_nic *efx) |
| 274 | { | 280 | { |
| 275 | return !falcon_check_xaui_link_up(efx, 5); | 281 | return !falcon_xmac_link_ok_retry(efx, 5); |
| 276 | } | 282 | } |
| 277 | 283 | ||
| 278 | static int falcon_reconfigure_xmac(struct efx_nic *efx) | 284 | static int falcon_reconfigure_xmac(struct efx_nic *efx) |
| @@ -284,7 +290,7 @@ static int falcon_reconfigure_xmac(struct efx_nic *efx) | |||
| 284 | 290 | ||
| 285 | falcon_reconfigure_mac_wrapper(efx); | 291 | falcon_reconfigure_mac_wrapper(efx); |
| 286 | 292 | ||
| 287 | efx->xmac_poll_required = !falcon_check_xaui_link_up(efx, 5); | 293 | efx->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 5); |
| 288 | falcon_mask_status_intr(efx, true); | 294 | falcon_mask_status_intr(efx, true); |
| 289 | 295 | ||
| 290 | return 0; | 296 | return 0; |
| @@ -357,7 +363,7 @@ void falcon_poll_xmac(struct efx_nic *efx) | |||
| 357 | return; | 363 | return; |
| 358 | 364 | ||
| 359 | falcon_mask_status_intr(efx, false); | 365 | falcon_mask_status_intr(efx, false); |
| 360 | efx->xmac_poll_required = !falcon_check_xaui_link_up(efx, 1); | 366 | efx->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 1); |
| 361 | falcon_mask_status_intr(efx, true); | 367 | falcon_mask_status_intr(efx, true); |
| 362 | } | 368 | } |
| 363 | 369 | ||
diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c index 0e1bcc5a0d52..eb694af7a473 100644 --- a/drivers/net/sfc/mcdi_phy.c +++ b/drivers/net/sfc/mcdi_phy.c | |||
| @@ -304,31 +304,47 @@ static u32 mcdi_to_ethtool_media(u32 media) | |||
| 304 | 304 | ||
| 305 | static int efx_mcdi_phy_probe(struct efx_nic *efx) | 305 | static int efx_mcdi_phy_probe(struct efx_nic *efx) |
| 306 | { | 306 | { |
| 307 | struct efx_mcdi_phy_cfg *phy_cfg; | 307 | struct efx_mcdi_phy_cfg *phy_data; |
| 308 | u8 outbuf[MC_CMD_GET_LINK_OUT_LEN]; | ||
| 309 | u32 caps; | ||
| 308 | int rc; | 310 | int rc; |
| 309 | 311 | ||
| 310 | /* TODO: Move phy_data initialisation to | 312 | /* Initialise and populate phy_data */ |
| 311 | * phy_op->probe/remove, rather than init/fini */ | 313 | phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); |
| 312 | phy_cfg = kzalloc(sizeof(*phy_cfg), GFP_KERNEL); | 314 | if (phy_data == NULL) |
| 313 | if (phy_cfg == NULL) { | 315 | return -ENOMEM; |
| 314 | rc = -ENOMEM; | 316 | |
| 315 | goto fail_alloc; | 317 | rc = efx_mcdi_get_phy_cfg(efx, phy_data); |
| 316 | } | ||
| 317 | rc = efx_mcdi_get_phy_cfg(efx, phy_cfg); | ||
| 318 | if (rc != 0) | 318 | if (rc != 0) |
| 319 | goto fail; | 319 | goto fail; |
| 320 | 320 | ||
| 321 | efx->phy_type = phy_cfg->type; | 321 | /* Read initial link advertisement */ |
| 322 | BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0); | ||
| 323 | rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, | ||
| 324 | outbuf, sizeof(outbuf), NULL); | ||
| 325 | if (rc) | ||
| 326 | goto fail; | ||
| 327 | |||
| 328 | /* Fill out nic state */ | ||
| 329 | efx->phy_data = phy_data; | ||
| 330 | efx->phy_type = phy_data->type; | ||
| 322 | 331 | ||
| 323 | efx->mdio_bus = phy_cfg->channel; | 332 | efx->mdio_bus = phy_data->channel; |
| 324 | efx->mdio.prtad = phy_cfg->port; | 333 | efx->mdio.prtad = phy_data->port; |
| 325 | efx->mdio.mmds = phy_cfg->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22); | 334 | efx->mdio.mmds = phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22); |
| 326 | efx->mdio.mode_support = 0; | 335 | efx->mdio.mode_support = 0; |
| 327 | if (phy_cfg->mmd_mask & (1 << MC_CMD_MMD_CLAUSE22)) | 336 | if (phy_data->mmd_mask & (1 << MC_CMD_MMD_CLAUSE22)) |
| 328 | efx->mdio.mode_support |= MDIO_SUPPORTS_C22; | 337 | efx->mdio.mode_support |= MDIO_SUPPORTS_C22; |
| 329 | if (phy_cfg->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22)) | 338 | if (phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22)) |
| 330 | efx->mdio.mode_support |= MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; | 339 | efx->mdio.mode_support |= MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; |
| 331 | 340 | ||
| 341 | caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP); | ||
| 342 | if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN)) | ||
| 343 | efx->link_advertising = | ||
| 344 | mcdi_to_ethtool_cap(phy_data->media, caps); | ||
| 345 | else | ||
| 346 | phy_data->forced_cap = caps; | ||
| 347 | |||
| 332 | /* Assert that we can map efx -> mcdi loopback modes */ | 348 | /* Assert that we can map efx -> mcdi loopback modes */ |
| 333 | BUILD_BUG_ON(LOOPBACK_NONE != MC_CMD_LOOPBACK_NONE); | 349 | BUILD_BUG_ON(LOOPBACK_NONE != MC_CMD_LOOPBACK_NONE); |
| 334 | BUILD_BUG_ON(LOOPBACK_DATA != MC_CMD_LOOPBACK_DATA); | 350 | BUILD_BUG_ON(LOOPBACK_DATA != MC_CMD_LOOPBACK_DATA); |
| @@ -365,46 +381,6 @@ static int efx_mcdi_phy_probe(struct efx_nic *efx) | |||
| 365 | * but by convention we don't */ | 381 | * but by convention we don't */ |
| 366 | efx->loopback_modes &= ~(1 << LOOPBACK_NONE); | 382 | efx->loopback_modes &= ~(1 << LOOPBACK_NONE); |
| 367 | 383 | ||
| 368 | kfree(phy_cfg); | ||
| 369 | |||
| 370 | return 0; | ||
| 371 | |||
| 372 | fail: | ||
| 373 | kfree(phy_cfg); | ||
| 374 | fail_alloc: | ||
| 375 | return rc; | ||
| 376 | } | ||
| 377 | |||
| 378 | static int efx_mcdi_phy_init(struct efx_nic *efx) | ||
| 379 | { | ||
| 380 | struct efx_mcdi_phy_cfg *phy_data; | ||
| 381 | u8 outbuf[MC_CMD_GET_LINK_OUT_LEN]; | ||
| 382 | u32 caps; | ||
| 383 | int rc; | ||
| 384 | |||
| 385 | phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); | ||
| 386 | if (phy_data == NULL) | ||
| 387 | return -ENOMEM; | ||
| 388 | |||
| 389 | rc = efx_mcdi_get_phy_cfg(efx, phy_data); | ||
| 390 | if (rc != 0) | ||
| 391 | goto fail; | ||
| 392 | |||
| 393 | efx->phy_data = phy_data; | ||
| 394 | |||
| 395 | BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0); | ||
| 396 | rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, | ||
| 397 | outbuf, sizeof(outbuf), NULL); | ||
| 398 | if (rc) | ||
| 399 | goto fail; | ||
| 400 | |||
| 401 | caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP); | ||
| 402 | if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN)) | ||
| 403 | efx->link_advertising = | ||
| 404 | mcdi_to_ethtool_cap(phy_data->media, caps); | ||
| 405 | else | ||
| 406 | phy_data->forced_cap = caps; | ||
| 407 | |||
| 408 | return 0; | 384 | return 0; |
| 409 | 385 | ||
| 410 | fail: | 386 | fail: |
| @@ -504,7 +480,7 @@ static bool efx_mcdi_phy_poll(struct efx_nic *efx) | |||
| 504 | return !efx_link_state_equal(&efx->link_state, &old_state); | 480 | return !efx_link_state_equal(&efx->link_state, &old_state); |
| 505 | } | 481 | } |
| 506 | 482 | ||
| 507 | static void efx_mcdi_phy_fini(struct efx_nic *efx) | 483 | static void efx_mcdi_phy_remove(struct efx_nic *efx) |
| 508 | { | 484 | { |
| 509 | struct efx_mcdi_phy_data *phy_data = efx->phy_data; | 485 | struct efx_mcdi_phy_data *phy_data = efx->phy_data; |
| 510 | 486 | ||
| @@ -586,10 +562,11 @@ static int efx_mcdi_phy_set_settings(struct efx_nic *efx, struct ethtool_cmd *ec | |||
| 586 | 562 | ||
| 587 | struct efx_phy_operations efx_mcdi_phy_ops = { | 563 | struct efx_phy_operations efx_mcdi_phy_ops = { |
| 588 | .probe = efx_mcdi_phy_probe, | 564 | .probe = efx_mcdi_phy_probe, |
| 589 | .init = efx_mcdi_phy_init, | 565 | .init = efx_port_dummy_op_int, |
| 590 | .reconfigure = efx_mcdi_phy_reconfigure, | 566 | .reconfigure = efx_mcdi_phy_reconfigure, |
| 591 | .poll = efx_mcdi_phy_poll, | 567 | .poll = efx_mcdi_phy_poll, |
| 592 | .fini = efx_mcdi_phy_fini, | 568 | .fini = efx_port_dummy_op_void, |
| 569 | .remove = efx_mcdi_phy_remove, | ||
| 593 | .get_settings = efx_mcdi_phy_get_settings, | 570 | .get_settings = efx_mcdi_phy_get_settings, |
| 594 | .set_settings = efx_mcdi_phy_set_settings, | 571 | .set_settings = efx_mcdi_phy_set_settings, |
| 595 | .run_tests = NULL, | 572 | .run_tests = NULL, |
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 34c381f009b7..d5aab5b3fa06 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
| @@ -524,6 +524,7 @@ struct efx_phy_operations { | |||
| 524 | int (*probe) (struct efx_nic *efx); | 524 | int (*probe) (struct efx_nic *efx); |
| 525 | int (*init) (struct efx_nic *efx); | 525 | int (*init) (struct efx_nic *efx); |
| 526 | void (*fini) (struct efx_nic *efx); | 526 | void (*fini) (struct efx_nic *efx); |
| 527 | void (*remove) (struct efx_nic *efx); | ||
| 527 | int (*reconfigure) (struct efx_nic *efx); | 528 | int (*reconfigure) (struct efx_nic *efx); |
| 528 | bool (*poll) (struct efx_nic *efx); | 529 | bool (*poll) (struct efx_nic *efx); |
| 529 | void (*get_settings) (struct efx_nic *efx, | 530 | void (*get_settings) (struct efx_nic *efx, |
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index a577be227862..db44224ed2ca 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c | |||
| @@ -1576,6 +1576,8 @@ void efx_nic_init_common(struct efx_nic *efx) | |||
| 1576 | EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_SOFT_EVT_EN, 1); | 1576 | EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_SOFT_EVT_EN, 1); |
| 1577 | /* Prefetch threshold 2 => fetch when descriptor cache half empty */ | 1577 | /* Prefetch threshold 2 => fetch when descriptor cache half empty */ |
| 1578 | EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PREF_THRESHOLD, 2); | 1578 | EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PREF_THRESHOLD, 2); |
| 1579 | /* Disable hardware watchdog which can misfire */ | ||
| 1580 | EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PREF_WD_TMR, 0x3fffff); | ||
| 1579 | /* Squash TX of packets of 16 bytes or less */ | 1581 | /* Squash TX of packets of 16 bytes or less */ |
| 1580 | if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) | 1582 | if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) |
| 1581 | EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); | 1583 | EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); |
diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c index 3800fc791b2f..ff8f0a417fa3 100644 --- a/drivers/net/sfc/qt202x_phy.c +++ b/drivers/net/sfc/qt202x_phy.c | |||
| @@ -33,6 +33,9 @@ | |||
| 33 | #define PCS_FW_HEARTBEAT_REG 0xd7ee | 33 | #define PCS_FW_HEARTBEAT_REG 0xd7ee |
| 34 | #define PCS_FW_HEARTB_LBN 0 | 34 | #define PCS_FW_HEARTB_LBN 0 |
| 35 | #define PCS_FW_HEARTB_WIDTH 8 | 35 | #define PCS_FW_HEARTB_WIDTH 8 |
| 36 | #define PCS_FW_PRODUCT_CODE_1 0xd7f0 | ||
| 37 | #define PCS_FW_VERSION_1 0xd7f3 | ||
| 38 | #define PCS_FW_BUILD_1 0xd7f6 | ||
| 36 | #define PCS_UC8051_STATUS_REG 0xd7fd | 39 | #define PCS_UC8051_STATUS_REG 0xd7fd |
| 37 | #define PCS_UC_STATUS_LBN 0 | 40 | #define PCS_UC_STATUS_LBN 0 |
| 38 | #define PCS_UC_STATUS_WIDTH 8 | 41 | #define PCS_UC_STATUS_WIDTH 8 |
| @@ -52,14 +55,24 @@ void falcon_qt202x_set_led(struct efx_nic *p, int led, int mode) | |||
| 52 | 55 | ||
| 53 | struct qt202x_phy_data { | 56 | struct qt202x_phy_data { |
| 54 | enum efx_phy_mode phy_mode; | 57 | enum efx_phy_mode phy_mode; |
| 58 | bool bug17190_in_bad_state; | ||
| 59 | unsigned long bug17190_timer; | ||
| 60 | u32 firmware_ver; | ||
| 55 | }; | 61 | }; |
| 56 | 62 | ||
| 57 | #define QT2022C2_MAX_RESET_TIME 500 | 63 | #define QT2022C2_MAX_RESET_TIME 500 |
| 58 | #define QT2022C2_RESET_WAIT 10 | 64 | #define QT2022C2_RESET_WAIT 10 |
| 59 | 65 | ||
| 60 | static int qt2025c_wait_reset(struct efx_nic *efx) | 66 | #define QT2025C_MAX_HEARTB_TIME (5 * HZ) |
| 67 | #define QT2025C_HEARTB_WAIT 100 | ||
| 68 | #define QT2025C_MAX_FWSTART_TIME (25 * HZ / 10) | ||
| 69 | #define QT2025C_FWSTART_WAIT 100 | ||
| 70 | |||
| 71 | #define BUG17190_INTERVAL (2 * HZ) | ||
| 72 | |||
| 73 | static int qt2025c_wait_heartbeat(struct efx_nic *efx) | ||
| 61 | { | 74 | { |
| 62 | unsigned long timeout = jiffies + 10 * HZ; | 75 | unsigned long timeout = jiffies + QT2025C_MAX_HEARTB_TIME; |
| 63 | int reg, old_counter = 0; | 76 | int reg, old_counter = 0; |
| 64 | 77 | ||
| 65 | /* Wait for firmware heartbeat to start */ | 78 | /* Wait for firmware heartbeat to start */ |
| @@ -74,11 +87,25 @@ static int qt2025c_wait_reset(struct efx_nic *efx) | |||
| 74 | old_counter = counter; | 87 | old_counter = counter; |
| 75 | else if (counter != old_counter) | 88 | else if (counter != old_counter) |
| 76 | break; | 89 | break; |
| 77 | if (time_after(jiffies, timeout)) | 90 | if (time_after(jiffies, timeout)) { |
| 91 | /* Some cables have EEPROMs that conflict with the | ||
| 92 | * PHY's on-board EEPROM so it cannot load firmware */ | ||
| 93 | EFX_ERR(efx, "If an SFP+ direct attach cable is" | ||
| 94 | " connected, please check that it complies" | ||
| 95 | " with the SFP+ specification\n"); | ||
| 78 | return -ETIMEDOUT; | 96 | return -ETIMEDOUT; |
| 79 | msleep(10); | 97 | } |
| 98 | msleep(QT2025C_HEARTB_WAIT); | ||
| 80 | } | 99 | } |
| 81 | 100 | ||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | |||
| 104 | static int qt2025c_wait_fw_status_good(struct efx_nic *efx) | ||
| 105 | { | ||
| 106 | unsigned long timeout = jiffies + QT2025C_MAX_FWSTART_TIME; | ||
| 107 | int reg; | ||
| 108 | |||
| 82 | /* Wait for firmware status to look good */ | 109 | /* Wait for firmware status to look good */ |
| 83 | for (;;) { | 110 | for (;;) { |
| 84 | reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_UC8051_STATUS_REG); | 111 | reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_UC8051_STATUS_REG); |
| @@ -90,7 +117,178 @@ static int qt2025c_wait_reset(struct efx_nic *efx) | |||
| 90 | break; | 117 | break; |
| 91 | if (time_after(jiffies, timeout)) | 118 | if (time_after(jiffies, timeout)) |
| 92 | return -ETIMEDOUT; | 119 | return -ETIMEDOUT; |
| 120 | msleep(QT2025C_FWSTART_WAIT); | ||
| 121 | } | ||
| 122 | |||
| 123 | return 0; | ||
| 124 | } | ||
| 125 | |||
| 126 | static void qt2025c_restart_firmware(struct efx_nic *efx) | ||
| 127 | { | ||
| 128 | /* Restart microcontroller execution of firmware from RAM */ | ||
| 129 | efx_mdio_write(efx, 3, 0xe854, 0x00c0); | ||
| 130 | efx_mdio_write(efx, 3, 0xe854, 0x0040); | ||
| 131 | msleep(50); | ||
| 132 | } | ||
| 133 | |||
| 134 | static int qt2025c_wait_reset(struct efx_nic *efx) | ||
| 135 | { | ||
| 136 | int rc; | ||
| 137 | |||
| 138 | rc = qt2025c_wait_heartbeat(efx); | ||
| 139 | if (rc != 0) | ||
| 140 | return rc; | ||
| 141 | |||
| 142 | rc = qt2025c_wait_fw_status_good(efx); | ||
| 143 | if (rc == -ETIMEDOUT) { | ||
| 144 | /* Bug 17689: occasionally heartbeat starts but firmware status | ||
| 145 | * code never progresses beyond 0x00. Try again, once, after | ||
| 146 | * restarting execution of the firmware image. */ | ||
| 147 | EFX_LOG(efx, "bashing QT2025C microcontroller\n"); | ||
| 148 | qt2025c_restart_firmware(efx); | ||
| 149 | rc = qt2025c_wait_heartbeat(efx); | ||
| 150 | if (rc != 0) | ||
| 151 | return rc; | ||
| 152 | rc = qt2025c_wait_fw_status_good(efx); | ||
| 153 | } | ||
| 154 | |||
| 155 | return rc; | ||
| 156 | } | ||
| 157 | |||
| 158 | static void qt2025c_firmware_id(struct efx_nic *efx) | ||
| 159 | { | ||
| 160 | struct qt202x_phy_data *phy_data = efx->phy_data; | ||
| 161 | u8 firmware_id[9]; | ||
| 162 | size_t i; | ||
| 163 | |||
| 164 | for (i = 0; i < sizeof(firmware_id); i++) | ||
| 165 | firmware_id[i] = efx_mdio_read(efx, MDIO_MMD_PCS, | ||
| 166 | PCS_FW_PRODUCT_CODE_1 + i); | ||
| 167 | EFX_INFO(efx, "QT2025C firmware %xr%d v%d.%d.%d.%d [20%02d-%02d-%02d]\n", | ||
| 168 | (firmware_id[0] << 8) | firmware_id[1], firmware_id[2], | ||
| 169 | firmware_id[3] >> 4, firmware_id[3] & 0xf, | ||
| 170 | firmware_id[4], firmware_id[5], | ||
| 171 | firmware_id[6], firmware_id[7], firmware_id[8]); | ||
| 172 | phy_data->firmware_ver = ((firmware_id[3] & 0xf0) << 20) | | ||
| 173 | ((firmware_id[3] & 0x0f) << 16) | | ||
| 174 | (firmware_id[4] << 8) | firmware_id[5]; | ||
| 175 | } | ||
| 176 | |||
| 177 | static void qt2025c_bug17190_workaround(struct efx_nic *efx) | ||
| 178 | { | ||
| 179 | struct qt202x_phy_data *phy_data = efx->phy_data; | ||
| 180 | |||
| 181 | /* The PHY can get stuck in a state where it reports PHY_XS and PMA/PMD | ||
| 182 | * layers up, but PCS down (no block_lock). If we notice this state | ||
| 183 | * persisting for a couple of seconds, we switch PMA/PMD loopback | ||
| 184 | * briefly on and then off again, which is normally sufficient to | ||
| 185 | * recover it. | ||
| 186 | */ | ||
| 187 | if (efx->link_state.up || | ||
| 188 | !efx_mdio_links_ok(efx, MDIO_DEVS_PMAPMD | MDIO_DEVS_PHYXS)) { | ||
| 189 | phy_data->bug17190_in_bad_state = false; | ||
| 190 | return; | ||
| 191 | } | ||
| 192 | |||
| 193 | if (!phy_data->bug17190_in_bad_state) { | ||
| 194 | phy_data->bug17190_in_bad_state = true; | ||
| 195 | phy_data->bug17190_timer = jiffies + BUG17190_INTERVAL; | ||
| 196 | return; | ||
| 197 | } | ||
| 198 | |||
| 199 | if (time_after_eq(jiffies, phy_data->bug17190_timer)) { | ||
| 200 | EFX_LOG(efx, "bashing QT2025C PMA/PMD\n"); | ||
| 201 | efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1, | ||
| 202 | MDIO_PMA_CTRL1_LOOPBACK, true); | ||
| 93 | msleep(100); | 203 | msleep(100); |
| 204 | efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1, | ||
| 205 | MDIO_PMA_CTRL1_LOOPBACK, false); | ||
| 206 | phy_data->bug17190_timer = jiffies + BUG17190_INTERVAL; | ||
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 210 | static int qt2025c_select_phy_mode(struct efx_nic *efx) | ||
| 211 | { | ||
| 212 | struct qt202x_phy_data *phy_data = efx->phy_data; | ||
| 213 | struct falcon_board *board = falcon_board(efx); | ||
| 214 | int reg, rc, i; | ||
| 215 | uint16_t phy_op_mode; | ||
| 216 | |||
| 217 | /* Only 2.0.1.0+ PHY firmware supports the more optimal SFP+ | ||
| 218 | * Self-Configure mode. Don't attempt any switching if we encounter | ||
| 219 | * older firmware. */ | ||
| 220 | if (phy_data->firmware_ver < 0x02000100) | ||
| 221 | return 0; | ||
| 222 | |||
| 223 | /* In general we will get optimal behaviour in "SFP+ Self-Configure" | ||
| 224 | * mode; however, that powers down most of the PHY when no module is | ||
| 225 | * present, so we must use a different mode (any fixed mode will do) | ||
| 226 | * to be sure that loopbacks will work. */ | ||
| 227 | phy_op_mode = (efx->loopback_mode == LOOPBACK_NONE) ? 0x0038 : 0x0020; | ||
| 228 | |||
| 229 | /* Only change mode if really necessary */ | ||
| 230 | reg = efx_mdio_read(efx, 1, 0xc319); | ||
| 231 | if ((reg & 0x0038) == phy_op_mode) | ||
| 232 | return 0; | ||
| 233 | EFX_LOG(efx, "Switching PHY to mode 0x%04x\n", phy_op_mode); | ||
| 234 | |||
| 235 | /* This sequence replicates the register writes configured in the boot | ||
| 236 | * EEPROM (including the differences between board revisions), except | ||
| 237 | * that the operating mode is changed, and the PHY is prevented from | ||
| 238 | * unnecessarily reloading the main firmware image again. */ | ||
| 239 | efx_mdio_write(efx, 1, 0xc300, 0x0000); | ||
| 240 | /* (Note: this portion of the boot EEPROM sequence, which bit-bashes 9 | ||
| 241 | * STOPs onto the firmware/module I2C bus to reset it, varies across | ||
| 242 | * board revisions, as the bus is connected to different GPIO/LED | ||
| 243 | * outputs on the PHY.) */ | ||
| 244 | if (board->major == 0 && board->minor < 2) { | ||
| 245 | efx_mdio_write(efx, 1, 0xc303, 0x4498); | ||
| 246 | for (i = 0; i < 9; i++) { | ||
| 247 | efx_mdio_write(efx, 1, 0xc303, 0x4488); | ||
| 248 | efx_mdio_write(efx, 1, 0xc303, 0x4480); | ||
| 249 | efx_mdio_write(efx, 1, 0xc303, 0x4490); | ||
| 250 | efx_mdio_write(efx, 1, 0xc303, 0x4498); | ||
| 251 | } | ||
| 252 | } else { | ||
| 253 | efx_mdio_write(efx, 1, 0xc303, 0x0920); | ||
| 254 | efx_mdio_write(efx, 1, 0xd008, 0x0004); | ||
| 255 | for (i = 0; i < 9; i++) { | ||
| 256 | efx_mdio_write(efx, 1, 0xc303, 0x0900); | ||
| 257 | efx_mdio_write(efx, 1, 0xd008, 0x0005); | ||
| 258 | efx_mdio_write(efx, 1, 0xc303, 0x0920); | ||
| 259 | efx_mdio_write(efx, 1, 0xd008, 0x0004); | ||
| 260 | } | ||
| 261 | efx_mdio_write(efx, 1, 0xc303, 0x4900); | ||
| 262 | } | ||
| 263 | efx_mdio_write(efx, 1, 0xc303, 0x4900); | ||
| 264 | efx_mdio_write(efx, 1, 0xc302, 0x0004); | ||
| 265 | efx_mdio_write(efx, 1, 0xc316, 0x0013); | ||
| 266 | efx_mdio_write(efx, 1, 0xc318, 0x0054); | ||
| 267 | efx_mdio_write(efx, 1, 0xc319, phy_op_mode); | ||
| 268 | efx_mdio_write(efx, 1, 0xc31a, 0x0098); | ||
| 269 | efx_mdio_write(efx, 3, 0x0026, 0x0e00); | ||
| 270 | efx_mdio_write(efx, 3, 0x0027, 0x0013); | ||
| 271 | efx_mdio_write(efx, 3, 0x0028, 0xa528); | ||
| 272 | efx_mdio_write(efx, 1, 0xd006, 0x000a); | ||
| 273 | efx_mdio_write(efx, 1, 0xd007, 0x0009); | ||
| 274 | efx_mdio_write(efx, 1, 0xd008, 0x0004); | ||
| 275 | /* This additional write is not present in the boot EEPROM. It | ||
| 276 | * prevents the PHY's internal boot ROM doing another pointless (and | ||
| 277 | * slow) reload of the firmware image (the microcontroller's code | ||
| 278 | * memory is not affected by the microcontroller reset). */ | ||
| 279 | efx_mdio_write(efx, 1, 0xc317, 0x00ff); | ||
| 280 | efx_mdio_write(efx, 1, 0xc300, 0x0002); | ||
| 281 | msleep(20); | ||
| 282 | |||
| 283 | /* Restart microcontroller execution of firmware from RAM */ | ||
| 284 | qt2025c_restart_firmware(efx); | ||
| 285 | |||
| 286 | /* Wait for the microcontroller to be ready again */ | ||
| 287 | rc = qt2025c_wait_reset(efx); | ||
| 288 | if (rc < 0) { | ||
| 289 | EFX_ERR(efx, "PHY microcontroller reset during mode switch " | ||
| 290 | "timed out\n"); | ||
| 291 | return rc; | ||
| 94 | } | 292 | } |
| 95 | 293 | ||
| 96 | return 0; | 294 | return 0; |
| @@ -137,6 +335,16 @@ static int qt202x_reset_phy(struct efx_nic *efx) | |||
| 137 | 335 | ||
| 138 | static int qt202x_phy_probe(struct efx_nic *efx) | 336 | static int qt202x_phy_probe(struct efx_nic *efx) |
| 139 | { | 337 | { |
| 338 | struct qt202x_phy_data *phy_data; | ||
| 339 | |||
| 340 | phy_data = kzalloc(sizeof(struct qt202x_phy_data), GFP_KERNEL); | ||
| 341 | if (!phy_data) | ||
| 342 | return -ENOMEM; | ||
| 343 | efx->phy_data = phy_data; | ||
| 344 | phy_data->phy_mode = efx->phy_mode; | ||
| 345 | phy_data->bug17190_in_bad_state = false; | ||
| 346 | phy_data->bug17190_timer = 0; | ||
| 347 | |||
| 140 | efx->mdio.mmds = QT202X_REQUIRED_DEVS; | 348 | efx->mdio.mmds = QT202X_REQUIRED_DEVS; |
| 141 | efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; | 349 | efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; |
| 142 | efx->loopback_modes = QT202X_LOOPBACKS | FALCON_XMAC_LOOPBACKS; | 350 | efx->loopback_modes = QT202X_LOOPBACKS | FALCON_XMAC_LOOPBACKS; |
| @@ -145,7 +353,6 @@ static int qt202x_phy_probe(struct efx_nic *efx) | |||
| 145 | 353 | ||
| 146 | static int qt202x_phy_init(struct efx_nic *efx) | 354 | static int qt202x_phy_init(struct efx_nic *efx) |
| 147 | { | 355 | { |
| 148 | struct qt202x_phy_data *phy_data; | ||
| 149 | u32 devid; | 356 | u32 devid; |
| 150 | int rc; | 357 | int rc; |
| 151 | 358 | ||
| @@ -155,17 +362,14 @@ static int qt202x_phy_init(struct efx_nic *efx) | |||
| 155 | return rc; | 362 | return rc; |
| 156 | } | 363 | } |
| 157 | 364 | ||
| 158 | phy_data = kzalloc(sizeof(struct qt202x_phy_data), GFP_KERNEL); | ||
| 159 | if (!phy_data) | ||
| 160 | return -ENOMEM; | ||
| 161 | efx->phy_data = phy_data; | ||
| 162 | |||
| 163 | devid = efx_mdio_read_id(efx, MDIO_MMD_PHYXS); | 365 | devid = efx_mdio_read_id(efx, MDIO_MMD_PHYXS); |
| 164 | EFX_INFO(efx, "PHY ID reg %x (OUI %06x model %02x revision %x)\n", | 366 | EFX_INFO(efx, "PHY ID reg %x (OUI %06x model %02x revision %x)\n", |
| 165 | devid, efx_mdio_id_oui(devid), efx_mdio_id_model(devid), | 367 | devid, efx_mdio_id_oui(devid), efx_mdio_id_model(devid), |
| 166 | efx_mdio_id_rev(devid)); | 368 | efx_mdio_id_rev(devid)); |
| 167 | 369 | ||
| 168 | phy_data->phy_mode = efx->phy_mode; | 370 | if (efx->phy_type == PHY_TYPE_QT2025C) |
| 371 | qt2025c_firmware_id(efx); | ||
| 372 | |||
| 169 | return 0; | 373 | return 0; |
| 170 | } | 374 | } |
| 171 | 375 | ||
| @@ -183,6 +387,9 @@ static bool qt202x_phy_poll(struct efx_nic *efx) | |||
| 183 | efx->link_state.fd = true; | 387 | efx->link_state.fd = true; |
| 184 | efx->link_state.fc = efx->wanted_fc; | 388 | efx->link_state.fc = efx->wanted_fc; |
| 185 | 389 | ||
| 390 | if (efx->phy_type == PHY_TYPE_QT2025C) | ||
| 391 | qt2025c_bug17190_workaround(efx); | ||
| 392 | |||
| 186 | return efx->link_state.up != was_up; | 393 | return efx->link_state.up != was_up; |
| 187 | } | 394 | } |
| 188 | 395 | ||
| @@ -191,6 +398,10 @@ static int qt202x_phy_reconfigure(struct efx_nic *efx) | |||
| 191 | struct qt202x_phy_data *phy_data = efx->phy_data; | 398 | struct qt202x_phy_data *phy_data = efx->phy_data; |
| 192 | 399 | ||
| 193 | if (efx->phy_type == PHY_TYPE_QT2025C) { | 400 | if (efx->phy_type == PHY_TYPE_QT2025C) { |
| 401 | int rc = qt2025c_select_phy_mode(efx); | ||
| 402 | if (rc) | ||
| 403 | return rc; | ||
| 404 | |||
| 194 | /* There are several different register bits which can | 405 | /* There are several different register bits which can |
| 195 | * disable TX (and save power) on direct-attach cables | 406 | * disable TX (and save power) on direct-attach cables |
| 196 | * or optical transceivers, varying somewhat between | 407 | * or optical transceivers, varying somewhat between |
| @@ -224,7 +435,7 @@ static void qt202x_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecm | |||
| 224 | mdio45_ethtool_gset(&efx->mdio, ecmd); | 435 | mdio45_ethtool_gset(&efx->mdio, ecmd); |
| 225 | } | 436 | } |
| 226 | 437 | ||
| 227 | static void qt202x_phy_fini(struct efx_nic *efx) | 438 | static void qt202x_phy_remove(struct efx_nic *efx) |
| 228 | { | 439 | { |
| 229 | /* Free the context block */ | 440 | /* Free the context block */ |
| 230 | kfree(efx->phy_data); | 441 | kfree(efx->phy_data); |
| @@ -236,7 +447,8 @@ struct efx_phy_operations falcon_qt202x_phy_ops = { | |||
| 236 | .init = qt202x_phy_init, | 447 | .init = qt202x_phy_init, |
| 237 | .reconfigure = qt202x_phy_reconfigure, | 448 | .reconfigure = qt202x_phy_reconfigure, |
| 238 | .poll = qt202x_phy_poll, | 449 | .poll = qt202x_phy_poll, |
| 239 | .fini = qt202x_phy_fini, | 450 | .fini = efx_port_dummy_op_void, |
| 451 | .remove = qt202x_phy_remove, | ||
| 240 | .get_settings = qt202x_phy_get_settings, | 452 | .get_settings = qt202x_phy_get_settings, |
| 241 | .set_settings = efx_mdio_set_settings, | 453 | .set_settings = efx_mdio_set_settings, |
| 242 | }; | 454 | }; |
diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index de07a4f031b2..f8c6771e66d8 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c | |||
| @@ -133,6 +133,7 @@ static int siena_probe_port(struct efx_nic *efx) | |||
| 133 | 133 | ||
| 134 | void siena_remove_port(struct efx_nic *efx) | 134 | void siena_remove_port(struct efx_nic *efx) |
| 135 | { | 135 | { |
| 136 | efx->phy_op->remove(efx); | ||
| 136 | efx_nic_free_buffer(efx, &efx->stats_buffer); | 137 | efx_nic_free_buffer(efx, &efx->stats_buffer); |
| 137 | } | 138 | } |
| 138 | 139 | ||
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index ca11572a49a9..3009c297c135 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c | |||
| @@ -202,10 +202,14 @@ static ssize_t set_phy_short_reach(struct device *dev, | |||
| 202 | int rc; | 202 | int rc; |
| 203 | 203 | ||
| 204 | rtnl_lock(); | 204 | rtnl_lock(); |
| 205 | efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR, | 205 | if (efx->state != STATE_RUNNING) { |
| 206 | MDIO_PMA_10GBT_TXPWR_SHORT, | 206 | rc = -EBUSY; |
| 207 | count != 0 && *buf != '0'); | 207 | } else { |
| 208 | rc = efx_reconfigure_port(efx); | 208 | efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR, |
| 209 | MDIO_PMA_10GBT_TXPWR_SHORT, | ||
| 210 | count != 0 && *buf != '0'); | ||
| 211 | rc = efx_reconfigure_port(efx); | ||
| 212 | } | ||
| 209 | rtnl_unlock(); | 213 | rtnl_unlock(); |
| 210 | 214 | ||
| 211 | return rc < 0 ? rc : (ssize_t)count; | 215 | return rc < 0 ? rc : (ssize_t)count; |
| @@ -298,36 +302,62 @@ static int tenxpress_init(struct efx_nic *efx) | |||
| 298 | return 0; | 302 | return 0; |
| 299 | } | 303 | } |
| 300 | 304 | ||
| 301 | static int sfx7101_phy_probe(struct efx_nic *efx) | 305 | static int tenxpress_phy_probe(struct efx_nic *efx) |
| 302 | { | 306 | { |
| 303 | efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; | 307 | struct tenxpress_phy_data *phy_data; |
| 304 | efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; | 308 | int rc; |
| 305 | efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS; | 309 | |
| 306 | return 0; | 310 | /* Allocate phy private storage */ |
| 307 | } | 311 | phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); |
| 312 | if (!phy_data) | ||
| 313 | return -ENOMEM; | ||
| 314 | efx->phy_data = phy_data; | ||
| 315 | phy_data->phy_mode = efx->phy_mode; | ||
| 316 | |||
| 317 | /* Create any special files */ | ||
| 318 | if (efx->phy_type == PHY_TYPE_SFT9001B) { | ||
| 319 | rc = device_create_file(&efx->pci_dev->dev, | ||
| 320 | &dev_attr_phy_short_reach); | ||
| 321 | if (rc) | ||
| 322 | goto fail; | ||
| 323 | } | ||
| 324 | |||
| 325 | if (efx->phy_type == PHY_TYPE_SFX7101) { | ||
| 326 | efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; | ||
| 327 | efx->mdio.mode_support = MDIO_SUPPORTS_C45; | ||
| 328 | |||
| 329 | efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS; | ||
| 330 | |||
| 331 | efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg | | ||
| 332 | ADVERTISED_10000baseT_Full); | ||
| 333 | } else { | ||
| 334 | efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; | ||
| 335 | efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; | ||
| 336 | |||
| 337 | efx->loopback_modes = (SFT9001_LOOPBACKS | | ||
| 338 | FALCON_XMAC_LOOPBACKS | | ||
| 339 | FALCON_GMAC_LOOPBACKS); | ||
| 340 | |||
| 341 | efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg | | ||
| 342 | ADVERTISED_10000baseT_Full | | ||
| 343 | ADVERTISED_1000baseT_Full | | ||
| 344 | ADVERTISED_100baseT_Full); | ||
| 345 | } | ||
| 308 | 346 | ||
| 309 | static int sft9001_phy_probe(struct efx_nic *efx) | ||
| 310 | { | ||
| 311 | efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; | ||
| 312 | efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; | ||
| 313 | efx->loopback_modes = (SFT9001_LOOPBACKS | FALCON_XMAC_LOOPBACKS | | ||
| 314 | FALCON_GMAC_LOOPBACKS); | ||
| 315 | return 0; | 347 | return 0; |
| 348 | |||
| 349 | fail: | ||
| 350 | kfree(efx->phy_data); | ||
| 351 | efx->phy_data = NULL; | ||
| 352 | return rc; | ||
| 316 | } | 353 | } |
| 317 | 354 | ||
| 318 | static int tenxpress_phy_init(struct efx_nic *efx) | 355 | static int tenxpress_phy_init(struct efx_nic *efx) |
| 319 | { | 356 | { |
| 320 | struct tenxpress_phy_data *phy_data; | 357 | int rc; |
| 321 | int rc = 0; | ||
| 322 | 358 | ||
| 323 | falcon_board(efx)->type->init_phy(efx); | 359 | falcon_board(efx)->type->init_phy(efx); |
| 324 | 360 | ||
| 325 | phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); | ||
| 326 | if (!phy_data) | ||
| 327 | return -ENOMEM; | ||
| 328 | efx->phy_data = phy_data; | ||
| 329 | phy_data->phy_mode = efx->phy_mode; | ||
| 330 | |||
| 331 | if (!(efx->phy_mode & PHY_MODE_SPECIAL)) { | 361 | if (!(efx->phy_mode & PHY_MODE_SPECIAL)) { |
| 332 | if (efx->phy_type == PHY_TYPE_SFT9001A) { | 362 | if (efx->phy_type == PHY_TYPE_SFT9001A) { |
| 333 | int reg; | 363 | int reg; |
| @@ -341,44 +371,27 @@ static int tenxpress_phy_init(struct efx_nic *efx) | |||
| 341 | 371 | ||
| 342 | rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); | 372 | rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); |
| 343 | if (rc < 0) | 373 | if (rc < 0) |
| 344 | goto fail; | 374 | return rc; |
| 345 | 375 | ||
| 346 | rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); | 376 | rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); |
| 347 | if (rc < 0) | 377 | if (rc < 0) |
| 348 | goto fail; | 378 | return rc; |
| 349 | } | 379 | } |
| 350 | 380 | ||
| 351 | rc = tenxpress_init(efx); | 381 | rc = tenxpress_init(efx); |
| 352 | if (rc < 0) | 382 | if (rc < 0) |
| 353 | goto fail; | 383 | return rc; |
| 354 | 384 | ||
| 355 | /* Initialise advertising flags */ | 385 | /* Reinitialise flow control settings */ |
| 356 | efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg | | ||
| 357 | ADVERTISED_10000baseT_Full); | ||
| 358 | if (efx->phy_type != PHY_TYPE_SFX7101) | ||
| 359 | efx->link_advertising |= (ADVERTISED_1000baseT_Full | | ||
| 360 | ADVERTISED_100baseT_Full); | ||
| 361 | efx_link_set_wanted_fc(efx, efx->wanted_fc); | 386 | efx_link_set_wanted_fc(efx, efx->wanted_fc); |
| 362 | efx_mdio_an_reconfigure(efx); | 387 | efx_mdio_an_reconfigure(efx); |
| 363 | 388 | ||
| 364 | if (efx->phy_type == PHY_TYPE_SFT9001B) { | ||
| 365 | rc = device_create_file(&efx->pci_dev->dev, | ||
| 366 | &dev_attr_phy_short_reach); | ||
| 367 | if (rc) | ||
| 368 | goto fail; | ||
| 369 | } | ||
| 370 | |||
| 371 | schedule_timeout_uninterruptible(HZ / 5); /* 200ms */ | 389 | schedule_timeout_uninterruptible(HZ / 5); /* 200ms */ |
| 372 | 390 | ||
| 373 | /* Let XGXS and SerDes out of reset */ | 391 | /* Let XGXS and SerDes out of reset */ |
| 374 | falcon_reset_xaui(efx); | 392 | falcon_reset_xaui(efx); |
| 375 | 393 | ||
| 376 | return 0; | 394 | return 0; |
| 377 | |||
| 378 | fail: | ||
| 379 | kfree(efx->phy_data); | ||
| 380 | efx->phy_data = NULL; | ||
| 381 | return rc; | ||
| 382 | } | 395 | } |
| 383 | 396 | ||
| 384 | /* Perform a "special software reset" on the PHY. The caller is | 397 | /* Perform a "special software reset" on the PHY. The caller is |
| @@ -589,25 +602,26 @@ static bool tenxpress_phy_poll(struct efx_nic *efx) | |||
| 589 | return !efx_link_state_equal(&efx->link_state, &old_state); | 602 | return !efx_link_state_equal(&efx->link_state, &old_state); |
| 590 | } | 603 | } |
| 591 | 604 | ||
| 592 | static void tenxpress_phy_fini(struct efx_nic *efx) | 605 | static void sfx7101_phy_fini(struct efx_nic *efx) |
| 593 | { | 606 | { |
| 594 | int reg; | 607 | int reg; |
| 595 | 608 | ||
| 609 | /* Power down the LNPGA */ | ||
| 610 | reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN); | ||
| 611 | efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg); | ||
| 612 | |||
| 613 | /* Waiting here ensures that the board fini, which can turn | ||
| 614 | * off the power to the PHY, won't get run until the LNPGA | ||
| 615 | * powerdown has been given long enough to complete. */ | ||
| 616 | schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */ | ||
| 617 | } | ||
| 618 | |||
| 619 | static void tenxpress_phy_remove(struct efx_nic *efx) | ||
| 620 | { | ||
| 596 | if (efx->phy_type == PHY_TYPE_SFT9001B) | 621 | if (efx->phy_type == PHY_TYPE_SFT9001B) |
| 597 | device_remove_file(&efx->pci_dev->dev, | 622 | device_remove_file(&efx->pci_dev->dev, |
| 598 | &dev_attr_phy_short_reach); | 623 | &dev_attr_phy_short_reach); |
| 599 | 624 | ||
| 600 | if (efx->phy_type == PHY_TYPE_SFX7101) { | ||
| 601 | /* Power down the LNPGA */ | ||
| 602 | reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN); | ||
| 603 | efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg); | ||
| 604 | |||
| 605 | /* Waiting here ensures that the board fini, which can turn | ||
| 606 | * off the power to the PHY, won't get run until the LNPGA | ||
| 607 | * powerdown has been given long enough to complete. */ | ||
| 608 | schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */ | ||
| 609 | } | ||
| 610 | |||
| 611 | kfree(efx->phy_data); | 625 | kfree(efx->phy_data); |
| 612 | efx->phy_data = NULL; | 626 | efx->phy_data = NULL; |
| 613 | } | 627 | } |
| @@ -819,11 +833,12 @@ static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising) | |||
| 819 | } | 833 | } |
| 820 | 834 | ||
| 821 | struct efx_phy_operations falcon_sfx7101_phy_ops = { | 835 | struct efx_phy_operations falcon_sfx7101_phy_ops = { |
| 822 | .probe = sfx7101_phy_probe, | 836 | .probe = tenxpress_phy_probe, |
| 823 | .init = tenxpress_phy_init, | 837 | .init = tenxpress_phy_init, |
| 824 | .reconfigure = tenxpress_phy_reconfigure, | 838 | .reconfigure = tenxpress_phy_reconfigure, |
| 825 | .poll = tenxpress_phy_poll, | 839 | .poll = tenxpress_phy_poll, |
| 826 | .fini = tenxpress_phy_fini, | 840 | .fini = sfx7101_phy_fini, |
| 841 | .remove = tenxpress_phy_remove, | ||
| 827 | .get_settings = tenxpress_get_settings, | 842 | .get_settings = tenxpress_get_settings, |
| 828 | .set_settings = tenxpress_set_settings, | 843 | .set_settings = tenxpress_set_settings, |
| 829 | .set_npage_adv = sfx7101_set_npage_adv, | 844 | .set_npage_adv = sfx7101_set_npage_adv, |
| @@ -832,11 +847,12 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = { | |||
| 832 | }; | 847 | }; |
| 833 | 848 | ||
| 834 | struct efx_phy_operations falcon_sft9001_phy_ops = { | 849 | struct efx_phy_operations falcon_sft9001_phy_ops = { |
| 835 | .probe = sft9001_phy_probe, | 850 | .probe = tenxpress_phy_probe, |
| 836 | .init = tenxpress_phy_init, | 851 | .init = tenxpress_phy_init, |
| 837 | .reconfigure = tenxpress_phy_reconfigure, | 852 | .reconfigure = tenxpress_phy_reconfigure, |
| 838 | .poll = tenxpress_phy_poll, | 853 | .poll = tenxpress_phy_poll, |
| 839 | .fini = tenxpress_phy_fini, | 854 | .fini = efx_port_dummy_op_void, |
| 855 | .remove = tenxpress_phy_remove, | ||
| 840 | .get_settings = tenxpress_get_settings, | 856 | .get_settings = tenxpress_get_settings, |
| 841 | .set_settings = tenxpress_set_settings, | 857 | .set_settings = tenxpress_set_settings, |
| 842 | .set_npage_adv = sft9001_set_npage_adv, | 858 | .set_npage_adv = sft9001_set_npage_adv, |
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index e669f94e821b..a8b70ef6d817 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c | |||
| @@ -821,8 +821,6 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue) | |||
| 821 | EFX_TXQ_MASK]; | 821 | EFX_TXQ_MASK]; |
| 822 | efx_tsoh_free(tx_queue, buffer); | 822 | efx_tsoh_free(tx_queue, buffer); |
| 823 | EFX_BUG_ON_PARANOID(buffer->skb); | 823 | EFX_BUG_ON_PARANOID(buffer->skb); |
| 824 | buffer->len = 0; | ||
| 825 | buffer->continuation = true; | ||
| 826 | if (buffer->unmap_len) { | 824 | if (buffer->unmap_len) { |
| 827 | unmap_addr = (buffer->dma_addr + buffer->len - | 825 | unmap_addr = (buffer->dma_addr + buffer->len - |
| 828 | buffer->unmap_len); | 826 | buffer->unmap_len); |
| @@ -836,6 +834,8 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue) | |||
| 836 | PCI_DMA_TODEVICE); | 834 | PCI_DMA_TODEVICE); |
| 837 | buffer->unmap_len = 0; | 835 | buffer->unmap_len = 0; |
| 838 | } | 836 | } |
| 837 | buffer->len = 0; | ||
| 838 | buffer->continuation = true; | ||
| 839 | } | 839 | } |
| 840 | } | 840 | } |
| 841 | 841 | ||
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 01e99f22210e..2834a01bae24 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
| @@ -849,13 +849,13 @@ static void tun_sock_write_space(struct sock *sk) | |||
| 849 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 849 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) |
| 850 | wake_up_interruptible_sync(sk->sk_sleep); | 850 | wake_up_interruptible_sync(sk->sk_sleep); |
| 851 | 851 | ||
| 852 | tun = container_of(sk, struct tun_sock, sk)->tun; | 852 | tun = tun_sk(sk)->tun; |
| 853 | kill_fasync(&tun->fasync, SIGIO, POLL_OUT); | 853 | kill_fasync(&tun->fasync, SIGIO, POLL_OUT); |
| 854 | } | 854 | } |
| 855 | 855 | ||
| 856 | static void tun_sock_destruct(struct sock *sk) | 856 | static void tun_sock_destruct(struct sock *sk) |
| 857 | { | 857 | { |
| 858 | free_netdev(container_of(sk, struct tun_sock, sk)->tun->dev); | 858 | free_netdev(tun_sk(sk)->tun->dev); |
| 859 | } | 859 | } |
| 860 | 860 | ||
| 861 | static struct proto tun_proto = { | 861 | static struct proto tun_proto = { |
| @@ -990,7 +990,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
| 990 | sk->sk_write_space = tun_sock_write_space; | 990 | sk->sk_write_space = tun_sock_write_space; |
| 991 | sk->sk_sndbuf = INT_MAX; | 991 | sk->sk_sndbuf = INT_MAX; |
| 992 | 992 | ||
| 993 | container_of(sk, struct tun_sock, sk)->tun = tun; | 993 | tun_sk(sk)->tun = tun; |
| 994 | 994 | ||
| 995 | security_tun_dev_post_create(sk); | 995 | security_tun_dev_post_create(sk); |
| 996 | 996 | ||
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index afaf088b72ea..41ad2f3697c7 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
| @@ -1563,7 +1563,10 @@ static int ugeth_disable(struct ucc_geth_private *ugeth, enum comm_dir mode) | |||
| 1563 | 1563 | ||
| 1564 | static void ugeth_quiesce(struct ucc_geth_private *ugeth) | 1564 | static void ugeth_quiesce(struct ucc_geth_private *ugeth) |
| 1565 | { | 1565 | { |
| 1566 | /* Wait for and prevent any further xmits. */ | 1566 | /* Prevent any further xmits, plus detach the device. */ |
| 1567 | netif_device_detach(ugeth->ndev); | ||
| 1568 | |||
| 1569 | /* Wait for any current xmits to finish. */ | ||
| 1567 | netif_tx_disable(ugeth->ndev); | 1570 | netif_tx_disable(ugeth->ndev); |
| 1568 | 1571 | ||
| 1569 | /* Disable the interrupt to avoid NAPI rescheduling. */ | 1572 | /* Disable the interrupt to avoid NAPI rescheduling. */ |
| @@ -1577,7 +1580,7 @@ static void ugeth_activate(struct ucc_geth_private *ugeth) | |||
| 1577 | { | 1580 | { |
| 1578 | napi_enable(&ugeth->napi); | 1581 | napi_enable(&ugeth->napi); |
| 1579 | enable_irq(ugeth->ug_info->uf_info.irq); | 1582 | enable_irq(ugeth->ug_info->uf_info.irq); |
| 1580 | netif_tx_wake_all_queues(ugeth->ndev); | 1583 | netif_device_attach(ugeth->ndev); |
| 1581 | } | 1584 | } |
| 1582 | 1585 | ||
| 1583 | /* Called every time the controller might need to be made | 1586 | /* Called every time the controller might need to be made |
| @@ -1648,25 +1651,28 @@ static void adjust_link(struct net_device *dev) | |||
| 1648 | ugeth->oldspeed = phydev->speed; | 1651 | ugeth->oldspeed = phydev->speed; |
| 1649 | } | 1652 | } |
| 1650 | 1653 | ||
| 1651 | /* | ||
| 1652 | * To change the MAC configuration we need to disable the | ||
| 1653 | * controller. To do so, we have to either grab ugeth->lock, | ||
| 1654 | * which is a bad idea since 'graceful stop' commands might | ||
| 1655 | * take quite a while, or we can quiesce driver's activity. | ||
| 1656 | */ | ||
| 1657 | ugeth_quiesce(ugeth); | ||
| 1658 | ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); | ||
| 1659 | |||
| 1660 | out_be32(&ug_regs->maccfg2, tempval); | ||
| 1661 | out_be32(&uf_regs->upsmr, upsmr); | ||
| 1662 | |||
| 1663 | ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); | ||
| 1664 | ugeth_activate(ugeth); | ||
| 1665 | |||
| 1666 | if (!ugeth->oldlink) { | 1654 | if (!ugeth->oldlink) { |
| 1667 | new_state = 1; | 1655 | new_state = 1; |
| 1668 | ugeth->oldlink = 1; | 1656 | ugeth->oldlink = 1; |
| 1669 | } | 1657 | } |
| 1658 | |||
| 1659 | if (new_state) { | ||
| 1660 | /* | ||
| 1661 | * To change the MAC configuration we need to disable | ||
| 1662 | * the controller. To do so, we have to either grab | ||
| 1663 | * ugeth->lock, which is a bad idea since 'graceful | ||
| 1664 | * stop' commands might take quite a while, or we can | ||
| 1665 | * quiesce driver's activity. | ||
| 1666 | */ | ||
| 1667 | ugeth_quiesce(ugeth); | ||
| 1668 | ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); | ||
| 1669 | |||
| 1670 | out_be32(&ug_regs->maccfg2, tempval); | ||
| 1671 | out_be32(&uf_regs->upsmr, upsmr); | ||
| 1672 | |||
| 1673 | ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); | ||
| 1674 | ugeth_activate(ugeth); | ||
| 1675 | } | ||
| 1670 | } else if (ugeth->oldlink) { | 1676 | } else if (ugeth->oldlink) { |
| 1671 | new_state = 1; | 1677 | new_state = 1; |
| 1672 | ugeth->oldlink = 0; | 1678 | ugeth->oldlink = 0; |
| @@ -3273,7 +3279,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) | |||
| 3273 | /* Handle the transmitted buffer and release */ | 3279 | /* Handle the transmitted buffer and release */ |
| 3274 | /* the BD to be used with the current frame */ | 3280 | /* the BD to be used with the current frame */ |
| 3275 | 3281 | ||
| 3276 | if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0)) | 3282 | if (bd == ugeth->txBd[txQ]) /* queue empty? */ |
| 3277 | break; | 3283 | break; |
| 3278 | 3284 | ||
| 3279 | dev->stats.tx_packets++; | 3285 | dev->stats.tx_packets++; |
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 593e01f64e9b..611b80435955 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c | |||
| @@ -102,6 +102,7 @@ static const int multicast_filter_limit = 32; | |||
| 102 | #include <linux/ethtool.h> | 102 | #include <linux/ethtool.h> |
| 103 | #include <linux/crc32.h> | 103 | #include <linux/crc32.h> |
| 104 | #include <linux/bitops.h> | 104 | #include <linux/bitops.h> |
| 105 | #include <linux/workqueue.h> | ||
| 105 | #include <asm/processor.h> /* Processor type for cache alignment. */ | 106 | #include <asm/processor.h> /* Processor type for cache alignment. */ |
| 106 | #include <asm/io.h> | 107 | #include <asm/io.h> |
| 107 | #include <asm/irq.h> | 108 | #include <asm/irq.h> |
| @@ -389,6 +390,7 @@ struct rhine_private { | |||
| 389 | struct net_device *dev; | 390 | struct net_device *dev; |
| 390 | struct napi_struct napi; | 391 | struct napi_struct napi; |
| 391 | spinlock_t lock; | 392 | spinlock_t lock; |
| 393 | struct work_struct reset_task; | ||
| 392 | 394 | ||
| 393 | /* Frequently used values: keep some adjacent for cache effect. */ | 395 | /* Frequently used values: keep some adjacent for cache effect. */ |
| 394 | u32 quirks; | 396 | u32 quirks; |
| @@ -407,6 +409,7 @@ struct rhine_private { | |||
| 407 | static int mdio_read(struct net_device *dev, int phy_id, int location); | 409 | static int mdio_read(struct net_device *dev, int phy_id, int location); |
| 408 | static void mdio_write(struct net_device *dev, int phy_id, int location, int value); | 410 | static void mdio_write(struct net_device *dev, int phy_id, int location, int value); |
| 409 | static int rhine_open(struct net_device *dev); | 411 | static int rhine_open(struct net_device *dev); |
| 412 | static void rhine_reset_task(struct work_struct *work); | ||
| 410 | static void rhine_tx_timeout(struct net_device *dev); | 413 | static void rhine_tx_timeout(struct net_device *dev); |
| 411 | static netdev_tx_t rhine_start_tx(struct sk_buff *skb, | 414 | static netdev_tx_t rhine_start_tx(struct sk_buff *skb, |
| 412 | struct net_device *dev); | 415 | struct net_device *dev); |
| @@ -775,6 +778,8 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, | |||
| 775 | dev->irq = pdev->irq; | 778 | dev->irq = pdev->irq; |
| 776 | 779 | ||
| 777 | spin_lock_init(&rp->lock); | 780 | spin_lock_init(&rp->lock); |
| 781 | INIT_WORK(&rp->reset_task, rhine_reset_task); | ||
| 782 | |||
| 778 | rp->mii_if.dev = dev; | 783 | rp->mii_if.dev = dev; |
| 779 | rp->mii_if.mdio_read = mdio_read; | 784 | rp->mii_if.mdio_read = mdio_read; |
| 780 | rp->mii_if.mdio_write = mdio_write; | 785 | rp->mii_if.mdio_write = mdio_write; |
| @@ -1179,22 +1184,18 @@ static int rhine_open(struct net_device *dev) | |||
| 1179 | return 0; | 1184 | return 0; |
| 1180 | } | 1185 | } |
| 1181 | 1186 | ||
| 1182 | static void rhine_tx_timeout(struct net_device *dev) | 1187 | static void rhine_reset_task(struct work_struct *work) |
| 1183 | { | 1188 | { |
| 1184 | struct rhine_private *rp = netdev_priv(dev); | 1189 | struct rhine_private *rp = container_of(work, struct rhine_private, |
| 1185 | void __iomem *ioaddr = rp->base; | 1190 | reset_task); |
| 1186 | 1191 | struct net_device *dev = rp->dev; | |
| 1187 | printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status " | ||
| 1188 | "%4.4x, resetting...\n", | ||
| 1189 | dev->name, ioread16(ioaddr + IntrStatus), | ||
| 1190 | mdio_read(dev, rp->mii_if.phy_id, MII_BMSR)); | ||
| 1191 | 1192 | ||
| 1192 | /* protect against concurrent rx interrupts */ | 1193 | /* protect against concurrent rx interrupts */ |
| 1193 | disable_irq(rp->pdev->irq); | 1194 | disable_irq(rp->pdev->irq); |
| 1194 | 1195 | ||
| 1195 | napi_disable(&rp->napi); | 1196 | napi_disable(&rp->napi); |
| 1196 | 1197 | ||
| 1197 | spin_lock(&rp->lock); | 1198 | spin_lock_bh(&rp->lock); |
| 1198 | 1199 | ||
| 1199 | /* clear all descriptors */ | 1200 | /* clear all descriptors */ |
| 1200 | free_tbufs(dev); | 1201 | free_tbufs(dev); |
| @@ -1206,7 +1207,7 @@ static void rhine_tx_timeout(struct net_device *dev) | |||
| 1206 | rhine_chip_reset(dev); | 1207 | rhine_chip_reset(dev); |
| 1207 | init_registers(dev); | 1208 | init_registers(dev); |
| 1208 | 1209 | ||
| 1209 | spin_unlock(&rp->lock); | 1210 | spin_unlock_bh(&rp->lock); |
| 1210 | enable_irq(rp->pdev->irq); | 1211 | enable_irq(rp->pdev->irq); |
| 1211 | 1212 | ||
| 1212 | dev->trans_start = jiffies; | 1213 | dev->trans_start = jiffies; |
| @@ -1214,6 +1215,19 @@ static void rhine_tx_timeout(struct net_device *dev) | |||
| 1214 | netif_wake_queue(dev); | 1215 | netif_wake_queue(dev); |
| 1215 | } | 1216 | } |
| 1216 | 1217 | ||
| 1218 | static void rhine_tx_timeout(struct net_device *dev) | ||
| 1219 | { | ||
| 1220 | struct rhine_private *rp = netdev_priv(dev); | ||
| 1221 | void __iomem *ioaddr = rp->base; | ||
| 1222 | |||
| 1223 | printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status " | ||
| 1224 | "%4.4x, resetting...\n", | ||
| 1225 | dev->name, ioread16(ioaddr + IntrStatus), | ||
| 1226 | mdio_read(dev, rp->mii_if.phy_id, MII_BMSR)); | ||
| 1227 | |||
| 1228 | schedule_work(&rp->reset_task); | ||
| 1229 | } | ||
| 1230 | |||
| 1217 | static netdev_tx_t rhine_start_tx(struct sk_buff *skb, | 1231 | static netdev_tx_t rhine_start_tx(struct sk_buff *skb, |
| 1218 | struct net_device *dev) | 1232 | struct net_device *dev) |
| 1219 | { | 1233 | { |
| @@ -1830,10 +1844,11 @@ static int rhine_close(struct net_device *dev) | |||
| 1830 | struct rhine_private *rp = netdev_priv(dev); | 1844 | struct rhine_private *rp = netdev_priv(dev); |
| 1831 | void __iomem *ioaddr = rp->base; | 1845 | void __iomem *ioaddr = rp->base; |
| 1832 | 1846 | ||
| 1833 | spin_lock_irq(&rp->lock); | ||
| 1834 | |||
| 1835 | netif_stop_queue(dev); | ||
| 1836 | napi_disable(&rp->napi); | 1847 | napi_disable(&rp->napi); |
| 1848 | cancel_work_sync(&rp->reset_task); | ||
| 1849 | netif_stop_queue(dev); | ||
| 1850 | |||
| 1851 | spin_lock_irq(&rp->lock); | ||
| 1837 | 1852 | ||
| 1838 | if (debug > 1) | 1853 | if (debug > 1) |
| 1839 | printk(KERN_DEBUG "%s: Shutting down ethercard, " | 1854 | printk(KERN_DEBUG "%s: Shutting down ethercard, " |
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index f1c4b2a1e867..0fdfd58a35a1 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c | |||
| @@ -4087,21 +4087,21 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
| 4087 | goto _exit0; | 4087 | goto _exit0; |
| 4088 | } | 4088 | } |
| 4089 | 4089 | ||
| 4090 | if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) { | 4090 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { |
| 4091 | vxge_debug_ll_config(VXGE_TRACE, | 4091 | vxge_debug_ll_config(VXGE_TRACE, |
| 4092 | "%s : using 64bit DMA", __func__); | 4092 | "%s : using 64bit DMA", __func__); |
| 4093 | 4093 | ||
| 4094 | high_dma = 1; | 4094 | high_dma = 1; |
| 4095 | 4095 | ||
| 4096 | if (pci_set_consistent_dma_mask(pdev, | 4096 | if (pci_set_consistent_dma_mask(pdev, |
| 4097 | 0xffffffffffffffffULL)) { | 4097 | DMA_BIT_MASK(64))) { |
| 4098 | vxge_debug_init(VXGE_ERR, | 4098 | vxge_debug_init(VXGE_ERR, |
| 4099 | "%s : unable to obtain 64bit DMA for " | 4099 | "%s : unable to obtain 64bit DMA for " |
| 4100 | "consistent allocations", __func__); | 4100 | "consistent allocations", __func__); |
| 4101 | ret = -ENOMEM; | 4101 | ret = -ENOMEM; |
| 4102 | goto _exit1; | 4102 | goto _exit1; |
| 4103 | } | 4103 | } |
| 4104 | } else if (!pci_set_dma_mask(pdev, 0xffffffffUL)) { | 4104 | } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { |
| 4105 | vxge_debug_ll_config(VXGE_TRACE, | 4105 | vxge_debug_ll_config(VXGE_TRACE, |
| 4106 | "%s : using 32bit DMA", __func__); | 4106 | "%s : using 32bit DMA", __func__); |
| 4107 | } else { | 4107 | } else { |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index a4c086f069b1..e63b7c40d0ee 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
| @@ -1903,17 +1903,6 @@ accept: | |||
| 1903 | rxs->noise = sc->ah->ah_noise_floor; | 1903 | rxs->noise = sc->ah->ah_noise_floor; |
| 1904 | rxs->signal = rxs->noise + rs.rs_rssi; | 1904 | rxs->signal = rxs->noise + rs.rs_rssi; |
| 1905 | 1905 | ||
| 1906 | /* An rssi of 35 indicates you should be able use | ||
| 1907 | * 54 Mbps reliably. A more elaborate scheme can be used | ||
| 1908 | * here but it requires a map of SNR/throughput for each | ||
| 1909 | * possible mode used */ | ||
| 1910 | rxs->qual = rs.rs_rssi * 100 / 35; | ||
| 1911 | |||
| 1912 | /* rssi can be more than 35 though, anything above that | ||
| 1913 | * should be considered at 100% */ | ||
| 1914 | if (rxs->qual > 100) | ||
| 1915 | rxs->qual = 100; | ||
| 1916 | |||
| 1917 | rxs->antenna = rs.rs_antenna; | 1906 | rxs->antenna = rs.rs_antenna; |
| 1918 | rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); | 1907 | rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); |
| 1919 | rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); | 1908 | rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); |
| @@ -2381,6 +2370,9 @@ ath5k_init(struct ath5k_softc *sc) | |||
| 2381 | */ | 2370 | */ |
| 2382 | ath5k_stop_locked(sc); | 2371 | ath5k_stop_locked(sc); |
| 2383 | 2372 | ||
| 2373 | /* Set PHY calibration interval */ | ||
| 2374 | ah->ah_cal_intval = ath5k_calinterval; | ||
| 2375 | |||
| 2384 | /* | 2376 | /* |
| 2385 | * The basic interface to setting the hardware in a good | 2377 | * The basic interface to setting the hardware in a good |
| 2386 | * state is ``reset''. On return the hardware is known to | 2378 | * state is ``reset''. On return the hardware is known to |
| @@ -2408,10 +2400,6 @@ ath5k_init(struct ath5k_softc *sc) | |||
| 2408 | 2400 | ||
| 2409 | /* Set ack to be sent at low bit-rates */ | 2401 | /* Set ack to be sent at low bit-rates */ |
| 2410 | ath5k_hw_set_ack_bitrate_high(ah, false); | 2402 | ath5k_hw_set_ack_bitrate_high(ah, false); |
| 2411 | |||
| 2412 | /* Set PHY calibration inteval */ | ||
| 2413 | ah->ah_cal_intval = ath5k_calinterval; | ||
| 2414 | |||
| 2415 | ret = 0; | 2403 | ret = 0; |
| 2416 | done: | 2404 | done: |
| 2417 | mmiowb(); | 2405 | mmiowb(); |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 71b84d91dcff..efc420cd42bf 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
| @@ -186,7 +186,7 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) | |||
| 186 | wait = wait_time; | 186 | wait = wait_time; |
| 187 | while (ath9k_hw_numtxpending(ah, q)) { | 187 | while (ath9k_hw_numtxpending(ah, q)) { |
| 188 | if ((--wait) == 0) { | 188 | if ((--wait) == 0) { |
| 189 | ath_print(common, ATH_DBG_QUEUE, | 189 | ath_print(common, ATH_DBG_FATAL, |
| 190 | "Failed to stop TX DMA in 100 " | 190 | "Failed to stop TX DMA in 100 " |
| 191 | "msec after killing last frame\n"); | 191 | "msec after killing last frame\n"); |
| 192 | break; | 192 | break; |
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 0c87771383f0..e185479e295e 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
| @@ -77,6 +77,9 @@ | |||
| 77 | #define ATH9K_TXERR_XTXOP 0x08 | 77 | #define ATH9K_TXERR_XTXOP 0x08 |
| 78 | #define ATH9K_TXERR_TIMER_EXPIRED 0x10 | 78 | #define ATH9K_TXERR_TIMER_EXPIRED 0x10 |
| 79 | #define ATH9K_TX_ACKED 0x20 | 79 | #define ATH9K_TX_ACKED 0x20 |
| 80 | #define ATH9K_TXERR_MASK \ | ||
| 81 | (ATH9K_TXERR_XRETRY | ATH9K_TXERR_FILT | ATH9K_TXERR_FIFO | \ | ||
| 82 | ATH9K_TXERR_XTXOP | ATH9K_TXERR_TIMER_EXPIRED) | ||
| 80 | 83 | ||
| 81 | #define ATH9K_TX_BA 0x01 | 84 | #define ATH9K_TX_BA 0x01 |
| 82 | #define ATH9K_TX_PWRMGMT 0x02 | 85 | #define ATH9K_TX_PWRMGMT 0x02 |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c48743452515..996eb90263cc 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
| @@ -1973,6 +1973,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
| 1973 | struct ieee80211_hw *hw = sc->hw; | 1973 | struct ieee80211_hw *hw = sc->hw; |
| 1974 | int r; | 1974 | int r; |
| 1975 | 1975 | ||
| 1976 | /* Stop ANI */ | ||
| 1977 | del_timer_sync(&common->ani.timer); | ||
| 1978 | |||
| 1976 | ath9k_hw_set_interrupts(ah, 0); | 1979 | ath9k_hw_set_interrupts(ah, 0); |
| 1977 | ath_drain_all_txq(sc, retry_tx); | 1980 | ath_drain_all_txq(sc, retry_tx); |
| 1978 | ath_stoprecv(sc); | 1981 | ath_stoprecv(sc); |
| @@ -2014,6 +2017,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
| 2014 | } | 2017 | } |
| 2015 | } | 2018 | } |
| 2016 | 2019 | ||
| 2020 | /* Start ANI */ | ||
| 2021 | ath_start_ani(common); | ||
| 2022 | |||
| 2017 | return r; | 2023 | return r; |
| 2018 | } | 2024 | } |
| 2019 | 2025 | ||
| @@ -2508,6 +2514,9 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
| 2508 | return; /* another wiphy still in use */ | 2514 | return; /* another wiphy still in use */ |
| 2509 | } | 2515 | } |
| 2510 | 2516 | ||
| 2517 | /* Ensure HW is awake when we try to shut it down. */ | ||
| 2518 | ath9k_ps_wakeup(sc); | ||
| 2519 | |||
| 2511 | if (ah->btcoex_hw.enabled) { | 2520 | if (ah->btcoex_hw.enabled) { |
| 2512 | ath9k_hw_btcoex_disable(ah); | 2521 | ath9k_hw_btcoex_disable(ah); |
| 2513 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | 2522 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
| @@ -2528,6 +2537,9 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
| 2528 | /* disable HAL and put h/w to sleep */ | 2537 | /* disable HAL and put h/w to sleep */ |
| 2529 | ath9k_hw_disable(ah); | 2538 | ath9k_hw_disable(ah); |
| 2530 | ath9k_hw_configpcipowersave(ah, 1, 1); | 2539 | ath9k_hw_configpcipowersave(ah, 1, 1); |
| 2540 | ath9k_ps_restore(sc); | ||
| 2541 | |||
| 2542 | /* Finally, put the chip in FULL SLEEP mode */ | ||
| 2531 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); | 2543 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); |
| 2532 | 2544 | ||
| 2533 | sc->sc_flags |= SC_OP_INVALID; | 2545 | sc->sc_flags |= SC_OP_INVALID; |
| @@ -2641,8 +2653,10 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
| 2641 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || | 2653 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || |
| 2642 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || | 2654 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || |
| 2643 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { | 2655 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { |
| 2656 | ath9k_ps_wakeup(sc); | ||
| 2644 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 2657 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
| 2645 | ath_beacon_return(sc, avp); | 2658 | ath_beacon_return(sc, avp); |
| 2659 | ath9k_ps_restore(sc); | ||
| 2646 | } | 2660 | } |
| 2647 | 2661 | ||
| 2648 | sc->sc_flags &= ~SC_OP_BEACONS; | 2662 | sc->sc_flags &= ~SC_OP_BEACONS; |
| @@ -3091,15 +3105,21 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
| 3091 | case IEEE80211_AMPDU_RX_STOP: | 3105 | case IEEE80211_AMPDU_RX_STOP: |
| 3092 | break; | 3106 | break; |
| 3093 | case IEEE80211_AMPDU_TX_START: | 3107 | case IEEE80211_AMPDU_TX_START: |
| 3108 | ath9k_ps_wakeup(sc); | ||
| 3094 | ath_tx_aggr_start(sc, sta, tid, ssn); | 3109 | ath_tx_aggr_start(sc, sta, tid, ssn); |
| 3095 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 3110 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
| 3111 | ath9k_ps_restore(sc); | ||
| 3096 | break; | 3112 | break; |
| 3097 | case IEEE80211_AMPDU_TX_STOP: | 3113 | case IEEE80211_AMPDU_TX_STOP: |
| 3114 | ath9k_ps_wakeup(sc); | ||
| 3098 | ath_tx_aggr_stop(sc, sta, tid); | 3115 | ath_tx_aggr_stop(sc, sta, tid); |
| 3099 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 3116 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
| 3117 | ath9k_ps_restore(sc); | ||
| 3100 | break; | 3118 | break; |
| 3101 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 3119 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
| 3120 | ath9k_ps_wakeup(sc); | ||
| 3102 | ath_tx_aggr_resume(sc, sta, tid); | 3121 | ath_tx_aggr_resume(sc, sta, tid); |
| 3122 | ath9k_ps_restore(sc); | ||
| 3103 | break; | 3123 | break; |
| 3104 | default: | 3124 | default: |
| 3105 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | 3125 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 5321f735e5a0..f7af5ea54753 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
| @@ -96,7 +96,7 @@ static void ath_pci_bt_coex_prep(struct ath_common *common) | |||
| 96 | pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm); | 96 | pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | const static struct ath_bus_ops ath_pci_bus_ops = { | 99 | static const struct ath_bus_ops ath_pci_bus_ops = { |
| 100 | .read_cachesize = ath_pci_read_cachesize, | 100 | .read_cachesize = ath_pci_read_cachesize, |
| 101 | .cleanup = ath_pci_cleanup, | 101 | .cleanup = ath_pci_cleanup, |
| 102 | .eeprom_read = ath_pci_eeprom_read, | 102 | .eeprom_read = ath_pci_eeprom_read, |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 2a11cc57ceea..fa12b9060b0b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -1108,11 +1108,11 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | |||
| 1108 | if (npend) { | 1108 | if (npend) { |
| 1109 | int r; | 1109 | int r; |
| 1110 | 1110 | ||
| 1111 | ath_print(common, ATH_DBG_XMIT, | 1111 | ath_print(common, ATH_DBG_FATAL, |
| 1112 | "Unable to stop TxDMA. Reset HAL!\n"); | 1112 | "Unable to stop TxDMA. Reset HAL!\n"); |
| 1113 | 1113 | ||
| 1114 | spin_lock_bh(&sc->sc_resetlock); | 1114 | spin_lock_bh(&sc->sc_resetlock); |
| 1115 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true); | 1115 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false); |
| 1116 | if (r) | 1116 | if (r) |
| 1117 | ath_print(common, ATH_DBG_FATAL, | 1117 | ath_print(common, ATH_DBG_FATAL, |
| 1118 | "Unable to reset hardware; reset status %d\n", | 1118 | "Unable to reset hardware; reset status %d\n", |
| @@ -1414,17 +1414,9 @@ static void assign_aggr_tid_seqno(struct sk_buff *skb, | |||
| 1414 | * For HT capable stations, we save tidno for later use. | 1414 | * For HT capable stations, we save tidno for later use. |
| 1415 | * We also override seqno set by upper layer with the one | 1415 | * We also override seqno set by upper layer with the one |
| 1416 | * in tx aggregation state. | 1416 | * in tx aggregation state. |
| 1417 | * | ||
| 1418 | * If fragmentation is on, the sequence number is | ||
| 1419 | * not overridden, since it has been | ||
| 1420 | * incremented by the fragmentation routine. | ||
| 1421 | * | ||
| 1422 | * FIXME: check if the fragmentation threshold exceeds | ||
| 1423 | * IEEE80211 max. | ||
| 1424 | */ | 1417 | */ |
| 1425 | tid = ATH_AN_2_TID(an, bf->bf_tidno); | 1418 | tid = ATH_AN_2_TID(an, bf->bf_tidno); |
| 1426 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << | 1419 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); |
| 1427 | IEEE80211_SEQ_SEQ_SHIFT); | ||
| 1428 | bf->bf_seqno = tid->seq_next; | 1420 | bf->bf_seqno = tid->seq_next; |
| 1429 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); | 1421 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); |
| 1430 | } | 1422 | } |
| @@ -1636,7 +1628,8 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
| 1636 | bf->bf_keyix = ATH9K_TXKEYIX_INVALID; | 1628 | bf->bf_keyix = ATH9K_TXKEYIX_INVALID; |
| 1637 | } | 1629 | } |
| 1638 | 1630 | ||
| 1639 | if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR)) | 1631 | if (ieee80211_is_data_qos(fc) && bf_isht(bf) && |
| 1632 | (sc->sc_flags & SC_OP_TXAGGR)) | ||
| 1640 | assign_aggr_tid_seqno(skb, bf); | 1633 | assign_aggr_tid_seqno(skb, bf); |
| 1641 | 1634 | ||
| 1642 | bf->bf_mpdu = skb; | 1635 | bf->bf_mpdu = skb; |
| @@ -1780,7 +1773,8 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 1780 | struct ath_wiphy *aphy = hw->priv; | 1773 | struct ath_wiphy *aphy = hw->priv; |
| 1781 | struct ath_softc *sc = aphy->sc; | 1774 | struct ath_softc *sc = aphy->sc; |
| 1782 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1775 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
| 1783 | int hdrlen, padsize; | 1776 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
| 1777 | int padpos, padsize; | ||
| 1784 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1778 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 1785 | struct ath_tx_control txctl; | 1779 | struct ath_tx_control txctl; |
| 1786 | 1780 | ||
| @@ -1792,7 +1786,6 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 1792 | * BSSes. | 1786 | * BSSes. |
| 1793 | */ | 1787 | */ |
| 1794 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | 1788 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { |
| 1795 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
| 1796 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | 1789 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) |
| 1797 | sc->tx.seq_no += 0x10; | 1790 | sc->tx.seq_no += 0x10; |
| 1798 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | 1791 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); |
| @@ -1800,9 +1793,9 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 1800 | } | 1793 | } |
| 1801 | 1794 | ||
| 1802 | /* Add the padding after the header if this is not already done */ | 1795 | /* Add the padding after the header if this is not already done */ |
| 1803 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1796 | padpos = ath9k_cmn_padpos(hdr->frame_control); |
| 1804 | if (hdrlen & 3) { | 1797 | padsize = padpos & 3; |
| 1805 | padsize = hdrlen % 4; | 1798 | if (padsize && skb->len>padpos) { |
| 1806 | if (skb_headroom(skb) < padsize) { | 1799 | if (skb_headroom(skb) < padsize) { |
| 1807 | ath_print(common, ATH_DBG_XMIT, | 1800 | ath_print(common, ATH_DBG_XMIT, |
| 1808 | "TX CABQ padding failed\n"); | 1801 | "TX CABQ padding failed\n"); |
| @@ -1810,7 +1803,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 1810 | return; | 1803 | return; |
| 1811 | } | 1804 | } |
| 1812 | skb_push(skb, padsize); | 1805 | skb_push(skb, padsize); |
| 1813 | memmove(skb->data, skb->data + padsize, hdrlen); | 1806 | memmove(skb->data, skb->data + padsize, padpos); |
| 1814 | } | 1807 | } |
| 1815 | 1808 | ||
| 1816 | txctl.txq = sc->beacon.cabq; | 1809 | txctl.txq = sc->beacon.cabq; |
| @@ -1838,7 +1831,8 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
| 1838 | struct ieee80211_hw *hw = sc->hw; | 1831 | struct ieee80211_hw *hw = sc->hw; |
| 1839 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1832 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
| 1840 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1833 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
| 1841 | int hdrlen, padsize; | 1834 | struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; |
| 1835 | int padpos, padsize; | ||
| 1842 | 1836 | ||
| 1843 | ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); | 1837 | ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); |
| 1844 | 1838 | ||
| @@ -1853,14 +1847,14 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
| 1853 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | 1847 | tx_info->flags |= IEEE80211_TX_STAT_ACK; |
| 1854 | } | 1848 | } |
| 1855 | 1849 | ||
| 1856 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1850 | padpos = ath9k_cmn_padpos(hdr->frame_control); |
| 1857 | padsize = hdrlen & 3; | 1851 | padsize = padpos & 3; |
| 1858 | if (padsize && hdrlen >= 24) { | 1852 | if (padsize && skb->len>padpos+padsize) { |
| 1859 | /* | 1853 | /* |
| 1860 | * Remove MAC header padding before giving the frame back to | 1854 | * Remove MAC header padding before giving the frame back to |
| 1861 | * mac80211. | 1855 | * mac80211. |
| 1862 | */ | 1856 | */ |
| 1863 | memmove(skb->data + padsize, skb->data, hdrlen); | 1857 | memmove(skb->data + padsize, skb->data, padpos); |
| 1864 | skb_pull(skb, padsize); | 1858 | skb_pull(skb, padsize); |
| 1865 | } | 1859 | } |
| 1866 | 1860 | ||
| @@ -2078,7 +2072,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
| 2078 | &txq->axq_q, lastbf->list.prev); | 2072 | &txq->axq_q, lastbf->list.prev); |
| 2079 | 2073 | ||
| 2080 | txq->axq_depth--; | 2074 | txq->axq_depth--; |
| 2081 | txok = !(ds->ds_txstat.ts_status & ATH9K_TXERR_FILT); | 2075 | txok = !(ds->ds_txstat.ts_status & ATH9K_TXERR_MASK); |
| 2082 | txq->axq_tx_inprogress = false; | 2076 | txq->axq_tx_inprogress = false; |
| 2083 | spin_unlock_bh(&txq->axq_lock); | 2077 | spin_unlock_bh(&txq->axq_lock); |
| 2084 | 2078 | ||
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 027be275e035..88d1fd02d40a 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
| @@ -383,160 +383,44 @@ static inline | |||
| 383 | } | 383 | } |
| 384 | } | 384 | } |
| 385 | 385 | ||
| 386 | /* Check if a DMA region fits the device constraints. | ||
| 387 | * Returns true, if the region is OK for usage with this device. */ | ||
| 388 | static inline bool b43_dma_address_ok(struct b43_dmaring *ring, | ||
| 389 | dma_addr_t addr, size_t size) | ||
| 390 | { | ||
| 391 | switch (ring->type) { | ||
| 392 | case B43_DMA_30BIT: | ||
| 393 | if ((u64)addr + size > (1ULL << 30)) | ||
| 394 | return 0; | ||
| 395 | break; | ||
| 396 | case B43_DMA_32BIT: | ||
| 397 | if ((u64)addr + size > (1ULL << 32)) | ||
| 398 | return 0; | ||
| 399 | break; | ||
| 400 | case B43_DMA_64BIT: | ||
| 401 | /* Currently we can't have addresses beyond | ||
| 402 | * 64bit in the kernel. */ | ||
| 403 | break; | ||
| 404 | } | ||
| 405 | return 1; | ||
| 406 | } | ||
| 407 | |||
| 408 | #define is_4k_aligned(addr) (((u64)(addr) & 0x0FFFull) == 0) | ||
| 409 | #define is_8k_aligned(addr) (((u64)(addr) & 0x1FFFull) == 0) | ||
| 410 | |||
| 411 | static void b43_unmap_and_free_ringmem(struct b43_dmaring *ring, void *base, | ||
| 412 | dma_addr_t dmaaddr, size_t size) | ||
| 413 | { | ||
| 414 | ssb_dma_unmap_single(ring->dev->dev, dmaaddr, size, DMA_TO_DEVICE); | ||
| 415 | free_pages((unsigned long)base, get_order(size)); | ||
| 416 | } | ||
| 417 | |||
| 418 | static void * __b43_get_and_map_ringmem(struct b43_dmaring *ring, | ||
| 419 | dma_addr_t *dmaaddr, size_t size, | ||
| 420 | gfp_t gfp_flags) | ||
| 421 | { | ||
| 422 | void *base; | ||
| 423 | |||
| 424 | base = (void *)__get_free_pages(gfp_flags, get_order(size)); | ||
| 425 | if (!base) | ||
| 426 | return NULL; | ||
| 427 | memset(base, 0, size); | ||
| 428 | *dmaaddr = ssb_dma_map_single(ring->dev->dev, base, size, | ||
| 429 | DMA_TO_DEVICE); | ||
| 430 | if (ssb_dma_mapping_error(ring->dev->dev, *dmaaddr)) { | ||
| 431 | free_pages((unsigned long)base, get_order(size)); | ||
| 432 | return NULL; | ||
| 433 | } | ||
| 434 | |||
| 435 | return base; | ||
| 436 | } | ||
| 437 | |||
| 438 | static void * b43_get_and_map_ringmem(struct b43_dmaring *ring, | ||
| 439 | dma_addr_t *dmaaddr, size_t size) | ||
| 440 | { | ||
| 441 | void *base; | ||
| 442 | |||
| 443 | base = __b43_get_and_map_ringmem(ring, dmaaddr, size, | ||
| 444 | GFP_KERNEL); | ||
| 445 | if (!base) { | ||
| 446 | b43err(ring->dev->wl, "Failed to allocate or map pages " | ||
| 447 | "for DMA ringmemory\n"); | ||
| 448 | return NULL; | ||
| 449 | } | ||
| 450 | if (!b43_dma_address_ok(ring, *dmaaddr, size)) { | ||
| 451 | /* The memory does not fit our device constraints. | ||
| 452 | * Retry with GFP_DMA set to get lower memory. */ | ||
| 453 | b43_unmap_and_free_ringmem(ring, base, *dmaaddr, size); | ||
| 454 | base = __b43_get_and_map_ringmem(ring, dmaaddr, size, | ||
| 455 | GFP_KERNEL | GFP_DMA); | ||
| 456 | if (!base) { | ||
| 457 | b43err(ring->dev->wl, "Failed to allocate or map pages " | ||
| 458 | "in the GFP_DMA region for DMA ringmemory\n"); | ||
| 459 | return NULL; | ||
| 460 | } | ||
| 461 | if (!b43_dma_address_ok(ring, *dmaaddr, size)) { | ||
| 462 | b43_unmap_and_free_ringmem(ring, base, *dmaaddr, size); | ||
| 463 | b43err(ring->dev->wl, "Failed to allocate DMA " | ||
| 464 | "ringmemory that fits device constraints\n"); | ||
| 465 | return NULL; | ||
| 466 | } | ||
| 467 | } | ||
| 468 | /* We expect the memory to be 4k aligned, at least. */ | ||
| 469 | if (B43_WARN_ON(!is_4k_aligned(*dmaaddr))) { | ||
| 470 | b43_unmap_and_free_ringmem(ring, base, *dmaaddr, size); | ||
| 471 | return NULL; | ||
| 472 | } | ||
| 473 | |||
| 474 | return base; | ||
| 475 | } | ||
| 476 | |||
| 477 | static int alloc_ringmemory(struct b43_dmaring *ring) | 386 | static int alloc_ringmemory(struct b43_dmaring *ring) |
| 478 | { | 387 | { |
| 479 | unsigned int required; | 388 | gfp_t flags = GFP_KERNEL; |
| 480 | void *base; | 389 | |
| 481 | dma_addr_t dmaaddr; | 390 | /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K |
| 482 | 391 | * alignment and 8K buffers for 64-bit DMA with 8K alignment. Testing | |
| 483 | /* There are several requirements to the descriptor ring memory: | 392 | * has shown that 4K is sufficient for the latter as long as the buffer |
| 484 | * - The memory region needs to fit the address constraints for the | 393 | * does not cross an 8K boundary. |
| 485 | * device (same as for frame buffers). | 394 | * |
| 486 | * - For 30/32bit DMA devices, the descriptor ring must be 4k aligned. | 395 | * For unknown reasons - possibly a hardware error - the BCM4311 rev |
| 487 | * - For 64bit DMA devices, the descriptor ring must be 8k aligned. | 396 | * 02, which uses 64-bit DMA, needs the ring buffer in very low memory, |
| 397 | * which accounts for the GFP_DMA flag below. | ||
| 398 | * | ||
| 399 | * The flags here must match the flags in free_ringmemory below! | ||
| 488 | */ | 400 | */ |
| 489 | |||
| 490 | if (ring->type == B43_DMA_64BIT) | 401 | if (ring->type == B43_DMA_64BIT) |
| 491 | required = ring->nr_slots * sizeof(struct b43_dmadesc64); | 402 | flags |= GFP_DMA; |
| 492 | else | 403 | ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev, |
| 493 | required = ring->nr_slots * sizeof(struct b43_dmadesc32); | 404 | B43_DMA_RINGMEMSIZE, |
| 494 | if (B43_WARN_ON(required > 0x1000)) | 405 | &(ring->dmabase), flags); |
| 406 | if (!ring->descbase) { | ||
| 407 | b43err(ring->dev->wl, "DMA ringmemory allocation failed\n"); | ||
| 495 | return -ENOMEM; | 408 | return -ENOMEM; |
| 496 | |||
| 497 | ring->alloc_descsize = 0x1000; | ||
| 498 | base = b43_get_and_map_ringmem(ring, &dmaaddr, ring->alloc_descsize); | ||
| 499 | if (!base) | ||
| 500 | return -ENOMEM; | ||
| 501 | ring->alloc_descbase = base; | ||
| 502 | ring->alloc_dmabase = dmaaddr; | ||
| 503 | |||
| 504 | if ((ring->type != B43_DMA_64BIT) || is_8k_aligned(dmaaddr)) { | ||
| 505 | /* We're on <=32bit DMA, or we already got 8k aligned memory. | ||
| 506 | * That's all we need, so we're fine. */ | ||
| 507 | ring->descbase = base; | ||
| 508 | ring->dmabase = dmaaddr; | ||
| 509 | return 0; | ||
| 510 | } | ||
| 511 | b43_unmap_and_free_ringmem(ring, base, dmaaddr, ring->alloc_descsize); | ||
| 512 | |||
| 513 | /* Ok, we failed at the 8k alignment requirement. | ||
| 514 | * Try to force-align the memory region now. */ | ||
| 515 | ring->alloc_descsize = 0x2000; | ||
| 516 | base = b43_get_and_map_ringmem(ring, &dmaaddr, ring->alloc_descsize); | ||
| 517 | if (!base) | ||
| 518 | return -ENOMEM; | ||
| 519 | ring->alloc_descbase = base; | ||
| 520 | ring->alloc_dmabase = dmaaddr; | ||
| 521 | |||
| 522 | if (is_8k_aligned(dmaaddr)) { | ||
| 523 | /* We're already 8k aligned. That Ok, too. */ | ||
| 524 | ring->descbase = base; | ||
| 525 | ring->dmabase = dmaaddr; | ||
| 526 | return 0; | ||
| 527 | } | 409 | } |
| 528 | /* Force-align it to 8k */ | 410 | memset(ring->descbase, 0, B43_DMA_RINGMEMSIZE); |
| 529 | ring->descbase = (void *)((u8 *)base + 0x1000); | ||
| 530 | ring->dmabase = dmaaddr + 0x1000; | ||
| 531 | B43_WARN_ON(!is_8k_aligned(ring->dmabase)); | ||
| 532 | 411 | ||
| 533 | return 0; | 412 | return 0; |
| 534 | } | 413 | } |
| 535 | 414 | ||
| 536 | static void free_ringmemory(struct b43_dmaring *ring) | 415 | static void free_ringmemory(struct b43_dmaring *ring) |
| 537 | { | 416 | { |
| 538 | b43_unmap_and_free_ringmem(ring, ring->alloc_descbase, | 417 | gfp_t flags = GFP_KERNEL; |
| 539 | ring->alloc_dmabase, ring->alloc_descsize); | 418 | |
| 419 | if (ring->type == B43_DMA_64BIT) | ||
| 420 | flags |= GFP_DMA; | ||
| 421 | |||
| 422 | ssb_dma_free_consistent(ring->dev->dev, B43_DMA_RINGMEMSIZE, | ||
| 423 | ring->descbase, ring->dmabase, flags); | ||
| 540 | } | 424 | } |
| 541 | 425 | ||
| 542 | /* Reset the RX DMA channel */ | 426 | /* Reset the RX DMA channel */ |
| @@ -646,14 +530,29 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, | |||
| 646 | if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr))) | 530 | if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr))) |
| 647 | return 1; | 531 | return 1; |
| 648 | 532 | ||
| 649 | if (!b43_dma_address_ok(ring, addr, buffersize)) { | 533 | switch (ring->type) { |
| 650 | /* We can't support this address. Unmap it again. */ | 534 | case B43_DMA_30BIT: |
| 651 | unmap_descbuffer(ring, addr, buffersize, dma_to_device); | 535 | if ((u64)addr + buffersize > (1ULL << 30)) |
| 652 | return 1; | 536 | goto address_error; |
| 537 | break; | ||
| 538 | case B43_DMA_32BIT: | ||
| 539 | if ((u64)addr + buffersize > (1ULL << 32)) | ||
| 540 | goto address_error; | ||
| 541 | break; | ||
| 542 | case B43_DMA_64BIT: | ||
| 543 | /* Currently we can't have addresses beyond | ||
| 544 | * 64bit in the kernel. */ | ||
| 545 | break; | ||
| 653 | } | 546 | } |
| 654 | 547 | ||
| 655 | /* The address is OK. */ | 548 | /* The address is OK. */ |
| 656 | return 0; | 549 | return 0; |
| 550 | |||
| 551 | address_error: | ||
| 552 | /* We can't support this address. Unmap it again. */ | ||
| 553 | unmap_descbuffer(ring, addr, buffersize, dma_to_device); | ||
| 554 | |||
| 555 | return 1; | ||
| 657 | } | 556 | } |
| 658 | 557 | ||
| 659 | static bool b43_rx_buffer_is_poisoned(struct b43_dmaring *ring, struct sk_buff *skb) | 558 | static bool b43_rx_buffer_is_poisoned(struct b43_dmaring *ring, struct sk_buff *skb) |
| @@ -715,9 +614,6 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, | |||
| 715 | meta->dmaaddr = dmaaddr; | 614 | meta->dmaaddr = dmaaddr; |
| 716 | ring->ops->fill_descriptor(ring, desc, dmaaddr, | 615 | ring->ops->fill_descriptor(ring, desc, dmaaddr, |
| 717 | ring->rx_buffersize, 0, 0, 0); | 616 | ring->rx_buffersize, 0, 0, 0); |
| 718 | ssb_dma_sync_single_for_device(ring->dev->dev, | ||
| 719 | ring->alloc_dmabase, | ||
| 720 | ring->alloc_descsize, DMA_TO_DEVICE); | ||
| 721 | 617 | ||
| 722 | return 0; | 618 | return 0; |
| 723 | } | 619 | } |
| @@ -1354,9 +1250,6 @@ static int dma_tx_fragment(struct b43_dmaring *ring, | |||
| 1354 | } | 1250 | } |
| 1355 | /* Now transfer the whole frame. */ | 1251 | /* Now transfer the whole frame. */ |
| 1356 | wmb(); | 1252 | wmb(); |
| 1357 | ssb_dma_sync_single_for_device(ring->dev->dev, | ||
| 1358 | ring->alloc_dmabase, | ||
| 1359 | ring->alloc_descsize, DMA_TO_DEVICE); | ||
| 1360 | ops->poke_tx(ring, next_slot(ring, slot)); | 1253 | ops->poke_tx(ring, next_slot(ring, slot)); |
| 1361 | return 0; | 1254 | return 0; |
| 1362 | 1255 | ||
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h index e607b392314c..f7ab37c4cdbc 100644 --- a/drivers/net/wireless/b43/dma.h +++ b/drivers/net/wireless/b43/dma.h | |||
| @@ -157,6 +157,7 @@ struct b43_dmadesc_generic { | |||
| 157 | } __attribute__ ((__packed__)); | 157 | } __attribute__ ((__packed__)); |
| 158 | 158 | ||
| 159 | /* Misc DMA constants */ | 159 | /* Misc DMA constants */ |
| 160 | #define B43_DMA_RINGMEMSIZE PAGE_SIZE | ||
| 160 | #define B43_DMA0_RX_FRAMEOFFSET 30 | 161 | #define B43_DMA0_RX_FRAMEOFFSET 30 |
| 161 | 162 | ||
| 162 | /* DMA engine tuning knobs */ | 163 | /* DMA engine tuning knobs */ |
| @@ -246,12 +247,6 @@ struct b43_dmaring { | |||
| 246 | /* The QOS priority assigned to this ring. Only used for TX rings. | 247 | /* The QOS priority assigned to this ring. Only used for TX rings. |
| 247 | * This is the mac80211 "queue" value. */ | 248 | * This is the mac80211 "queue" value. */ |
| 248 | u8 queue_prio; | 249 | u8 queue_prio; |
| 249 | /* Pointers and size of the originally allocated and mapped memory | ||
| 250 | * region for the descriptor ring. */ | ||
| 251 | void *alloc_descbase; | ||
| 252 | dma_addr_t alloc_dmabase; | ||
| 253 | unsigned int alloc_descsize; | ||
| 254 | /* Pointer to our wireless device. */ | ||
| 255 | struct b43_wldev *dev; | 250 | struct b43_wldev *dev; |
| 256 | #ifdef CONFIG_B43_DEBUG | 251 | #ifdef CONFIG_B43_DEBUG |
| 257 | /* Maximum number of used slots. */ | 252 | /* Maximum number of used slots. */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 7da1dab933d9..234891d8cc10 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
| @@ -681,19 +681,13 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, | |||
| 681 | snr = rx_stats_sig_avg / rx_stats_noise_diff; | 681 | snr = rx_stats_sig_avg / rx_stats_noise_diff; |
| 682 | rx_status.noise = rx_status.signal - | 682 | rx_status.noise = rx_status.signal - |
| 683 | iwl3945_calc_db_from_ratio(snr); | 683 | iwl3945_calc_db_from_ratio(snr); |
| 684 | rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal, | ||
| 685 | rx_status.noise); | ||
| 686 | |||
| 687 | /* If noise info not available, calculate signal quality indicator (%) | ||
| 688 | * using just the dBm signal level. */ | ||
| 689 | } else { | 684 | } else { |
| 690 | rx_status.noise = priv->last_rx_noise; | 685 | rx_status.noise = priv->last_rx_noise; |
| 691 | rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal, 0); | ||
| 692 | } | 686 | } |
| 693 | 687 | ||
| 694 | 688 | ||
| 695 | IWL_DEBUG_STATS(priv, "Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n", | 689 | IWL_DEBUG_STATS(priv, "Rssi %d noise %d sig_avg %d noise_diff %d\n", |
| 696 | rx_status.signal, rx_status.noise, rx_status.qual, | 690 | rx_status.signal, rx_status.noise, |
| 697 | rx_stats_sig_avg, rx_stats_noise_diff); | 691 | rx_stats_sig_avg, rx_stats_noise_diff); |
| 698 | 692 | ||
| 699 | header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); | 693 | header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); |
| @@ -1835,8 +1829,7 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) | |||
| 1835 | rc = -EIO; | 1829 | rc = -EIO; |
| 1836 | } | 1830 | } |
| 1837 | 1831 | ||
| 1838 | priv->alloc_rxb_page--; | 1832 | iwl_free_pages(priv, cmd.reply_page); |
| 1839 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); | ||
| 1840 | 1833 | ||
| 1841 | return rc; | 1834 | return rc; |
| 1842 | } | 1835 | } |
| @@ -2836,6 +2829,7 @@ static struct iwl_cfg iwl3945_bg_cfg = { | |||
| 2836 | .use_isr_legacy = true, | 2829 | .use_isr_legacy = true, |
| 2837 | .ht_greenfield_support = false, | 2830 | .ht_greenfield_support = false, |
| 2838 | .led_compensation = 64, | 2831 | .led_compensation = 64, |
| 2832 | .broken_powersave = true, | ||
| 2839 | }; | 2833 | }; |
| 2840 | 2834 | ||
| 2841 | static struct iwl_cfg iwl3945_abg_cfg = { | 2835 | static struct iwl_cfg iwl3945_abg_cfg = { |
| @@ -2852,6 +2846,7 @@ static struct iwl_cfg iwl3945_abg_cfg = { | |||
| 2852 | .use_isr_legacy = true, | 2846 | .use_isr_legacy = true, |
| 2853 | .ht_greenfield_support = false, | 2847 | .ht_greenfield_support = false, |
| 2854 | .led_compensation = 64, | 2848 | .led_compensation = 64, |
| 2849 | .broken_powersave = true, | ||
| 2855 | }; | 2850 | }; |
| 2856 | 2851 | ||
| 2857 | struct pci_device_id iwl3945_hw_card_ids[] = { | 2852 | struct pci_device_id iwl3945_hw_card_ids[] = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index ecc23ec1f6a4..531fa125f5a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
| @@ -222,7 +222,6 @@ struct iwl3945_ibss_seq { | |||
| 222 | * | 222 | * |
| 223 | *****************************************************************************/ | 223 | *****************************************************************************/ |
| 224 | extern int iwl3945_calc_db_from_ratio(int sig_ratio); | 224 | extern int iwl3945_calc_db_from_ratio(int sig_ratio); |
| 225 | extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm); | ||
| 226 | extern void iwl3945_rx_replenish(void *data); | 225 | extern void iwl3945_rx_replenish(void *data); |
| 227 | extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); | 226 | extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); |
| 228 | extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, | 227 | extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 386513b601f5..484c5fdf7c2a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
| @@ -1204,7 +1204,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, | |||
| 1204 | iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info); | 1204 | iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info); |
| 1205 | 1205 | ||
| 1206 | /* calculate tx gain adjustment based on power supply voltage */ | 1206 | /* calculate tx gain adjustment based on power supply voltage */ |
| 1207 | voltage = priv->calib_info->voltage; | 1207 | voltage = le16_to_cpu(priv->calib_info->voltage); |
| 1208 | init_voltage = (s32)le32_to_cpu(priv->card_alive_init.voltage); | 1208 | init_voltage = (s32)le32_to_cpu(priv->card_alive_init.voltage); |
| 1209 | voltage_compensation = | 1209 | voltage_compensation = |
| 1210 | iwl4965_get_voltage_compensation(voltage, init_voltage); | 1210 | iwl4965_get_voltage_compensation(voltage, init_voltage); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h index 4ef6804a455a..bc056e9ab85f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h | |||
| @@ -92,11 +92,15 @@ | |||
| 92 | 92 | ||
| 93 | static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv) | 93 | static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv) |
| 94 | { | 94 | { |
| 95 | u16 *temp_calib = (u16 *)iwl_eeprom_query_addr(priv, | 95 | u16 temperature, voltage; |
| 96 | EEPROM_5000_TEMPERATURE); | 96 | __le16 *temp_calib = |
| 97 | /* offset = temperature - voltage / coef */ | 97 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE); |
| 98 | s32 offset = (s32)(temp_calib[0] - temp_calib[1] / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF); | 98 | |
| 99 | return offset; | 99 | temperature = le16_to_cpu(temp_calib[0]); |
| 100 | voltage = le16_to_cpu(temp_calib[1]); | ||
| 101 | |||
| 102 | /* offset = temp - volt / coeff */ | ||
| 103 | return (s32)(temperature - voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF); | ||
| 100 | } | 104 | } |
| 101 | 105 | ||
| 102 | /* Fixed (non-configurable) rx data from phy */ | 106 | /* Fixed (non-configurable) rx data from phy */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index e2f8615c8c9b..33a5866538e7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
| @@ -333,14 +333,15 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv) | |||
| 333 | static int iwl5000_set_Xtal_calib(struct iwl_priv *priv) | 333 | static int iwl5000_set_Xtal_calib(struct iwl_priv *priv) |
| 334 | { | 334 | { |
| 335 | struct iwl_calib_xtal_freq_cmd cmd; | 335 | struct iwl_calib_xtal_freq_cmd cmd; |
| 336 | u16 *xtal_calib = (u16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL); | 336 | __le16 *xtal_calib = |
| 337 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL); | ||
| 337 | 338 | ||
| 338 | cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD; | 339 | cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD; |
| 339 | cmd.hdr.first_group = 0; | 340 | cmd.hdr.first_group = 0; |
| 340 | cmd.hdr.groups_num = 1; | 341 | cmd.hdr.groups_num = 1; |
| 341 | cmd.hdr.data_valid = 1; | 342 | cmd.hdr.data_valid = 1; |
| 342 | cmd.cap_pin1 = (u8)xtal_calib[0]; | 343 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); |
| 343 | cmd.cap_pin2 = (u8)xtal_calib[1]; | 344 | cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); |
| 344 | return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL], | 345 | return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL], |
| 345 | (u8 *)&cmd, sizeof(cmd)); | 346 | (u8 *)&cmd, sizeof(cmd)); |
| 346 | } | 347 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index fe511cbf012e..b93e49158196 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
| @@ -150,7 +150,7 @@ static s32 expected_tpt_mimo3_40MHz[4][IWL_RATE_COUNT] = { | |||
| 150 | }; | 150 | }; |
| 151 | 151 | ||
| 152 | /* mbps, mcs */ | 152 | /* mbps, mcs */ |
| 153 | const static struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = { | 153 | static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = { |
| 154 | { "1", "BPSK DSSS"}, | 154 | { "1", "BPSK DSSS"}, |
| 155 | { "2", "QPSK DSSS"}, | 155 | { "2", "QPSK DSSS"}, |
| 156 | {"5.5", "BPSK CCK"}, | 156 | {"5.5", "BPSK CCK"}, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b8377efb3ba7..1c9866daf815 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
| @@ -1842,7 +1842,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | |||
| 1842 | } | 1842 | } |
| 1843 | 1843 | ||
| 1844 | #ifdef CONFIG_IWLWIFI_DEBUG | 1844 | #ifdef CONFIG_IWLWIFI_DEBUG |
| 1845 | if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)) | 1845 | if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) |
| 1846 | size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) | 1846 | size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) |
| 1847 | ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; | 1847 | ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; |
| 1848 | #else | 1848 | #else |
| @@ -3173,7 +3173,6 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
| 3173 | 3173 | ||
| 3174 | priv->ibss_beacon = NULL; | 3174 | priv->ibss_beacon = NULL; |
| 3175 | 3175 | ||
| 3176 | spin_lock_init(&priv->lock); | ||
| 3177 | spin_lock_init(&priv->sta_lock); | 3176 | spin_lock_init(&priv->sta_lock); |
| 3178 | spin_lock_init(&priv->hcmd_lock); | 3177 | spin_lock_init(&priv->hcmd_lock); |
| 3179 | 3178 | ||
| @@ -3361,10 +3360,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 3361 | (unsigned long long) pci_resource_len(pdev, 0)); | 3360 | (unsigned long long) pci_resource_len(pdev, 0)); |
| 3362 | IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base); | 3361 | IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base); |
| 3363 | 3362 | ||
| 3364 | /* this spin lock will be used in apm_ops.init and EEPROM access | 3363 | /* these spin locks will be used in apm_ops.init and EEPROM access |
| 3365 | * we should init now | 3364 | * we should init now |
| 3366 | */ | 3365 | */ |
| 3367 | spin_lock_init(&priv->reg_lock); | 3366 | spin_lock_init(&priv->reg_lock); |
| 3367 | spin_lock_init(&priv->lock); | ||
| 3368 | iwl_hw_detect(priv); | 3368 | iwl_hw_detect(priv); |
| 3369 | IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n", | 3369 | IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n", |
| 3370 | priv->cfg->name, priv->hw_rev); | 3370 | priv->cfg->name, priv->hw_rev); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index a7bfae01f19b..1ec8cb4d5eae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
| @@ -77,8 +77,7 @@ | |||
| 77 | * The MAC (uCode processor, etc.) does not need to be powered up for accessing | 77 | * The MAC (uCode processor, etc.) does not need to be powered up for accessing |
| 78 | * the CSR registers. | 78 | * the CSR registers. |
| 79 | * | 79 | * |
| 80 | * NOTE: Newer devices using one-time-programmable (OTP) memory | 80 | * NOTE: Device does need to be awake in order to read this memory |
| 81 | * require device to be awake in order to read this memory | ||
| 82 | * via CSR_EEPROM and CSR_OTP registers | 81 | * via CSR_EEPROM and CSR_OTP registers |
| 83 | */ | 82 | */ |
| 84 | #define CSR_BASE (0x000) | 83 | #define CSR_BASE (0x000) |
| @@ -111,9 +110,8 @@ | |||
| 111 | /* | 110 | /* |
| 112 | * EEPROM and OTP (one-time-programmable) memory reads | 111 | * EEPROM and OTP (one-time-programmable) memory reads |
| 113 | * | 112 | * |
| 114 | * NOTE: For (newer) devices using OTP, device must be awake, initialized via | 113 | * NOTE: Device must be awake, initialized via apm_ops.init(), |
| 115 | * apm_ops.init() in order to read. Older devices (3945/4965/5000) | 114 | * in order to read. |
| 116 | * use EEPROM and do not require this. | ||
| 117 | */ | 115 | */ |
| 118 | #define CSR_EEPROM_REG (CSR_BASE+0x02c) | 116 | #define CSR_EEPROM_REG (CSR_BASE+0x02c) |
| 119 | #define CSR_EEPROM_GP (CSR_BASE+0x030) | 117 | #define CSR_EEPROM_GP (CSR_BASE+0x030) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 2673e9a4db92..165d1f6e2dd9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
| @@ -1168,7 +1168,7 @@ struct iwl_priv { | |||
| 1168 | u32 last_beacon_time; | 1168 | u32 last_beacon_time; |
| 1169 | u64 last_tsf; | 1169 | u64 last_tsf; |
| 1170 | 1170 | ||
| 1171 | /* eeprom */ | 1171 | /* eeprom -- this is in the card's little endian byte order */ |
| 1172 | u8 *eeprom; | 1172 | u8 *eeprom; |
| 1173 | int nvm_device_type; | 1173 | int nvm_device_type; |
| 1174 | struct iwl_eeprom_calib_info *calib_info; | 1174 | struct iwl_eeprom_calib_info *calib_info; |
| @@ -1353,4 +1353,15 @@ static inline int is_channel_ibss(const struct iwl_channel_info *ch) | |||
| 1353 | return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; | 1353 | return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; |
| 1354 | } | 1354 | } |
| 1355 | 1355 | ||
| 1356 | static inline void __iwl_free_pages(struct iwl_priv *priv, struct page *page) | ||
| 1357 | { | ||
| 1358 | __free_pages(page, priv->hw_params.rx_page_order); | ||
| 1359 | priv->alloc_rxb_page--; | ||
| 1360 | } | ||
| 1361 | |||
| 1362 | static inline void iwl_free_pages(struct iwl_priv *priv, unsigned long page) | ||
| 1363 | { | ||
| 1364 | free_pages(page, priv->hw_params.rx_page_order); | ||
| 1365 | priv->alloc_rxb_page--; | ||
| 1366 | } | ||
| 1356 | #endif /* __iwl_dev_h__ */ | 1367 | #endif /* __iwl_dev_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 3946e5c03f81..4a30969689ff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
| @@ -370,7 +370,7 @@ static int iwl_init_otp_access(struct iwl_priv *priv) | |||
| 370 | return ret; | 370 | return ret; |
| 371 | } | 371 | } |
| 372 | 372 | ||
| 373 | static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data) | 373 | static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_data) |
| 374 | { | 374 | { |
| 375 | int ret = 0; | 375 | int ret = 0; |
| 376 | u32 r; | 376 | u32 r; |
| @@ -404,7 +404,7 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data) | |||
| 404 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); | 404 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); |
| 405 | IWL_ERR(priv, "Correctable OTP ECC error, continue read\n"); | 405 | IWL_ERR(priv, "Correctable OTP ECC error, continue read\n"); |
| 406 | } | 406 | } |
| 407 | *eeprom_data = le16_to_cpu((__force __le16)(r >> 16)); | 407 | *eeprom_data = cpu_to_le16(r >> 16); |
| 408 | return 0; | 408 | return 0; |
| 409 | } | 409 | } |
| 410 | 410 | ||
| @@ -413,7 +413,8 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data) | |||
| 413 | */ | 413 | */ |
| 414 | static bool iwl_is_otp_empty(struct iwl_priv *priv) | 414 | static bool iwl_is_otp_empty(struct iwl_priv *priv) |
| 415 | { | 415 | { |
| 416 | u16 next_link_addr = 0, link_value; | 416 | u16 next_link_addr = 0; |
| 417 | __le16 link_value; | ||
| 417 | bool is_empty = false; | 418 | bool is_empty = false; |
| 418 | 419 | ||
| 419 | /* locate the beginning of OTP link list */ | 420 | /* locate the beginning of OTP link list */ |
| @@ -443,7 +444,8 @@ static bool iwl_is_otp_empty(struct iwl_priv *priv) | |||
| 443 | static int iwl_find_otp_image(struct iwl_priv *priv, | 444 | static int iwl_find_otp_image(struct iwl_priv *priv, |
| 444 | u16 *validblockaddr) | 445 | u16 *validblockaddr) |
| 445 | { | 446 | { |
| 446 | u16 next_link_addr = 0, link_value = 0, valid_addr; | 447 | u16 next_link_addr = 0, valid_addr; |
| 448 | __le16 link_value = 0; | ||
| 447 | int usedblocks = 0; | 449 | int usedblocks = 0; |
| 448 | 450 | ||
| 449 | /* set addressing mode to absolute to traverse the link list */ | 451 | /* set addressing mode to absolute to traverse the link list */ |
| @@ -463,7 +465,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv, | |||
| 463 | * check for more block on the link list | 465 | * check for more block on the link list |
| 464 | */ | 466 | */ |
| 465 | valid_addr = next_link_addr; | 467 | valid_addr = next_link_addr; |
| 466 | next_link_addr = link_value * sizeof(u16); | 468 | next_link_addr = le16_to_cpu(link_value) * sizeof(u16); |
| 467 | IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n", | 469 | IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n", |
| 468 | usedblocks, next_link_addr); | 470 | usedblocks, next_link_addr); |
| 469 | if (iwl_read_otp_word(priv, next_link_addr, &link_value)) | 471 | if (iwl_read_otp_word(priv, next_link_addr, &link_value)) |
| @@ -497,7 +499,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv, | |||
| 497 | */ | 499 | */ |
| 498 | int iwl_eeprom_init(struct iwl_priv *priv) | 500 | int iwl_eeprom_init(struct iwl_priv *priv) |
| 499 | { | 501 | { |
| 500 | u16 *e; | 502 | __le16 *e; |
| 501 | u32 gp = iwl_read32(priv, CSR_EEPROM_GP); | 503 | u32 gp = iwl_read32(priv, CSR_EEPROM_GP); |
| 502 | int sz; | 504 | int sz; |
| 503 | int ret; | 505 | int ret; |
| @@ -516,12 +518,9 @@ int iwl_eeprom_init(struct iwl_priv *priv) | |||
| 516 | ret = -ENOMEM; | 518 | ret = -ENOMEM; |
| 517 | goto alloc_err; | 519 | goto alloc_err; |
| 518 | } | 520 | } |
| 519 | e = (u16 *)priv->eeprom; | 521 | e = (__le16 *)priv->eeprom; |
| 520 | 522 | ||
| 521 | if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) { | 523 | priv->cfg->ops->lib->apm_ops.init(priv); |
| 522 | /* OTP reads require powered-up chip */ | ||
| 523 | priv->cfg->ops->lib->apm_ops.init(priv); | ||
| 524 | } | ||
| 525 | 524 | ||
| 526 | ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv); | 525 | ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv); |
| 527 | if (ret < 0) { | 526 | if (ret < 0) { |
| @@ -562,7 +561,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) | |||
| 562 | } | 561 | } |
| 563 | for (addr = validblockaddr; addr < validblockaddr + sz; | 562 | for (addr = validblockaddr; addr < validblockaddr + sz; |
| 564 | addr += sizeof(u16)) { | 563 | addr += sizeof(u16)) { |
| 565 | u16 eeprom_data; | 564 | __le16 eeprom_data; |
| 566 | 565 | ||
| 567 | ret = iwl_read_otp_word(priv, addr, &eeprom_data); | 566 | ret = iwl_read_otp_word(priv, addr, &eeprom_data); |
| 568 | if (ret) | 567 | if (ret) |
| @@ -570,13 +569,6 @@ int iwl_eeprom_init(struct iwl_priv *priv) | |||
| 570 | e[cache_addr / 2] = eeprom_data; | 569 | e[cache_addr / 2] = eeprom_data; |
| 571 | cache_addr += sizeof(u16); | 570 | cache_addr += sizeof(u16); |
| 572 | } | 571 | } |
| 573 | |||
| 574 | /* | ||
| 575 | * Now that OTP reads are complete, reset chip to save | ||
| 576 | * power until we load uCode during "up". | ||
| 577 | */ | ||
| 578 | priv->cfg->ops->lib->apm_ops.stop(priv); | ||
| 579 | |||
| 580 | } else { | 572 | } else { |
| 581 | /* eeprom is an array of 16bit values */ | 573 | /* eeprom is an array of 16bit values */ |
| 582 | for (addr = 0; addr < sz; addr += sizeof(u16)) { | 574 | for (addr = 0; addr < sz; addr += sizeof(u16)) { |
| @@ -594,7 +586,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) | |||
| 594 | goto done; | 586 | goto done; |
| 595 | } | 587 | } |
| 596 | r = _iwl_read_direct32(priv, CSR_EEPROM_REG); | 588 | r = _iwl_read_direct32(priv, CSR_EEPROM_REG); |
| 597 | e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16)); | 589 | e[addr / 2] = cpu_to_le16(r >> 16); |
| 598 | } | 590 | } |
| 599 | } | 591 | } |
| 600 | ret = 0; | 592 | ret = 0; |
| @@ -603,6 +595,8 @@ done: | |||
| 603 | err: | 595 | err: |
| 604 | if (ret) | 596 | if (ret) |
| 605 | iwl_eeprom_free(priv); | 597 | iwl_eeprom_free(priv); |
| 598 | /* Reset chip to save power until we load uCode during "up". */ | ||
| 599 | priv->cfg->ops->lib->apm_ops.stop(priv); | ||
| 606 | alloc_err: | 600 | alloc_err: |
| 607 | return ret; | 601 | return ret; |
| 608 | } | 602 | } |
| @@ -755,7 +749,8 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv, | |||
| 755 | ch_info->ht40_eeprom = *eeprom_ch; | 749 | ch_info->ht40_eeprom = *eeprom_ch; |
| 756 | ch_info->ht40_max_power_avg = eeprom_ch->max_power_avg; | 750 | ch_info->ht40_max_power_avg = eeprom_ch->max_power_avg; |
| 757 | ch_info->ht40_flags = eeprom_ch->flags; | 751 | ch_info->ht40_flags = eeprom_ch->flags; |
| 758 | ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel; | 752 | if (eeprom_ch->flags & EEPROM_CHANNEL_VALID) |
| 753 | ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel; | ||
| 759 | 754 | ||
| 760 | return 0; | 755 | return 0; |
| 761 | } | 756 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 5cd2b66bbe45..0cd9c02ee044 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h | |||
| @@ -137,7 +137,7 @@ struct iwl_eeprom_channel { | |||
| 137 | * | 137 | * |
| 138 | */ | 138 | */ |
| 139 | struct iwl_eeprom_enhanced_txpwr { | 139 | struct iwl_eeprom_enhanced_txpwr { |
| 140 | u16 common; | 140 | __le16 common; |
| 141 | s8 chain_a_max; | 141 | s8 chain_a_max; |
| 142 | s8 chain_b_max; | 142 | s8 chain_b_max; |
| 143 | s8 chain_c_max; | 143 | s8 chain_c_max; |
| @@ -360,7 +360,7 @@ struct iwl_eeprom_calib_subband_info { | |||
| 360 | struct iwl_eeprom_calib_info { | 360 | struct iwl_eeprom_calib_info { |
| 361 | u8 saturation_power24; /* half-dBm (e.g. "34" = 17 dBm) */ | 361 | u8 saturation_power24; /* half-dBm (e.g. "34" = 17 dBm) */ |
| 362 | u8 saturation_power52; /* half-dBm */ | 362 | u8 saturation_power52; /* half-dBm */ |
| 363 | s16 voltage; /* signed */ | 363 | __le16 voltage; /* signed */ |
| 364 | struct iwl_eeprom_calib_subband_info | 364 | struct iwl_eeprom_calib_subband_info |
| 365 | band_info[EEPROM_TX_POWER_BANDS]; | 365 | band_info[EEPROM_TX_POWER_BANDS]; |
| 366 | } __attribute__ ((packed)); | 366 | } __attribute__ ((packed)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index a23165948202..30e9ea6d54ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c | |||
| @@ -234,7 +234,7 @@ cancel: | |||
| 234 | } | 234 | } |
| 235 | fail: | 235 | fail: |
| 236 | if (cmd->reply_page) { | 236 | if (cmd->reply_page) { |
| 237 | free_pages(cmd->reply_page, priv->hw_params.rx_page_order); | 237 | iwl_free_pages(priv, cmd->reply_page); |
| 238 | cmd->reply_page = 0; | 238 | cmd->reply_page = 0; |
| 239 | } | 239 | } |
| 240 | out: | 240 | out: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 6090bc15a6d5..6f36b6e79f5e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
| @@ -345,10 +345,8 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
| 345 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, | 345 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, |
| 346 | PAGE_SIZE << priv->hw_params.rx_page_order, | 346 | PAGE_SIZE << priv->hw_params.rx_page_order, |
| 347 | PCI_DMA_FROMDEVICE); | 347 | PCI_DMA_FROMDEVICE); |
| 348 | __free_pages(rxq->pool[i].page, | 348 | __iwl_free_pages(priv, rxq->pool[i].page); |
| 349 | priv->hw_params.rx_page_order); | ||
| 350 | rxq->pool[i].page = NULL; | 349 | rxq->pool[i].page = NULL; |
| 351 | priv->alloc_rxb_page--; | ||
| 352 | } | 350 | } |
| 353 | } | 351 | } |
| 354 | 352 | ||
| @@ -416,9 +414,7 @@ void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
| 416 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, | 414 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, |
| 417 | PAGE_SIZE << priv->hw_params.rx_page_order, | 415 | PAGE_SIZE << priv->hw_params.rx_page_order, |
| 418 | PCI_DMA_FROMDEVICE); | 416 | PCI_DMA_FROMDEVICE); |
| 419 | priv->alloc_rxb_page--; | 417 | __iwl_free_pages(priv, rxq->pool[i].page); |
| 420 | __free_pages(rxq->pool[i].page, | ||
| 421 | priv->hw_params.rx_page_order); | ||
| 422 | rxq->pool[i].page = NULL; | 418 | rxq->pool[i].page = NULL; |
| 423 | } | 419 | } |
| 424 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | 420 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); |
| @@ -654,47 +650,6 @@ void iwl_reply_statistics(struct iwl_priv *priv, | |||
| 654 | } | 650 | } |
| 655 | EXPORT_SYMBOL(iwl_reply_statistics); | 651 | EXPORT_SYMBOL(iwl_reply_statistics); |
| 656 | 652 | ||
| 657 | #define PERFECT_RSSI (-20) /* dBm */ | ||
| 658 | #define WORST_RSSI (-95) /* dBm */ | ||
| 659 | #define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI) | ||
| 660 | |||
| 661 | /* Calculate an indication of rx signal quality (a percentage, not dBm!). | ||
| 662 | * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info | ||
| 663 | * about formulas used below. */ | ||
| 664 | static int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm) | ||
| 665 | { | ||
| 666 | int sig_qual; | ||
| 667 | int degradation = PERFECT_RSSI - rssi_dbm; | ||
| 668 | |||
| 669 | /* If we get a noise measurement, use signal-to-noise ratio (SNR) | ||
| 670 | * as indicator; formula is (signal dbm - noise dbm). | ||
| 671 | * SNR at or above 40 is a great signal (100%). | ||
| 672 | * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator. | ||
| 673 | * Weakest usable signal is usually 10 - 15 dB SNR. */ | ||
| 674 | if (noise_dbm) { | ||
| 675 | if (rssi_dbm - noise_dbm >= 40) | ||
| 676 | return 100; | ||
| 677 | else if (rssi_dbm < noise_dbm) | ||
| 678 | return 0; | ||
| 679 | sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2; | ||
| 680 | |||
| 681 | /* Else use just the signal level. | ||
| 682 | * This formula is a least squares fit of data points collected and | ||
| 683 | * compared with a reference system that had a percentage (%) display | ||
| 684 | * for signal quality. */ | ||
| 685 | } else | ||
| 686 | sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation * | ||
| 687 | (15 * RSSI_RANGE + 62 * degradation)) / | ||
| 688 | (RSSI_RANGE * RSSI_RANGE); | ||
| 689 | |||
| 690 | if (sig_qual > 100) | ||
| 691 | sig_qual = 100; | ||
| 692 | else if (sig_qual < 1) | ||
| 693 | sig_qual = 0; | ||
| 694 | |||
| 695 | return sig_qual; | ||
| 696 | } | ||
| 697 | |||
| 698 | /* Calc max signal level (dBm) among 3 possible receivers */ | 653 | /* Calc max signal level (dBm) among 3 possible receivers */ |
| 699 | static inline int iwl_calc_rssi(struct iwl_priv *priv, | 654 | static inline int iwl_calc_rssi(struct iwl_priv *priv, |
| 700 | struct iwl_rx_phy_res *rx_resp) | 655 | struct iwl_rx_phy_res *rx_resp) |
| @@ -1105,11 +1060,8 @@ void iwl_rx_reply_rx(struct iwl_priv *priv, | |||
| 1105 | if (iwl_is_associated(priv) && | 1060 | if (iwl_is_associated(priv) && |
| 1106 | !test_bit(STATUS_SCANNING, &priv->status)) { | 1061 | !test_bit(STATUS_SCANNING, &priv->status)) { |
| 1107 | rx_status.noise = priv->last_rx_noise; | 1062 | rx_status.noise = priv->last_rx_noise; |
| 1108 | rx_status.qual = iwl_calc_sig_qual(rx_status.signal, | ||
| 1109 | rx_status.noise); | ||
| 1110 | } else { | 1063 | } else { |
| 1111 | rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE; | 1064 | rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE; |
| 1112 | rx_status.qual = iwl_calc_sig_qual(rx_status.signal, 0); | ||
| 1113 | } | 1065 | } |
| 1114 | 1066 | ||
| 1115 | /* Reset beacon noise level if not associated. */ | 1067 | /* Reset beacon noise level if not associated. */ |
| @@ -1122,8 +1074,8 @@ void iwl_rx_reply_rx(struct iwl_priv *priv, | |||
| 1122 | iwl_dbg_report_frame(priv, phy_res, len, header, 1); | 1074 | iwl_dbg_report_frame(priv, phy_res, len, header, 1); |
| 1123 | #endif | 1075 | #endif |
| 1124 | iwl_dbg_log_rx_data_frame(priv, len, header); | 1076 | iwl_dbg_log_rx_data_frame(priv, len, header); |
| 1125 | IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, qual %d, TSF %llu\n", | 1077 | IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, TSF %llu\n", |
| 1126 | rx_status.signal, rx_status.noise, rx_status.qual, | 1078 | rx_status.signal, rx_status.noise, |
| 1127 | (unsigned long long)rx_status.mactime); | 1079 | (unsigned long long)rx_status.mactime); |
| 1128 | 1080 | ||
| 1129 | /* | 1081 | /* |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index a2b2b8315ff9..fa1c89ba6459 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
| @@ -144,8 +144,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) | |||
| 144 | clear_bit(STATUS_SCAN_HW, &priv->status); | 144 | clear_bit(STATUS_SCAN_HW, &priv->status); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | priv->alloc_rxb_page--; | 147 | iwl_free_pages(priv, cmd.reply_page); |
| 148 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); | ||
| 149 | 148 | ||
| 150 | return ret; | 149 | return ret; |
| 151 | } | 150 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index cd6a6901216e..cde09a890b73 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
| @@ -164,9 +164,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
| 164 | break; | 164 | break; |
| 165 | } | 165 | } |
| 166 | } | 166 | } |
| 167 | 167 | iwl_free_pages(priv, cmd.reply_page); | |
| 168 | priv->alloc_rxb_page--; | ||
| 169 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); | ||
| 170 | 168 | ||
| 171 | return ret; | 169 | return ret; |
| 172 | } | 170 | } |
| @@ -391,9 +389,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, | |||
| 391 | break; | 389 | break; |
| 392 | } | 390 | } |
| 393 | } | 391 | } |
| 394 | 392 | iwl_free_pages(priv, cmd.reply_page); | |
| 395 | priv->alloc_rxb_page--; | ||
| 396 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); | ||
| 397 | 393 | ||
| 398 | return ret; | 394 | return ret; |
| 399 | } | 395 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 00da5e152d46..87ce2bd292c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
| @@ -407,13 +407,14 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv) | |||
| 407 | int txq_id; | 407 | int txq_id; |
| 408 | 408 | ||
| 409 | /* Tx queues */ | 409 | /* Tx queues */ |
| 410 | if (priv->txq) | 410 | if (priv->txq) { |
| 411 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; | 411 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; |
| 412 | txq_id++) | 412 | txq_id++) |
| 413 | if (txq_id == IWL_CMD_QUEUE_NUM) | 413 | if (txq_id == IWL_CMD_QUEUE_NUM) |
| 414 | iwl_cmd_queue_free(priv); | 414 | iwl_cmd_queue_free(priv); |
| 415 | else | 415 | else |
| 416 | iwl_tx_queue_free(priv, txq_id); | 416 | iwl_tx_queue_free(priv, txq_id); |
| 417 | } | ||
| 417 | iwl_free_dma_ptr(priv, &priv->kw); | 418 | iwl_free_dma_ptr(priv, &priv->kw); |
| 418 | 419 | ||
| 419 | iwl_free_dma_ptr(priv, &priv->scd_bc_tbls); | 420 | iwl_free_dma_ptr(priv, &priv->scd_bc_tbls); |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 2a28a1f8b1fe..f8e4e4b18d02 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
| @@ -548,6 +548,9 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
| 548 | txq = &priv->txq[txq_id]; | 548 | txq = &priv->txq[txq_id]; |
| 549 | q = &txq->q; | 549 | q = &txq->q; |
| 550 | 550 | ||
| 551 | if ((iwl_queue_space(q) < q->high_mark)) | ||
| 552 | goto drop; | ||
| 553 | |||
| 551 | spin_lock_irqsave(&priv->lock, flags); | 554 | spin_lock_irqsave(&priv->lock, flags); |
| 552 | 555 | ||
| 553 | idx = get_cmd_index(q, q->write_ptr, 0); | 556 | idx = get_cmd_index(q, q->write_ptr, 0); |
| @@ -812,7 +815,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, | |||
| 812 | break; | 815 | break; |
| 813 | } | 816 | } |
| 814 | 817 | ||
| 815 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); | 818 | iwl_free_pages(priv, cmd.reply_page); |
| 816 | 819 | ||
| 817 | return rc; | 820 | return rc; |
| 818 | } | 821 | } |
| @@ -1198,9 +1201,7 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
| 1198 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, | 1201 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, |
| 1199 | PAGE_SIZE << priv->hw_params.rx_page_order, | 1202 | PAGE_SIZE << priv->hw_params.rx_page_order, |
| 1200 | PCI_DMA_FROMDEVICE); | 1203 | PCI_DMA_FROMDEVICE); |
| 1201 | priv->alloc_rxb_page--; | 1204 | __iwl_free_pages(priv, rxq->pool[i].page); |
| 1202 | __free_pages(rxq->pool[i].page, | ||
| 1203 | priv->hw_params.rx_page_order); | ||
| 1204 | rxq->pool[i].page = NULL; | 1205 | rxq->pool[i].page = NULL; |
| 1205 | } | 1206 | } |
| 1206 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | 1207 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); |
| @@ -1247,10 +1248,8 @@ static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rx | |||
| 1247 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, | 1248 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, |
| 1248 | PAGE_SIZE << priv->hw_params.rx_page_order, | 1249 | PAGE_SIZE << priv->hw_params.rx_page_order, |
| 1249 | PCI_DMA_FROMDEVICE); | 1250 | PCI_DMA_FROMDEVICE); |
| 1250 | __free_pages(rxq->pool[i].page, | 1251 | __iwl_free_pages(priv, rxq->pool[i].page); |
| 1251 | priv->hw_params.rx_page_order); | ||
| 1252 | rxq->pool[i].page = NULL; | 1252 | rxq->pool[i].page = NULL; |
| 1253 | priv->alloc_rxb_page--; | ||
| 1254 | } | 1253 | } |
| 1255 | } | 1254 | } |
| 1256 | 1255 | ||
| @@ -1300,47 +1299,6 @@ int iwl3945_calc_db_from_ratio(int sig_ratio) | |||
| 1300 | return (int)ratio2dB[sig_ratio]; | 1299 | return (int)ratio2dB[sig_ratio]; |
| 1301 | } | 1300 | } |
| 1302 | 1301 | ||
| 1303 | #define PERFECT_RSSI (-20) /* dBm */ | ||
| 1304 | #define WORST_RSSI (-95) /* dBm */ | ||
| 1305 | #define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI) | ||
| 1306 | |||
| 1307 | /* Calculate an indication of rx signal quality (a percentage, not dBm!). | ||
| 1308 | * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info | ||
| 1309 | * about formulas used below. */ | ||
| 1310 | int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm) | ||
| 1311 | { | ||
| 1312 | int sig_qual; | ||
| 1313 | int degradation = PERFECT_RSSI - rssi_dbm; | ||
| 1314 | |||
| 1315 | /* If we get a noise measurement, use signal-to-noise ratio (SNR) | ||
| 1316 | * as indicator; formula is (signal dbm - noise dbm). | ||
| 1317 | * SNR at or above 40 is a great signal (100%). | ||
| 1318 | * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator. | ||
| 1319 | * Weakest usable signal is usually 10 - 15 dB SNR. */ | ||
| 1320 | if (noise_dbm) { | ||
| 1321 | if (rssi_dbm - noise_dbm >= 40) | ||
| 1322 | return 100; | ||
| 1323 | else if (rssi_dbm < noise_dbm) | ||
| 1324 | return 0; | ||
| 1325 | sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2; | ||
| 1326 | |||
| 1327 | /* Else use just the signal level. | ||
| 1328 | * This formula is a least squares fit of data points collected and | ||
| 1329 | * compared with a reference system that had a percentage (%) display | ||
| 1330 | * for signal quality. */ | ||
| 1331 | } else | ||
| 1332 | sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation * | ||
| 1333 | (15 * RSSI_RANGE + 62 * degradation)) / | ||
| 1334 | (RSSI_RANGE * RSSI_RANGE); | ||
| 1335 | |||
| 1336 | if (sig_qual > 100) | ||
| 1337 | sig_qual = 100; | ||
| 1338 | else if (sig_qual < 1) | ||
| 1339 | sig_qual = 0; | ||
| 1340 | |||
| 1341 | return sig_qual; | ||
| 1342 | } | ||
| 1343 | |||
| 1344 | /** | 1302 | /** |
| 1345 | * iwl3945_rx_handle - Main entry function for receiving responses from uCode | 1303 | * iwl3945_rx_handle - Main entry function for receiving responses from uCode |
| 1346 | * | 1304 | * |
| @@ -1688,7 +1646,7 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | |||
| 1688 | } | 1646 | } |
| 1689 | 1647 | ||
| 1690 | #ifdef CONFIG_IWLWIFI_DEBUG | 1648 | #ifdef CONFIG_IWLWIFI_DEBUG |
| 1691 | if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)) | 1649 | if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) |
| 1692 | size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) | 1650 | size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) |
| 1693 | ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; | 1651 | ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; |
| 1694 | #else | 1652 | #else |
| @@ -3867,7 +3825,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv) | |||
| 3867 | priv->retry_rate = 1; | 3825 | priv->retry_rate = 1; |
| 3868 | priv->ibss_beacon = NULL; | 3826 | priv->ibss_beacon = NULL; |
| 3869 | 3827 | ||
| 3870 | spin_lock_init(&priv->lock); | ||
| 3871 | spin_lock_init(&priv->sta_lock); | 3828 | spin_lock_init(&priv->sta_lock); |
| 3872 | spin_lock_init(&priv->hcmd_lock); | 3829 | spin_lock_init(&priv->hcmd_lock); |
| 3873 | 3830 | ||
| @@ -3936,9 +3893,11 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) | |||
| 3936 | /* Tell mac80211 our characteristics */ | 3893 | /* Tell mac80211 our characteristics */ |
| 3937 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | 3894 | hw->flags = IEEE80211_HW_SIGNAL_DBM | |
| 3938 | IEEE80211_HW_NOISE_DBM | | 3895 | IEEE80211_HW_NOISE_DBM | |
| 3939 | IEEE80211_HW_SPECTRUM_MGMT | | 3896 | IEEE80211_HW_SPECTRUM_MGMT; |
| 3940 | IEEE80211_HW_SUPPORTS_PS | | 3897 | |
| 3941 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | 3898 | if (!priv->cfg->broken_powersave) |
| 3899 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | ||
| 3900 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | ||
| 3942 | 3901 | ||
| 3943 | hw->wiphy->interface_modes = | 3902 | hw->wiphy->interface_modes = |
| 3944 | BIT(NL80211_IFTYPE_STATION) | | 3903 | BIT(NL80211_IFTYPE_STATION) | |
| @@ -4057,10 +4016,11 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
| 4057 | * PCI Tx retries from interfering with C3 CPU state */ | 4016 | * PCI Tx retries from interfering with C3 CPU state */ |
| 4058 | pci_write_config_byte(pdev, 0x41, 0x00); | 4017 | pci_write_config_byte(pdev, 0x41, 0x00); |
| 4059 | 4018 | ||
| 4060 | /* this spin lock will be used in apm_ops.init and EEPROM access | 4019 | /* these spin locks will be used in apm_ops.init and EEPROM access |
| 4061 | * we should init now | 4020 | * we should init now |
| 4062 | */ | 4021 | */ |
| 4063 | spin_lock_init(&priv->reg_lock); | 4022 | spin_lock_init(&priv->reg_lock); |
| 4023 | spin_lock_init(&priv->lock); | ||
| 4064 | 4024 | ||
| 4065 | /*********************** | 4025 | /*********************** |
| 4066 | * 4. Read EEPROM | 4026 | * 4. Read EEPROM |
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h index 5a26bb05a33a..842811142bef 100644 --- a/drivers/net/wireless/iwmc3200wifi/iwm.h +++ b/drivers/net/wireless/iwmc3200wifi/iwm.h | |||
| @@ -268,7 +268,7 @@ struct iwm_priv { | |||
| 268 | 268 | ||
| 269 | struct sk_buff_head rx_list; | 269 | struct sk_buff_head rx_list; |
| 270 | struct list_head rx_tickets; | 270 | struct list_head rx_tickets; |
| 271 | struct list_head rx_packets[IWM_RX_ID_HASH]; | 271 | struct list_head rx_packets[IWM_RX_ID_HASH + 1]; |
| 272 | struct workqueue_struct *rx_wq; | 272 | struct workqueue_struct *rx_wq; |
| 273 | struct work_struct rx_worker; | 273 | struct work_struct rx_worker; |
| 274 | 274 | ||
| @@ -349,7 +349,7 @@ int iwm_up(struct iwm_priv *iwm); | |||
| 349 | int iwm_down(struct iwm_priv *iwm); | 349 | int iwm_down(struct iwm_priv *iwm); |
| 350 | 350 | ||
| 351 | /* TX API */ | 351 | /* TX API */ |
| 352 | u16 iwm_tid_to_queue(u16 tid); | 352 | int iwm_tid_to_queue(u16 tid); |
| 353 | void iwm_tx_credit_inc(struct iwm_priv *iwm, int id, int total_freed_pages); | 353 | void iwm_tx_credit_inc(struct iwm_priv *iwm, int id, int total_freed_pages); |
| 354 | void iwm_tx_worker(struct work_struct *work); | 354 | void iwm_tx_worker(struct work_struct *work); |
| 355 | int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev); | 355 | int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev); |
diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c index e4f0f8705f65..c4c0d23c63ec 100644 --- a/drivers/net/wireless/iwmc3200wifi/netdev.c +++ b/drivers/net/wireless/iwmc3200wifi/netdev.c | |||
| @@ -76,7 +76,7 @@ static int iwm_stop(struct net_device *ndev) | |||
| 76 | */ | 76 | */ |
| 77 | static const u16 iwm_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; | 77 | static const u16 iwm_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; |
| 78 | 78 | ||
| 79 | u16 iwm_tid_to_queue(u16 tid) | 79 | int iwm_tid_to_queue(u16 tid) |
| 80 | { | 80 | { |
| 81 | if (tid > IWM_UMAC_TID_NR - 2) | 81 | if (tid > IWM_UMAC_TID_NR - 2) |
| 82 | return -EINVAL; | 82 | return -EINVAL; |
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c index 1c57c1f72cba..6d6ed7485175 100644 --- a/drivers/net/wireless/iwmc3200wifi/rx.c +++ b/drivers/net/wireless/iwmc3200wifi/rx.c | |||
| @@ -1126,7 +1126,7 @@ static int iwm_ntf_stop_resume_tx(struct iwm_priv *iwm, u8 *buf, | |||
| 1126 | 1126 | ||
| 1127 | if (!stop) { | 1127 | if (!stop) { |
| 1128 | struct iwm_tx_queue *txq; | 1128 | struct iwm_tx_queue *txq; |
| 1129 | u16 queue = iwm_tid_to_queue(bit); | 1129 | int queue = iwm_tid_to_queue(bit); |
| 1130 | 1130 | ||
| 1131 | if (queue < 0) | 1131 | if (queue < 0) |
| 1132 | continue; | 1132 | continue; |
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index 2f91c9b808af..92b7a357a5e4 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #include <linux/delay.h> | 2 | #include <linux/delay.h> |
| 3 | #include <linux/etherdevice.h> | 3 | #include <linux/etherdevice.h> |
| 4 | #include <linux/netdevice.h> | 4 | #include <linux/netdevice.h> |
| 5 | #include <linux/if_ether.h> | ||
| 5 | #include <linux/if_arp.h> | 6 | #include <linux/if_arp.h> |
| 6 | #include <linux/kthread.h> | 7 | #include <linux/kthread.h> |
| 7 | #include <linux/kfifo.h> | 8 | #include <linux/kfifo.h> |
| @@ -351,8 +352,7 @@ int lbs_add_mesh(struct lbs_private *priv) | |||
| 351 | 352 | ||
| 352 | mesh_dev->netdev_ops = &mesh_netdev_ops; | 353 | mesh_dev->netdev_ops = &mesh_netdev_ops; |
| 353 | mesh_dev->ethtool_ops = &lbs_ethtool_ops; | 354 | mesh_dev->ethtool_ops = &lbs_ethtool_ops; |
| 354 | memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, | 355 | memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, ETH_ALEN); |
| 355 | sizeof(priv->dev->dev_addr)); | ||
| 356 | 356 | ||
| 357 | SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent); | 357 | SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent); |
| 358 | 358 | ||
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index c6a6c042b82f..b0b1c7841500 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c | |||
| @@ -567,11 +567,8 @@ int lbs_scan_networks(struct lbs_private *priv, int full_scan) | |||
| 567 | chan_count = lbs_scan_create_channel_list(priv, chan_list); | 567 | chan_count = lbs_scan_create_channel_list(priv, chan_list); |
| 568 | 568 | ||
| 569 | netif_stop_queue(priv->dev); | 569 | netif_stop_queue(priv->dev); |
| 570 | netif_carrier_off(priv->dev); | 570 | if (priv->mesh_dev) |
| 571 | if (priv->mesh_dev) { | ||
| 572 | netif_stop_queue(priv->mesh_dev); | 571 | netif_stop_queue(priv->mesh_dev); |
| 573 | netif_carrier_off(priv->mesh_dev); | ||
| 574 | } | ||
| 575 | 572 | ||
| 576 | /* Prepare to continue an interrupted scan */ | 573 | /* Prepare to continue an interrupted scan */ |
| 577 | lbs_deb_scan("chan_count %d, scan_channel %d\n", | 574 | lbs_deb_scan("chan_count %d, scan_channel %d\n", |
| @@ -635,16 +632,13 @@ out2: | |||
| 635 | priv->scan_channel = 0; | 632 | priv->scan_channel = 0; |
| 636 | 633 | ||
| 637 | out: | 634 | out: |
| 638 | if (priv->connect_status == LBS_CONNECTED) { | 635 | if (priv->connect_status == LBS_CONNECTED && !priv->tx_pending_len) |
| 639 | netif_carrier_on(priv->dev); | 636 | netif_wake_queue(priv->dev); |
| 640 | if (!priv->tx_pending_len) | 637 | |
| 641 | netif_wake_queue(priv->dev); | 638 | if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED) && |
| 642 | } | 639 | !priv->tx_pending_len) |
| 643 | if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED)) { | 640 | netif_wake_queue(priv->mesh_dev); |
| 644 | netif_carrier_on(priv->mesh_dev); | 641 | |
| 645 | if (!priv->tx_pending_len) | ||
| 646 | netif_wake_queue(priv->mesh_dev); | ||
| 647 | } | ||
| 648 | kfree(chan_list); | 642 | kfree(chan_list); |
| 649 | 643 | ||
| 650 | lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); | 644 | lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); |
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index a8eb9e1fcf36..4b1aab593a84 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c | |||
| @@ -2025,10 +2025,8 @@ static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info, | |||
| 2025 | if (priv->connect_status == LBS_CONNECTED) { | 2025 | if (priv->connect_status == LBS_CONNECTED) { |
| 2026 | memcpy(extra, priv->curbssparams.ssid, | 2026 | memcpy(extra, priv->curbssparams.ssid, |
| 2027 | priv->curbssparams.ssid_len); | 2027 | priv->curbssparams.ssid_len); |
| 2028 | extra[priv->curbssparams.ssid_len] = '\0'; | ||
| 2029 | } else { | 2028 | } else { |
| 2030 | memset(extra, 0, 32); | 2029 | memset(extra, 0, 32); |
| 2031 | extra[priv->curbssparams.ssid_len] = '\0'; | ||
| 2032 | } | 2030 | } |
| 2033 | /* | 2031 | /* |
| 2034 | * If none, we may want to get the one that was set | 2032 | * If none, we may want to get the one that was set |
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c index 019431d2f8a9..26a1abd5bb03 100644 --- a/drivers/net/wireless/libertas_tf/main.c +++ b/drivers/net/wireless/libertas_tf/main.c | |||
| @@ -495,7 +495,6 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) | |||
| 495 | stats.band = IEEE80211_BAND_2GHZ; | 495 | stats.band = IEEE80211_BAND_2GHZ; |
| 496 | stats.signal = prxpd->snr; | 496 | stats.signal = prxpd->snr; |
| 497 | stats.noise = prxpd->nf; | 497 | stats.noise = prxpd->nf; |
| 498 | stats.qual = prxpd->snr - prxpd->nf; | ||
| 499 | /* Marvell rate index has a hole at value 4 */ | 498 | /* Marvell rate index has a hole at value 4 */ |
| 500 | if (prxpd->rx_rate > 4) | 499 | if (prxpd->rx_rate > 4) |
| 501 | --prxpd->rx_rate; | 500 | --prxpd->rx_rate; |
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c index 7698fdd6a3a2..31ca241f7753 100644 --- a/drivers/net/wireless/orinoco/wext.c +++ b/drivers/net/wireless/orinoco/wext.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #define MAX_RID_LEN 1024 | 23 | #define MAX_RID_LEN 1024 |
| 24 | 24 | ||
| 25 | /* Helper routine to record keys | 25 | /* Helper routine to record keys |
| 26 | * Do not call from interrupt context */ | 26 | * It is called under orinoco_lock so it may not sleep */ |
| 27 | static int orinoco_set_key(struct orinoco_private *priv, int index, | 27 | static int orinoco_set_key(struct orinoco_private *priv, int index, |
| 28 | enum orinoco_alg alg, const u8 *key, int key_len, | 28 | enum orinoco_alg alg, const u8 *key, int key_len, |
| 29 | const u8 *seq, int seq_len) | 29 | const u8 *seq, int seq_len) |
| @@ -32,14 +32,14 @@ static int orinoco_set_key(struct orinoco_private *priv, int index, | |||
| 32 | kzfree(priv->keys[index].seq); | 32 | kzfree(priv->keys[index].seq); |
| 33 | 33 | ||
| 34 | if (key_len) { | 34 | if (key_len) { |
| 35 | priv->keys[index].key = kzalloc(key_len, GFP_KERNEL); | 35 | priv->keys[index].key = kzalloc(key_len, GFP_ATOMIC); |
| 36 | if (!priv->keys[index].key) | 36 | if (!priv->keys[index].key) |
| 37 | goto nomem; | 37 | goto nomem; |
| 38 | } else | 38 | } else |
| 39 | priv->keys[index].key = NULL; | 39 | priv->keys[index].key = NULL; |
| 40 | 40 | ||
| 41 | if (seq_len) { | 41 | if (seq_len) { |
| 42 | priv->keys[index].seq = kzalloc(seq_len, GFP_KERNEL); | 42 | priv->keys[index].seq = kzalloc(seq_len, GFP_ATOMIC); |
| 43 | if (!priv->keys[index].seq) | 43 | if (!priv->keys[index].seq) |
| 44 | goto free_key; | 44 | goto free_key; |
| 45 | } else | 45 | } else |
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index c5fe867665e6..1a7eae357fef 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h | |||
| @@ -1323,7 +1323,7 @@ | |||
| 1323 | #define PAIRWISE_KEY_ENTRY(__idx) \ | 1323 | #define PAIRWISE_KEY_ENTRY(__idx) \ |
| 1324 | ( PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) ) | 1324 | ( PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) ) |
| 1325 | #define MAC_IVEIV_ENTRY(__idx) \ | 1325 | #define MAC_IVEIV_ENTRY(__idx) \ |
| 1326 | ( MAC_IVEIV_TABLE_BASE + ((__idx) & sizeof(struct mac_iveiv_entry)) ) | 1326 | ( MAC_IVEIV_TABLE_BASE + ((__idx) * sizeof(struct mac_iveiv_entry)) ) |
| 1327 | #define MAC_WCID_ATTR_ENTRY(__idx) \ | 1327 | #define MAC_WCID_ATTR_ENTRY(__idx) \ |
| 1328 | ( MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)) ) | 1328 | ( MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)) ) |
| 1329 | #define SHARED_KEY_ENTRY(__idx) \ | 1329 | #define SHARED_KEY_ENTRY(__idx) \ |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index eb1e1d00bec3..27bf887f1453 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
| @@ -37,7 +37,7 @@ | |||
| 37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
| 38 | 38 | ||
| 39 | #include "rt2x00.h" | 39 | #include "rt2x00.h" |
| 40 | #ifdef CONFIG_RT2800USB | 40 | #if defined(CONFIG_RT2800USB) || defined(CONFIG_RT2800USB_MODULE) |
| 41 | #include "rt2x00usb.h" | 41 | #include "rt2x00usb.h" |
| 42 | #endif | 42 | #endif |
| 43 | #include "rt2800lib.h" | 43 | #include "rt2800lib.h" |
| @@ -1121,7 +1121,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
| 1121 | 1121 | ||
| 1122 | if (rt2x00_intf_is_usb(rt2x00dev)) { | 1122 | if (rt2x00_intf_is_usb(rt2x00dev)) { |
| 1123 | rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000); | 1123 | rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000); |
| 1124 | #ifdef CONFIG_RT2800USB | 1124 | #if defined(CONFIG_RT2800USB) || defined(CONFIG_RT2800USB_MODULE) |
| 1125 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, | 1125 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, |
| 1126 | USB_MODE_RESET, REGISTER_TIMEOUT); | 1126 | USB_MODE_RESET, REGISTER_TIMEOUT); |
| 1127 | #endif | 1127 | #endif |
| @@ -2022,6 +2022,12 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
| 2022 | u16 eeprom; | 2022 | u16 eeprom; |
| 2023 | 2023 | ||
| 2024 | /* | 2024 | /* |
| 2025 | * Disable powersaving as default on PCI devices. | ||
| 2026 | */ | ||
| 2027 | if (rt2x00_intf_is_pci(rt2x00dev)) | ||
| 2028 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
| 2029 | |||
| 2030 | /* | ||
| 2025 | * Initialize all hw fields. | 2031 | * Initialize all hw fields. |
| 2026 | */ | 2032 | */ |
| 2027 | rt2x00dev->hw->flags = | 2033 | rt2x00dev->hw->flags = |
| @@ -2074,8 +2080,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
| 2074 | IEEE80211_HT_CAP_SGI_20 | | 2080 | IEEE80211_HT_CAP_SGI_20 | |
| 2075 | IEEE80211_HT_CAP_SGI_40 | | 2081 | IEEE80211_HT_CAP_SGI_40 | |
| 2076 | IEEE80211_HT_CAP_TX_STBC | | 2082 | IEEE80211_HT_CAP_TX_STBC | |
| 2077 | IEEE80211_HT_CAP_RX_STBC | | 2083 | IEEE80211_HT_CAP_RX_STBC; |
| 2078 | IEEE80211_HT_CAP_PSMP_SUPPORT; | ||
| 2079 | spec->ht.ampdu_factor = 3; | 2084 | spec->ht.ampdu_factor = 3; |
| 2080 | spec->ht.ampdu_density = 4; | 2085 | spec->ht.ampdu_density = 4; |
| 2081 | spec->ht.mcs.tx_params = | 2086 | spec->ht.mcs.tx_params = |
| @@ -2140,8 +2145,8 @@ static void rt2800_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx, | |||
| 2140 | rt2800_register_multiread(rt2x00dev, offset, | 2145 | rt2800_register_multiread(rt2x00dev, offset, |
| 2141 | &iveiv_entry, sizeof(iveiv_entry)); | 2146 | &iveiv_entry, sizeof(iveiv_entry)); |
| 2142 | 2147 | ||
| 2143 | memcpy(&iveiv_entry.iv[0], iv16, sizeof(iv16)); | 2148 | memcpy(iv16, &iveiv_entry.iv[0], sizeof(*iv16)); |
| 2144 | memcpy(&iveiv_entry.iv[4], iv32, sizeof(iv32)); | 2149 | memcpy(iv32, &iveiv_entry.iv[4], sizeof(*iv32)); |
| 2145 | } | 2150 | } |
| 2146 | 2151 | ||
| 2147 | static int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value) | 2152 | static int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value) |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index af85d18cdbe7..ab95346cf6a3 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
| @@ -922,6 +922,7 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
| 922 | { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) }, | 922 | { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) }, |
| 923 | { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) }, | 923 | { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) }, |
| 924 | { USB_DEVICE(0x1737, 0x0077), USB_DEVICE_DATA(&rt2800usb_ops) }, | 924 | { USB_DEVICE(0x1737, 0x0077), USB_DEVICE_DATA(&rt2800usb_ops) }, |
| 925 | { USB_DEVICE(0x1737, 0x0079), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
| 925 | /* Logitec */ | 926 | /* Logitec */ |
| 926 | { USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) }, | 927 | { USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) }, |
| 927 | { USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) }, | 928 | { USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) }, |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 687e17dc2e9f..0ca589306d71 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
| @@ -2539,6 +2539,11 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
| 2539 | unsigned int i; | 2539 | unsigned int i; |
| 2540 | 2540 | ||
| 2541 | /* | 2541 | /* |
| 2542 | * Disable powersaving as default. | ||
| 2543 | */ | ||
| 2544 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
| 2545 | |||
| 2546 | /* | ||
| 2542 | * Initialize all hw fields. | 2547 | * Initialize all hw fields. |
| 2543 | */ | 2548 | */ |
| 2544 | rt2x00dev->hw->flags = | 2549 | rt2x00dev->hw->flags = |
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index a1a3dd15c664..8a40a1439984 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c | |||
| @@ -132,7 +132,6 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
| 132 | 132 | ||
| 133 | rx_status.antenna = (flags2 >> 15) & 1; | 133 | rx_status.antenna = (flags2 >> 15) & 1; |
| 134 | /* TODO: improve signal/rssi reporting */ | 134 | /* TODO: improve signal/rssi reporting */ |
| 135 | rx_status.qual = flags2 & 0xFF; | ||
| 136 | rx_status.signal = (flags2 >> 8) & 0x7F; | 135 | rx_status.signal = (flags2 >> 8) & 0x7F; |
| 137 | /* XXX: is this correct? */ | 136 | /* XXX: is this correct? */ |
| 138 | rx_status.rate_idx = (flags >> 20) & 0xF; | 137 | rx_status.rate_idx = (flags >> 20) & 0xF; |
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c index 2e733e7bdfd4..28a808674080 100644 --- a/drivers/net/wireless/wl12xx/wl1251_boot.c +++ b/drivers/net/wireless/wl12xx/wl1251_boot.c | |||
| @@ -256,7 +256,7 @@ int wl1251_boot_run_firmware(struct wl1251 *wl) | |||
| 256 | } | 256 | } |
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | if (loop >= INIT_LOOP) { | 259 | if (loop > INIT_LOOP) { |
| 260 | wl1251_error("timeout waiting for the hardware to " | 260 | wl1251_error("timeout waiting for the hardware to " |
| 261 | "complete initialization"); | 261 | "complete initialization"); |
| 262 | return -EIO; | 262 | return -EIO; |
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index 886a9bc39cc1..c3385b3d246c 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c | |||
| @@ -777,7 +777,7 @@ out: | |||
| 777 | return ret; | 777 | return ret; |
| 778 | } | 778 | } |
| 779 | 779 | ||
| 780 | static int wl1271_build_basic_rates(char *rates, u8 band) | 780 | static int wl1271_build_basic_rates(u8 *rates, u8 band) |
| 781 | { | 781 | { |
| 782 | u8 index = 0; | 782 | u8 index = 0; |
| 783 | 783 | ||
| @@ -804,7 +804,7 @@ static int wl1271_build_basic_rates(char *rates, u8 band) | |||
| 804 | return index; | 804 | return index; |
| 805 | } | 805 | } |
| 806 | 806 | ||
| 807 | static int wl1271_build_extended_rates(char *rates, u8 band) | 807 | static int wl1271_build_extended_rates(u8 *rates, u8 band) |
| 808 | { | 808 | { |
| 809 | u8 index = 0; | 809 | u8 index = 0; |
| 810 | 810 | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index dfa1b9bc22c8..7ca95c414fa8 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c | |||
| @@ -1325,151 +1325,11 @@ int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates) | |||
| 1325 | return r; | 1325 | return r; |
| 1326 | } | 1326 | } |
| 1327 | 1327 | ||
| 1328 | static int ofdm_qual_db(u8 status_quality, u8 zd_rate, unsigned int size) | ||
| 1329 | { | ||
| 1330 | static const u16 constants[] = { | ||
| 1331 | 715, 655, 585, 540, 470, 410, 360, 315, | ||
| 1332 | 270, 235, 205, 175, 150, 125, 105, 85, | ||
| 1333 | 65, 50, 40, 25, 15 | ||
| 1334 | }; | ||
| 1335 | |||
| 1336 | int i; | ||
| 1337 | u32 x; | ||
| 1338 | |||
| 1339 | /* It seems that their quality parameter is somehow per signal | ||
| 1340 | * and is now transferred per bit. | ||
| 1341 | */ | ||
| 1342 | switch (zd_rate) { | ||
| 1343 | case ZD_OFDM_RATE_6M: | ||
| 1344 | case ZD_OFDM_RATE_12M: | ||
| 1345 | case ZD_OFDM_RATE_24M: | ||
| 1346 | size *= 2; | ||
| 1347 | break; | ||
| 1348 | case ZD_OFDM_RATE_9M: | ||
| 1349 | case ZD_OFDM_RATE_18M: | ||
| 1350 | case ZD_OFDM_RATE_36M: | ||
| 1351 | case ZD_OFDM_RATE_54M: | ||
| 1352 | size *= 4; | ||
| 1353 | size /= 3; | ||
| 1354 | break; | ||
| 1355 | case ZD_OFDM_RATE_48M: | ||
| 1356 | size *= 3; | ||
| 1357 | size /= 2; | ||
| 1358 | break; | ||
| 1359 | default: | ||
| 1360 | return -EINVAL; | ||
| 1361 | } | ||
| 1362 | |||
| 1363 | x = (10000 * status_quality)/size; | ||
| 1364 | for (i = 0; i < ARRAY_SIZE(constants); i++) { | ||
| 1365 | if (x > constants[i]) | ||
| 1366 | break; | ||
| 1367 | } | ||
| 1368 | |||
| 1369 | switch (zd_rate) { | ||
| 1370 | case ZD_OFDM_RATE_6M: | ||
| 1371 | case ZD_OFDM_RATE_9M: | ||
| 1372 | i += 3; | ||
| 1373 | break; | ||
| 1374 | case ZD_OFDM_RATE_12M: | ||
| 1375 | case ZD_OFDM_RATE_18M: | ||
| 1376 | i += 5; | ||
| 1377 | break; | ||
| 1378 | case ZD_OFDM_RATE_24M: | ||
| 1379 | case ZD_OFDM_RATE_36M: | ||
| 1380 | i += 9; | ||
| 1381 | break; | ||
| 1382 | case ZD_OFDM_RATE_48M: | ||
| 1383 | case ZD_OFDM_RATE_54M: | ||
| 1384 | i += 15; | ||
| 1385 | break; | ||
| 1386 | default: | ||
| 1387 | return -EINVAL; | ||
| 1388 | } | ||
| 1389 | |||
| 1390 | return i; | ||
| 1391 | } | ||
| 1392 | |||
| 1393 | static int ofdm_qual_percent(u8 status_quality, u8 zd_rate, unsigned int size) | ||
| 1394 | { | ||
| 1395 | int r; | ||
| 1396 | |||
| 1397 | r = ofdm_qual_db(status_quality, zd_rate, size); | ||
| 1398 | ZD_ASSERT(r >= 0); | ||
| 1399 | if (r < 0) | ||
| 1400 | r = 0; | ||
| 1401 | |||
| 1402 | r = (r * 100)/29; | ||
| 1403 | return r <= 100 ? r : 100; | ||
| 1404 | } | ||
| 1405 | |||
| 1406 | static unsigned int log10times100(unsigned int x) | ||
| 1407 | { | ||
| 1408 | static const u8 log10[] = { | ||
| 1409 | 0, | ||
| 1410 | 0, 30, 47, 60, 69, 77, 84, 90, 95, 100, | ||
| 1411 | 104, 107, 111, 114, 117, 120, 123, 125, 127, 130, | ||
| 1412 | 132, 134, 136, 138, 139, 141, 143, 144, 146, 147, | ||
| 1413 | 149, 150, 151, 153, 154, 155, 156, 157, 159, 160, | ||
| 1414 | 161, 162, 163, 164, 165, 166, 167, 168, 169, 169, | ||
| 1415 | 170, 171, 172, 173, 174, 174, 175, 176, 177, 177, | ||
| 1416 | 178, 179, 179, 180, 181, 181, 182, 183, 183, 184, | ||
| 1417 | 185, 185, 186, 186, 187, 188, 188, 189, 189, 190, | ||
| 1418 | 190, 191, 191, 192, 192, 193, 193, 194, 194, 195, | ||
| 1419 | 195, 196, 196, 197, 197, 198, 198, 199, 199, 200, | ||
| 1420 | 200, 200, 201, 201, 202, 202, 202, 203, 203, 204, | ||
| 1421 | 204, 204, 205, 205, 206, 206, 206, 207, 207, 207, | ||
| 1422 | 208, 208, 208, 209, 209, 210, 210, 210, 211, 211, | ||
| 1423 | 211, 212, 212, 212, 213, 213, 213, 213, 214, 214, | ||
| 1424 | 214, 215, 215, 215, 216, 216, 216, 217, 217, 217, | ||
| 1425 | 217, 218, 218, 218, 219, 219, 219, 219, 220, 220, | ||
| 1426 | 220, 220, 221, 221, 221, 222, 222, 222, 222, 223, | ||
| 1427 | 223, 223, 223, 224, 224, 224, 224, | ||
| 1428 | }; | ||
| 1429 | |||
| 1430 | return x < ARRAY_SIZE(log10) ? log10[x] : 225; | ||
| 1431 | } | ||
| 1432 | |||
| 1433 | enum { | ||
| 1434 | MAX_CCK_EVM_DB = 45, | ||
| 1435 | }; | ||
| 1436 | |||
| 1437 | static int cck_evm_db(u8 status_quality) | ||
| 1438 | { | ||
| 1439 | return (20 * log10times100(status_quality)) / 100; | ||
| 1440 | } | ||
| 1441 | |||
| 1442 | static int cck_snr_db(u8 status_quality) | ||
| 1443 | { | ||
| 1444 | int r = MAX_CCK_EVM_DB - cck_evm_db(status_quality); | ||
| 1445 | ZD_ASSERT(r >= 0); | ||
| 1446 | return r; | ||
| 1447 | } | ||
| 1448 | |||
| 1449 | static int cck_qual_percent(u8 status_quality) | ||
| 1450 | { | ||
| 1451 | int r; | ||
| 1452 | |||
| 1453 | r = cck_snr_db(status_quality); | ||
| 1454 | r = (100*r)/17; | ||
| 1455 | return r <= 100 ? r : 100; | ||
| 1456 | } | ||
| 1457 | |||
| 1458 | static inline u8 zd_rate_from_ofdm_plcp_header(const void *rx_frame) | 1328 | static inline u8 zd_rate_from_ofdm_plcp_header(const void *rx_frame) |
| 1459 | { | 1329 | { |
| 1460 | return ZD_OFDM | zd_ofdm_plcp_header_rate(rx_frame); | 1330 | return ZD_OFDM | zd_ofdm_plcp_header_rate(rx_frame); |
| 1461 | } | 1331 | } |
| 1462 | 1332 | ||
| 1463 | u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size, | ||
| 1464 | const struct rx_status *status) | ||
| 1465 | { | ||
| 1466 | return (status->frame_status&ZD_RX_OFDM) ? | ||
| 1467 | ofdm_qual_percent(status->signal_quality_ofdm, | ||
| 1468 | zd_rate_from_ofdm_plcp_header(rx_frame), | ||
| 1469 | size) : | ||
| 1470 | cck_qual_percent(status->signal_quality_cck); | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | /** | 1333 | /** |
| 1474 | * zd_rx_rate - report zd-rate | 1334 | * zd_rx_rate - report zd-rate |
| 1475 | * @rx_frame - received frame | 1335 | * @rx_frame - received frame |
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index 9fd8f3508d66..f8bbf7d302ae 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h | |||
| @@ -929,9 +929,6 @@ static inline int zd_get_beacon_interval(struct zd_chip *chip, u32 *interval) | |||
| 929 | 929 | ||
| 930 | struct rx_status; | 930 | struct rx_status; |
| 931 | 931 | ||
| 932 | u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size, | ||
| 933 | const struct rx_status *status); | ||
| 934 | |||
| 935 | u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status); | 932 | u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status); |
| 936 | 933 | ||
| 937 | struct zd_mc_hash { | 934 | struct zd_mc_hash { |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index cf51e8f8174b..8ebf5c33955d 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
| @@ -828,9 +828,6 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) | |||
| 828 | stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq; | 828 | stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq; |
| 829 | stats.band = IEEE80211_BAND_2GHZ; | 829 | stats.band = IEEE80211_BAND_2GHZ; |
| 830 | stats.signal = status->signal_strength; | 830 | stats.signal = status->signal_strength; |
| 831 | stats.qual = zd_rx_qual_percent(buffer, | ||
| 832 | length - sizeof(struct rx_status), | ||
| 833 | status); | ||
| 834 | 831 | ||
| 835 | rate = zd_rx_rate(buffer, status); | 832 | rate = zd_rx_rate(buffer, status); |
| 836 | 833 | ||
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index d9724a28c0c2..163c840437d6 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h | |||
| @@ -832,7 +832,7 @@ struct ieee80211_ht_cap { | |||
| 832 | #define IEEE80211_HT_CAP_DELAY_BA 0x0400 | 832 | #define IEEE80211_HT_CAP_DELAY_BA 0x0400 |
| 833 | #define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 | 833 | #define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 |
| 834 | #define IEEE80211_HT_CAP_DSSSCCK40 0x1000 | 834 | #define IEEE80211_HT_CAP_DSSSCCK40 0x1000 |
| 835 | #define IEEE80211_HT_CAP_PSMP_SUPPORT 0x2000 | 835 | #define IEEE80211_HT_CAP_RESERVED 0x2000 |
| 836 | #define IEEE80211_HT_CAP_40MHZ_INTOLERANT 0x4000 | 836 | #define IEEE80211_HT_CAP_40MHZ_INTOLERANT 0x4000 |
| 837 | #define IEEE80211_HT_CAP_LSIG_TXOP_PROT 0x8000 | 837 | #define IEEE80211_HT_CAP_LSIG_TXOP_PROT 0x8000 |
| 838 | 838 | ||
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index 699e85c01a4d..b2304929434e 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h | |||
| @@ -81,6 +81,7 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev) | |||
| 81 | #define IN_DEV_FORWARD(in_dev) IN_DEV_CONF_GET((in_dev), FORWARDING) | 81 | #define IN_DEV_FORWARD(in_dev) IN_DEV_CONF_GET((in_dev), FORWARDING) |
| 82 | #define IN_DEV_MFORWARD(in_dev) IN_DEV_ANDCONF((in_dev), MC_FORWARDING) | 82 | #define IN_DEV_MFORWARD(in_dev) IN_DEV_ANDCONF((in_dev), MC_FORWARDING) |
| 83 | #define IN_DEV_RPFILTER(in_dev) IN_DEV_MAXCONF((in_dev), RP_FILTER) | 83 | #define IN_DEV_RPFILTER(in_dev) IN_DEV_MAXCONF((in_dev), RP_FILTER) |
| 84 | #define IN_DEV_SRC_VMARK(in_dev) IN_DEV_ORCONF((in_dev), SRC_VMARK) | ||
| 84 | #define IN_DEV_SOURCE_ROUTE(in_dev) IN_DEV_ANDCONF((in_dev), \ | 85 | #define IN_DEV_SOURCE_ROUTE(in_dev) IN_DEV_ANDCONF((in_dev), \ |
| 85 | ACCEPT_SOURCE_ROUTE) | 86 | ACCEPT_SOURCE_ROUTE) |
| 86 | #define IN_DEV_ACCEPT_LOCAL(in_dev) IN_DEV_ORCONF((in_dev), ACCEPT_LOCAL) | 87 | #define IN_DEV_ACCEPT_LOCAL(in_dev) IN_DEV_ORCONF((in_dev), ACCEPT_LOCAL) |
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 877ba039e6a4..bd27fbc9db62 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h | |||
| @@ -482,6 +482,7 @@ enum | |||
| 482 | NET_IPV4_CONF_ARP_ACCEPT=21, | 482 | NET_IPV4_CONF_ARP_ACCEPT=21, |
| 483 | NET_IPV4_CONF_ARP_NOTIFY=22, | 483 | NET_IPV4_CONF_ARP_NOTIFY=22, |
| 484 | NET_IPV4_CONF_ACCEPT_LOCAL=23, | 484 | NET_IPV4_CONF_ACCEPT_LOCAL=23, |
| 485 | NET_IPV4_CONF_SRC_VMARK=24, | ||
| 485 | __NET_IPV4_CONF_MAX | 486 | __NET_IPV4_CONF_MAX |
| 486 | }; | 487 | }; |
| 487 | 488 | ||
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 2aff4906b2ae..0bf369752274 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
| @@ -547,7 +547,6 @@ enum mac80211_rx_flags { | |||
| 547 | * unspecified depending on the hardware capabilities flags | 547 | * unspecified depending on the hardware capabilities flags |
| 548 | * @IEEE80211_HW_SIGNAL_* | 548 | * @IEEE80211_HW_SIGNAL_* |
| 549 | * @noise: noise when receiving this frame, in dBm. | 549 | * @noise: noise when receiving this frame, in dBm. |
| 550 | * @qual: overall signal quality indication, in percent (0-100). | ||
| 551 | * @antenna: antenna used | 550 | * @antenna: antenna used |
| 552 | * @rate_idx: index of data rate into band's supported rates or MCS index if | 551 | * @rate_idx: index of data rate into band's supported rates or MCS index if |
| 553 | * HT rates are use (RX_FLAG_HT) | 552 | * HT rates are use (RX_FLAG_HT) |
| @@ -559,7 +558,6 @@ struct ieee80211_rx_status { | |||
| 559 | int freq; | 558 | int freq; |
| 560 | int signal; | 559 | int signal; |
| 561 | int noise; | 560 | int noise; |
| 562 | int __deprecated qual; | ||
| 563 | int antenna; | 561 | int antenna; |
| 564 | int rate_idx; | 562 | int rate_idx; |
| 565 | int flag; | 563 | int flag; |
| @@ -1737,6 +1735,12 @@ static inline void ieee80211_rx_ni(struct ieee80211_hw *hw, | |||
| 1737 | local_bh_enable(); | 1735 | local_bh_enable(); |
| 1738 | } | 1736 | } |
| 1739 | 1737 | ||
| 1738 | /* | ||
| 1739 | * The TX headroom reserved by mac80211 for its own tx_status functions. | ||
| 1740 | * This is enough for the radiotap header. | ||
| 1741 | */ | ||
| 1742 | #define IEEE80211_TX_STATUS_HEADROOM 13 | ||
| 1743 | |||
| 1740 | /** | 1744 | /** |
| 1741 | * ieee80211_tx_status - transmit status callback | 1745 | * ieee80211_tx_status - transmit status callback |
| 1742 | * | 1746 | * |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index a23b45f08ec9..de0c2c726420 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
| @@ -250,8 +250,7 @@ struct pktgen_dev { | |||
| 250 | __u64 count; /* Default No packets to send */ | 250 | __u64 count; /* Default No packets to send */ |
| 251 | __u64 sofar; /* How many pkts we've sent so far */ | 251 | __u64 sofar; /* How many pkts we've sent so far */ |
| 252 | __u64 tx_bytes; /* How many bytes we've transmitted */ | 252 | __u64 tx_bytes; /* How many bytes we've transmitted */ |
| 253 | __u64 errors; /* Errors when trying to transmit, | 253 | __u64 errors; /* Errors when trying to transmit, */ |
| 254 | pkts will be re-sent */ | ||
| 255 | 254 | ||
| 256 | /* runtime counters relating to clone_skb */ | 255 | /* runtime counters relating to clone_skb */ |
| 257 | 256 | ||
| @@ -3465,6 +3464,12 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev) | |||
| 3465 | pkt_dev->seq_num++; | 3464 | pkt_dev->seq_num++; |
| 3466 | pkt_dev->tx_bytes += pkt_dev->last_pkt_size; | 3465 | pkt_dev->tx_bytes += pkt_dev->last_pkt_size; |
| 3467 | break; | 3466 | break; |
| 3467 | case NET_XMIT_DROP: | ||
| 3468 | case NET_XMIT_CN: | ||
| 3469 | case NET_XMIT_POLICED: | ||
| 3470 | /* skb has been consumed */ | ||
| 3471 | pkt_dev->errors++; | ||
| 3472 | break; | ||
| 3468 | default: /* Drivers are not supposed to return other values! */ | 3473 | default: /* Drivers are not supposed to return other values! */ |
| 3469 | if (net_ratelimit()) | 3474 | if (net_ratelimit()) |
| 3470 | pr_info("pktgen: %s xmit error: %d\n", | 3475 | pr_info("pktgen: %s xmit error: %d\n", |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 5cdbc102a418..040c4f05b653 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
| @@ -1397,6 +1397,7 @@ static struct devinet_sysctl_table { | |||
| 1397 | DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE, | 1397 | DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE, |
| 1398 | "accept_source_route"), | 1398 | "accept_source_route"), |
| 1399 | DEVINET_SYSCTL_RW_ENTRY(ACCEPT_LOCAL, "accept_local"), | 1399 | DEVINET_SYSCTL_RW_ENTRY(ACCEPT_LOCAL, "accept_local"), |
| 1400 | DEVINET_SYSCTL_RW_ENTRY(SRC_VMARK, "src_valid_mark"), | ||
| 1400 | DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"), | 1401 | DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"), |
| 1401 | DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"), | 1402 | DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"), |
| 1402 | DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"), | 1403 | DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"), |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 3323168ee52d..82dbf711d6d0 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
| @@ -252,6 +252,8 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, | |||
| 252 | no_addr = in_dev->ifa_list == NULL; | 252 | no_addr = in_dev->ifa_list == NULL; |
| 253 | rpf = IN_DEV_RPFILTER(in_dev); | 253 | rpf = IN_DEV_RPFILTER(in_dev); |
| 254 | accept_local = IN_DEV_ACCEPT_LOCAL(in_dev); | 254 | accept_local = IN_DEV_ACCEPT_LOCAL(in_dev); |
| 255 | if (mark && !IN_DEV_SRC_VMARK(in_dev)) | ||
| 256 | fl.mark = 0; | ||
| 255 | } | 257 | } |
| 256 | rcu_read_unlock(); | 258 | rcu_read_unlock(); |
| 257 | 259 | ||
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 3787455fb696..d7dcee680728 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
| @@ -34,9 +34,28 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, | |||
| 34 | 34 | ||
| 35 | ht_cap->ht_supported = true; | 35 | ht_cap->ht_supported = true; |
| 36 | 36 | ||
| 37 | ht_cap->cap = le16_to_cpu(ht_cap_ie->cap_info) & sband->ht_cap.cap; | 37 | /* |
| 38 | ht_cap->cap &= ~IEEE80211_HT_CAP_SM_PS; | 38 | * The bits listed in this expression should be |
| 39 | ht_cap->cap |= sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS; | 39 | * the same for the peer and us, if the station |
| 40 | * advertises more then we can't use those thus | ||
| 41 | * we mask them out. | ||
| 42 | */ | ||
| 43 | ht_cap->cap = le16_to_cpu(ht_cap_ie->cap_info) & | ||
| 44 | (sband->ht_cap.cap | | ||
| 45 | ~(IEEE80211_HT_CAP_LDPC_CODING | | ||
| 46 | IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
| 47 | IEEE80211_HT_CAP_GRN_FLD | | ||
| 48 | IEEE80211_HT_CAP_SGI_20 | | ||
| 49 | IEEE80211_HT_CAP_SGI_40 | | ||
| 50 | IEEE80211_HT_CAP_DSSSCCK40)); | ||
| 51 | /* | ||
| 52 | * The STBC bits are asymmetric -- if we don't have | ||
| 53 | * TX then mask out the peer's RX and vice versa. | ||
| 54 | */ | ||
| 55 | if (!(sband->ht_cap.cap & IEEE80211_HT_CAP_TX_STBC)) | ||
| 56 | ht_cap->cap &= ~IEEE80211_HT_CAP_RX_STBC; | ||
| 57 | if (!(sband->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)) | ||
| 58 | ht_cap->cap &= ~IEEE80211_HT_CAP_TX_STBC; | ||
| 40 | 59 | ||
| 41 | ampdu_info = ht_cap_ie->ampdu_params_info; | 60 | ampdu_info = ht_cap_ie->ampdu_params_info; |
| 42 | ht_cap->ampdu_factor = | 61 | ht_cap->ampdu_factor = |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 10d13856f86c..1f2db647bb5c 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
| @@ -382,6 +382,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
| 382 | struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | 382 | struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, |
| 383 | u8 *bssid,u8 *addr, u32 supp_rates) | 383 | u8 *bssid,u8 *addr, u32 supp_rates) |
| 384 | { | 384 | { |
| 385 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | ||
| 385 | struct ieee80211_local *local = sdata->local; | 386 | struct ieee80211_local *local = sdata->local; |
| 386 | struct sta_info *sta; | 387 | struct sta_info *sta; |
| 387 | int band = local->hw.conf.channel->band; | 388 | int band = local->hw.conf.channel->band; |
| @@ -397,6 +398,9 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
| 397 | return NULL; | 398 | return NULL; |
| 398 | } | 399 | } |
| 399 | 400 | ||
| 401 | if (ifibss->state == IEEE80211_IBSS_MLME_SEARCH) | ||
| 402 | return NULL; | ||
| 403 | |||
| 400 | if (compare_ether_addr(bssid, sdata->u.ibss.bssid)) | 404 | if (compare_ether_addr(bssid, sdata->u.ibss.bssid)) |
| 401 | return NULL; | 405 | return NULL; |
| 402 | 406 | ||
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 8116d1a96a4a..0d2d94881f1f 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
| @@ -515,6 +515,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 515 | * and we need some headroom for passing the frame to monitor | 515 | * and we need some headroom for passing the frame to monitor |
| 516 | * interfaces, but never both at the same time. | 516 | * interfaces, but never both at the same time. |
| 517 | */ | 517 | */ |
| 518 | BUILD_BUG_ON(IEEE80211_TX_STATUS_HEADROOM != | ||
| 519 | sizeof(struct ieee80211_tx_status_rtap_hdr)); | ||
| 518 | local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom, | 520 | local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom, |
| 519 | sizeof(struct ieee80211_tx_status_rtap_hdr)); | 521 | sizeof(struct ieee80211_tx_status_rtap_hdr)); |
| 520 | 522 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index d8d50fb5e823..c79e59f82fd9 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -915,6 +915,14 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
| 915 | sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | | 915 | sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | |
| 916 | IEEE80211_STA_BEACON_POLL); | 916 | IEEE80211_STA_BEACON_POLL); |
| 917 | 917 | ||
| 918 | /* | ||
| 919 | * Always handle WMM once after association regardless | ||
| 920 | * of the first value the AP uses. Setting -1 here has | ||
| 921 | * that effect because the AP values is an unsigned | ||
| 922 | * 4-bit value. | ||
| 923 | */ | ||
| 924 | sdata->u.mgd.wmm_last_param_set = -1; | ||
| 925 | |||
| 918 | ieee80211_led_assoc(local, 1); | 926 | ieee80211_led_assoc(local, 1); |
| 919 | 927 | ||
| 920 | sdata->vif.bss_conf.assoc = 1; | 928 | sdata->vif.bss_conf.assoc = 1; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 8834cc93c716..27ceaefd7bc8 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -1419,6 +1419,10 @@ static bool need_dynamic_ps(struct ieee80211_local *local) | |||
| 1419 | if (!local->ps_sdata) | 1419 | if (!local->ps_sdata) |
| 1420 | return false; | 1420 | return false; |
| 1421 | 1421 | ||
| 1422 | /* No point if we're going to suspend */ | ||
| 1423 | if (local->quiescing) | ||
| 1424 | return false; | ||
| 1425 | |||
| 1422 | return true; | 1426 | return true; |
| 1423 | } | 1427 | } |
| 1424 | 1428 | ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 78a6e924c7e1..dc76267e436e 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -1039,7 +1039,19 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
| 1039 | 1039 | ||
| 1040 | /* restart hardware */ | 1040 | /* restart hardware */ |
| 1041 | if (local->open_count) { | 1041 | if (local->open_count) { |
| 1042 | /* | ||
| 1043 | * Upon resume hardware can sometimes be goofy due to | ||
| 1044 | * various platform / driver / bus issues, so restarting | ||
| 1045 | * the device may at times not work immediately. Propagate | ||
| 1046 | * the error. | ||
| 1047 | */ | ||
| 1042 | res = drv_start(local); | 1048 | res = drv_start(local); |
| 1049 | if (res) { | ||
| 1050 | WARN(local->suspended, "Harware became unavailable " | ||
| 1051 | "upon resume. This is could be a software issue" | ||
| 1052 | "prior to suspend or a harware issue\n"); | ||
| 1053 | return res; | ||
| 1054 | } | ||
| 1043 | 1055 | ||
| 1044 | ieee80211_led_radio(local, true); | 1056 | ieee80211_led_radio(local, true); |
| 1045 | } | 1057 | } |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 1001db4912f7..82e6002c8d67 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
| @@ -93,7 +93,18 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len) | |||
| 93 | } | 93 | } |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | WARN_ON(!bss); | 96 | /* |
| 97 | * We might be coming here because the driver reported | ||
| 98 | * a successful association at the same time as the | ||
| 99 | * user requested a deauth. In that case, we will have | ||
| 100 | * removed the BSS from the auth_bsses list due to the | ||
| 101 | * deauth request when the assoc response makes it. If | ||
| 102 | * the two code paths acquire the lock the other way | ||
| 103 | * around, that's just the standard situation of a | ||
| 104 | * deauth being requested while connected. | ||
| 105 | */ | ||
| 106 | if (!bss) | ||
| 107 | goto out; | ||
| 97 | } else if (wdev->conn) { | 108 | } else if (wdev->conn) { |
| 98 | cfg80211_sme_failed_assoc(wdev); | 109 | cfg80211_sme_failed_assoc(wdev); |
| 99 | /* | 110 | /* |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 12dfa62aad18..0c2cbbebca95 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
| @@ -601,7 +601,7 @@ int cfg80211_wext_siwscan(struct net_device *dev, | |||
| 601 | struct cfg80211_registered_device *rdev; | 601 | struct cfg80211_registered_device *rdev; |
| 602 | struct wiphy *wiphy; | 602 | struct wiphy *wiphy; |
| 603 | struct iw_scan_req *wreq = NULL; | 603 | struct iw_scan_req *wreq = NULL; |
| 604 | struct cfg80211_scan_request *creq; | 604 | struct cfg80211_scan_request *creq = NULL; |
| 605 | int i, err, n_channels = 0; | 605 | int i, err, n_channels = 0; |
| 606 | enum ieee80211_band band; | 606 | enum ieee80211_band band; |
| 607 | 607 | ||
| @@ -694,8 +694,10 @@ int cfg80211_wext_siwscan(struct net_device *dev, | |||
| 694 | /* translate "Scan for SSID" request */ | 694 | /* translate "Scan for SSID" request */ |
| 695 | if (wreq) { | 695 | if (wreq) { |
| 696 | if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { | 696 | if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { |
| 697 | if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) | 697 | if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) { |
| 698 | return -EINVAL; | 698 | err = -EINVAL; |
| 699 | goto out; | ||
| 700 | } | ||
| 699 | memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len); | 701 | memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len); |
| 700 | creq->ssids[0].ssid_len = wreq->essid_len; | 702 | creq->ssids[0].ssid_len = wreq->essid_len; |
| 701 | } | 703 | } |
| @@ -707,12 +709,15 @@ int cfg80211_wext_siwscan(struct net_device *dev, | |||
| 707 | err = rdev->ops->scan(wiphy, dev, creq); | 709 | err = rdev->ops->scan(wiphy, dev, creq); |
| 708 | if (err) { | 710 | if (err) { |
| 709 | rdev->scan_req = NULL; | 711 | rdev->scan_req = NULL; |
| 710 | kfree(creq); | 712 | /* creq will be freed below */ |
| 711 | } else { | 713 | } else { |
| 712 | nl80211_send_scan_start(rdev, dev); | 714 | nl80211_send_scan_start(rdev, dev); |
| 715 | /* creq now owned by driver */ | ||
| 716 | creq = NULL; | ||
| 713 | dev_hold(dev); | 717 | dev_hold(dev); |
| 714 | } | 718 | } |
| 715 | out: | 719 | out: |
| 720 | kfree(creq); | ||
| 716 | cfg80211_unlock_rdev(rdev); | 721 | cfg80211_unlock_rdev(rdev); |
| 717 | return err; | 722 | return err; |
| 718 | } | 723 | } |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index cb81ca35b0d6..4725a549ad4d 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -1445,7 +1445,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, | |||
| 1445 | if (!dev) | 1445 | if (!dev) |
| 1446 | goto free_dst; | 1446 | goto free_dst; |
| 1447 | 1447 | ||
| 1448 | /* Copy neighbout for reachability confirmation */ | 1448 | /* Copy neighbour for reachability confirmation */ |
| 1449 | dst0->neighbour = neigh_clone(dst->neighbour); | 1449 | dst0->neighbour = neigh_clone(dst->neighbour); |
| 1450 | 1450 | ||
| 1451 | xfrm_init_path((struct xfrm_dst *)dst0, dst, nfheader_len); | 1451 | xfrm_init_path((struct xfrm_dst *)dst0, dst, nfheader_len); |
