diff options
author | David S. Miller <davem@davemloft.net> | 2011-05-25 13:28:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-05-25 13:28:55 -0400 |
commit | 22e95ac87d62bdc65b8a694a23cd4a364689b013 (patch) | |
tree | 5ac900300ad1d4a8d8118545e3e971862de70ea4 | |
parent | 6b3678354647a653e669746c05765f05d2b90239 (diff) | |
parent | 31ec97d9cebac804814de298592648f7c18d8281 (diff) |
Merge branch 'for-davem' of ssh://master.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
142 files changed, 1820 insertions, 976 deletions
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index 99dd36e8500b..ffd8797faf4f 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c | |||
@@ -171,6 +171,7 @@ static void bcma_host_pci_remove(struct pci_dev *dev) | |||
171 | } | 171 | } |
172 | 172 | ||
173 | static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { | 173 | static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { |
174 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, | ||
174 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, | 175 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, |
175 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, | 176 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, |
176 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, | 177 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, |
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index a70c512f05d2..55cf71fbffe3 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -4501,17 +4501,15 @@ static int setup_proc_entry( struct net_device *dev, | |||
4501 | struct proc_dir_entry *entry; | 4501 | struct proc_dir_entry *entry; |
4502 | /* First setup the device directory */ | 4502 | /* First setup the device directory */ |
4503 | strcpy(apriv->proc_name,dev->name); | 4503 | strcpy(apriv->proc_name,dev->name); |
4504 | apriv->proc_entry = create_proc_entry(apriv->proc_name, | 4504 | apriv->proc_entry = proc_mkdir_mode(apriv->proc_name, airo_perm, |
4505 | S_IFDIR|airo_perm, | 4505 | airo_entry); |
4506 | airo_entry); | ||
4507 | if (!apriv->proc_entry) | 4506 | if (!apriv->proc_entry) |
4508 | goto fail; | 4507 | goto fail; |
4509 | apriv->proc_entry->uid = proc_uid; | 4508 | apriv->proc_entry->uid = proc_uid; |
4510 | apriv->proc_entry->gid = proc_gid; | 4509 | apriv->proc_entry->gid = proc_gid; |
4511 | 4510 | ||
4512 | /* Setup the StatsDelta */ | 4511 | /* Setup the StatsDelta */ |
4513 | entry = proc_create_data("StatsDelta", | 4512 | entry = proc_create_data("StatsDelta", S_IRUGO & proc_perm, |
4514 | S_IFREG | (S_IRUGO&proc_perm), | ||
4515 | apriv->proc_entry, &proc_statsdelta_ops, dev); | 4513 | apriv->proc_entry, &proc_statsdelta_ops, dev); |
4516 | if (!entry) | 4514 | if (!entry) |
4517 | goto fail_stats_delta; | 4515 | goto fail_stats_delta; |
@@ -4519,8 +4517,7 @@ static int setup_proc_entry( struct net_device *dev, | |||
4519 | entry->gid = proc_gid; | 4517 | entry->gid = proc_gid; |
4520 | 4518 | ||
4521 | /* Setup the Stats */ | 4519 | /* Setup the Stats */ |
4522 | entry = proc_create_data("Stats", | 4520 | entry = proc_create_data("Stats", S_IRUGO & proc_perm, |
4523 | S_IFREG | (S_IRUGO&proc_perm), | ||
4524 | apriv->proc_entry, &proc_stats_ops, dev); | 4521 | apriv->proc_entry, &proc_stats_ops, dev); |
4525 | if (!entry) | 4522 | if (!entry) |
4526 | goto fail_stats; | 4523 | goto fail_stats; |
@@ -4528,8 +4525,7 @@ static int setup_proc_entry( struct net_device *dev, | |||
4528 | entry->gid = proc_gid; | 4525 | entry->gid = proc_gid; |
4529 | 4526 | ||
4530 | /* Setup the Status */ | 4527 | /* Setup the Status */ |
4531 | entry = proc_create_data("Status", | 4528 | entry = proc_create_data("Status", S_IRUGO & proc_perm, |
4532 | S_IFREG | (S_IRUGO&proc_perm), | ||
4533 | apriv->proc_entry, &proc_status_ops, dev); | 4529 | apriv->proc_entry, &proc_status_ops, dev); |
4534 | if (!entry) | 4530 | if (!entry) |
4535 | goto fail_status; | 4531 | goto fail_status; |
@@ -4537,8 +4533,7 @@ static int setup_proc_entry( struct net_device *dev, | |||
4537 | entry->gid = proc_gid; | 4533 | entry->gid = proc_gid; |
4538 | 4534 | ||
4539 | /* Setup the Config */ | 4535 | /* Setup the Config */ |
4540 | entry = proc_create_data("Config", | 4536 | entry = proc_create_data("Config", proc_perm, |
4541 | S_IFREG | proc_perm, | ||
4542 | apriv->proc_entry, &proc_config_ops, dev); | 4537 | apriv->proc_entry, &proc_config_ops, dev); |
4543 | if (!entry) | 4538 | if (!entry) |
4544 | goto fail_config; | 4539 | goto fail_config; |
@@ -4546,8 +4541,7 @@ static int setup_proc_entry( struct net_device *dev, | |||
4546 | entry->gid = proc_gid; | 4541 | entry->gid = proc_gid; |
4547 | 4542 | ||
4548 | /* Setup the SSID */ | 4543 | /* Setup the SSID */ |
4549 | entry = proc_create_data("SSID", | 4544 | entry = proc_create_data("SSID", proc_perm, |
4550 | S_IFREG | proc_perm, | ||
4551 | apriv->proc_entry, &proc_SSID_ops, dev); | 4545 | apriv->proc_entry, &proc_SSID_ops, dev); |
4552 | if (!entry) | 4546 | if (!entry) |
4553 | goto fail_ssid; | 4547 | goto fail_ssid; |
@@ -4555,8 +4549,7 @@ static int setup_proc_entry( struct net_device *dev, | |||
4555 | entry->gid = proc_gid; | 4549 | entry->gid = proc_gid; |
4556 | 4550 | ||
4557 | /* Setup the APList */ | 4551 | /* Setup the APList */ |
4558 | entry = proc_create_data("APList", | 4552 | entry = proc_create_data("APList", proc_perm, |
4559 | S_IFREG | proc_perm, | ||
4560 | apriv->proc_entry, &proc_APList_ops, dev); | 4553 | apriv->proc_entry, &proc_APList_ops, dev); |
4561 | if (!entry) | 4554 | if (!entry) |
4562 | goto fail_aplist; | 4555 | goto fail_aplist; |
@@ -4564,8 +4557,7 @@ static int setup_proc_entry( struct net_device *dev, | |||
4564 | entry->gid = proc_gid; | 4557 | entry->gid = proc_gid; |
4565 | 4558 | ||
4566 | /* Setup the BSSList */ | 4559 | /* Setup the BSSList */ |
4567 | entry = proc_create_data("BSSList", | 4560 | entry = proc_create_data("BSSList", proc_perm, |
4568 | S_IFREG | proc_perm, | ||
4569 | apriv->proc_entry, &proc_BSSList_ops, dev); | 4561 | apriv->proc_entry, &proc_BSSList_ops, dev); |
4570 | if (!entry) | 4562 | if (!entry) |
4571 | goto fail_bsslist; | 4563 | goto fail_bsslist; |
@@ -4573,8 +4565,7 @@ static int setup_proc_entry( struct net_device *dev, | |||
4573 | entry->gid = proc_gid; | 4565 | entry->gid = proc_gid; |
4574 | 4566 | ||
4575 | /* Setup the WepKey */ | 4567 | /* Setup the WepKey */ |
4576 | entry = proc_create_data("WepKey", | 4568 | entry = proc_create_data("WepKey", proc_perm, |
4577 | S_IFREG | proc_perm, | ||
4578 | apriv->proc_entry, &proc_wepkey_ops, dev); | 4569 | apriv->proc_entry, &proc_wepkey_ops, dev); |
4579 | if (!entry) | 4570 | if (!entry) |
4580 | goto fail_wepkey; | 4571 | goto fail_wepkey; |
@@ -5706,9 +5697,7 @@ static int __init airo_init_module( void ) | |||
5706 | { | 5697 | { |
5707 | int i; | 5698 | int i; |
5708 | 5699 | ||
5709 | airo_entry = create_proc_entry("driver/aironet", | 5700 | airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL); |
5710 | S_IFDIR | airo_perm, | ||
5711 | NULL); | ||
5712 | 5701 | ||
5713 | if (airo_entry) { | 5702 | if (airo_entry) { |
5714 | airo_entry->uid = proc_uid; | 5703 | airo_entry->uid = proc_uid; |
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 61956392f2da..5b49cd03bfdf 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org> | 3 | * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org> |
4 | * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org> | 4 | * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org> |
5 | * | 5 | * |
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 5a1f4f511bc1..bfb6481f01f9 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2010 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h index 0cd6783de883..dbab5b9ce494 100644 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ b/drivers/net/wireless/ath/ath9k/ani.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h index 36f7d0639db3..234617c948a1 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 4bf9dab4f2b3..441bb33f17ad 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2010 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h index 69a94c7e45cb..6d2e2f3303f9 100644 --- a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index cb611b287b35..015d97439935 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2010 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index f44c84ab5dce..f344cc2b3d59 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2010 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h index 6203eed860dd..7573257731b6 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 7a332f16b79a..077e8a6983fa 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index a57e963cf0dc..2fe0a34cbabc 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2010 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h index 47780ef1c892..453af6dc514b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2010 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index f915a3dbfcad..e8ac70da5ac7 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index f276cb922b4d..f48051c50092 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index d985841ff401..0ca7635d0669 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index afb0b5ee1865..ab21a4915981 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | |||
@@ -1,3 +1,19 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010-2011 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
1 | #ifndef AR9003_EEPROM_H | 17 | #ifndef AR9003_EEPROM_H |
2 | #define AR9003_EEPROM_H | 18 | #define AR9003_EEPROM_H |
3 | 19 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index a55eddbb2589..392bf0f8ff16 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2010 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index be6adec33ddb..10d71f7d3fc2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h index 45cc7e80436c..c50449387bf1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 356d2fd78822..e4d6a87ec538 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 25f3c2fdf2bc..eee23ecd118a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index c7505b48e5c0..443090d278e3 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2002-2010 Atheros Communications, Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications, Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index fbdde29f0ab8..611ea6ce8508 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 03b37d7be1c3..f75068b4b310 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -397,6 +397,9 @@ struct ath_beacon { | |||
397 | struct ath_descdma bdma; | 397 | struct ath_descdma bdma; |
398 | struct ath_txq *cabq; | 398 | struct ath_txq *cabq; |
399 | struct list_head bbuf; | 399 | struct list_head bbuf; |
400 | |||
401 | bool tx_processed; | ||
402 | bool tx_last; | ||
400 | }; | 403 | }; |
401 | 404 | ||
402 | void ath_beacon_tasklet(unsigned long data); | 405 | void ath_beacon_tasklet(unsigned long data); |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 637dbc5f7b67..d4d8ceced89b 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -18,6 +18,12 @@ | |||
18 | 18 | ||
19 | #define FUDGE 2 | 19 | #define FUDGE 2 |
20 | 20 | ||
21 | static void ath9k_reset_beacon_status(struct ath_softc *sc) | ||
22 | { | ||
23 | sc->beacon.tx_processed = false; | ||
24 | sc->beacon.tx_last = false; | ||
25 | } | ||
26 | |||
21 | /* | 27 | /* |
22 | * This function will modify certain transmit queue properties depending on | 28 | * This function will modify certain transmit queue properties depending on |
23 | * the operating mode of the station (AP or AdHoc). Parameters are AIFS | 29 | * the operating mode of the station (AP or AdHoc). Parameters are AIFS |
@@ -72,6 +78,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, | |||
72 | struct ieee80211_supported_band *sband; | 78 | struct ieee80211_supported_band *sband; |
73 | u8 rate = 0; | 79 | u8 rate = 0; |
74 | 80 | ||
81 | ath9k_reset_beacon_status(sc); | ||
82 | |||
75 | ds = bf->bf_desc; | 83 | ds = bf->bf_desc; |
76 | flags = ATH9K_TXDESC_NOACK; | 84 | flags = ATH9K_TXDESC_NOACK; |
77 | 85 | ||
@@ -134,6 +142,8 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, | |||
134 | struct ieee80211_tx_info *info; | 142 | struct ieee80211_tx_info *info; |
135 | int cabq_depth; | 143 | int cabq_depth; |
136 | 144 | ||
145 | ath9k_reset_beacon_status(sc); | ||
146 | |||
137 | avp = (void *)vif->drv_priv; | 147 | avp = (void *)vif->drv_priv; |
138 | cabq = sc->beacon.cabq; | 148 | cabq = sc->beacon.cabq; |
139 | 149 | ||
@@ -351,9 +361,7 @@ void ath_beacon_tasklet(unsigned long data) | |||
351 | struct ath_buf *bf = NULL; | 361 | struct ath_buf *bf = NULL; |
352 | struct ieee80211_vif *vif; | 362 | struct ieee80211_vif *vif; |
353 | int slot; | 363 | int slot; |
354 | u32 bfaddr, bc = 0, tsftu; | 364 | u32 bfaddr, bc = 0; |
355 | u64 tsf; | ||
356 | u16 intval; | ||
357 | 365 | ||
358 | /* | 366 | /* |
359 | * Check if the previous beacon has gone out. If | 367 | * Check if the previous beacon has gone out. If |
@@ -388,17 +396,27 @@ void ath_beacon_tasklet(unsigned long data) | |||
388 | * on the tsf to safeguard against missing an swba. | 396 | * on the tsf to safeguard against missing an swba. |
389 | */ | 397 | */ |
390 | 398 | ||
391 | intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; | ||
392 | 399 | ||
393 | tsf = ath9k_hw_gettsf64(ah); | 400 | if (ah->opmode == NL80211_IFTYPE_AP) { |
394 | tsf += TU_TO_USEC(ah->config.sw_beacon_response_time); | 401 | u16 intval; |
395 | tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF); | 402 | u32 tsftu; |
396 | slot = (tsftu % (intval * ATH_BCBUF)) / intval; | 403 | u64 tsf; |
397 | vif = sc->beacon.bslot[slot]; | 404 | |
405 | intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; | ||
406 | tsf = ath9k_hw_gettsf64(ah); | ||
407 | tsf += TU_TO_USEC(ah->config.sw_beacon_response_time); | ||
408 | tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF); | ||
409 | slot = (tsftu % (intval * ATH_BCBUF)) / intval; | ||
410 | vif = sc->beacon.bslot[slot]; | ||
411 | |||
412 | ath_dbg(common, ATH_DBG_BEACON, | ||
413 | "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", | ||
414 | slot, tsf, tsftu / ATH_BCBUF, intval, vif); | ||
415 | } else { | ||
416 | slot = 0; | ||
417 | vif = sc->beacon.bslot[slot]; | ||
418 | } | ||
398 | 419 | ||
399 | ath_dbg(common, ATH_DBG_BEACON, | ||
400 | "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", | ||
401 | slot, tsf, tsftu / ATH_BCBUF, intval, vif); | ||
402 | 420 | ||
403 | bfaddr = 0; | 421 | bfaddr = 0; |
404 | if (vif) { | 422 | if (vif) { |
@@ -636,6 +654,8 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, | |||
636 | struct ath_common *common = ath9k_hw_common(ah); | 654 | struct ath_common *common = ath9k_hw_common(ah); |
637 | u32 tsf, delta, intval, nexttbtt; | 655 | u32 tsf, delta, intval, nexttbtt; |
638 | 656 | ||
657 | ath9k_reset_beacon_status(sc); | ||
658 | |||
639 | tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE); | 659 | tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE); |
640 | intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD); | 660 | intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD); |
641 | 661 | ||
@@ -646,7 +666,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, | |||
646 | delta = (tsf - sc->beacon.bc_tstamp); | 666 | delta = (tsf - sc->beacon.bc_tstamp); |
647 | else | 667 | else |
648 | delta = (tsf + 1 + (~0U - sc->beacon.bc_tstamp)); | 668 | delta = (tsf + 1 + (~0U - sc->beacon.bc_tstamp)); |
649 | nexttbtt = tsf + roundup(delta, intval); | 669 | nexttbtt = tsf + intval - (delta % intval); |
650 | } | 670 | } |
651 | 671 | ||
652 | ath_dbg(common, ATH_DBG_BEACON, | 672 | ath_dbg(common, ATH_DBG_BEACON, |
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c index 23f15a7ca7f1..41ce0b139886 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/drivers/net/wireless/ath/ath9k/btcoex.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2009 Atheros Communications Inc. | 2 | * Copyright (c) 2009-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h index a9efca83d676..234f77689b14 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.h +++ b/drivers/net/wireless/ath/ath9k/btcoex.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2009 Atheros Communications Inc. | 2 | * Copyright (c) 2009-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 558b228a717f..a1250c586e40 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h index 4420780fa3b8..1bef41d1b1ff 100644 --- a/drivers/net/wireless/ath/ath9k/calib.h +++ b/drivers/net/wireless/ath/ath9k/calib.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 74535e6dfb82..fa6bd2d189e5 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2009 Atheros Communications Inc. | 2 | * Copyright (c) 2009-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index 5124f1420b3a..77ec288b5a70 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2009 Atheros Communications Inc. | 2 | * Copyright (c) 2009-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index bad1a87249b6..d55ffd7d4bd2 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -435,6 +435,7 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, | |||
435 | conf->channel_type, | 435 | conf->channel_type, |
436 | channel_type_str(conf->channel_type)); | 436 | channel_type_str(conf->channel_type)); |
437 | 437 | ||
438 | ath9k_ps_wakeup(sc); | ||
438 | put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr); | 439 | put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr); |
439 | put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4); | 440 | put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4); |
440 | len += snprintf(buf + len, sizeof(buf) - len, | 441 | len += snprintf(buf + len, sizeof(buf) - len, |
@@ -444,6 +445,7 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, | |||
444 | len += snprintf(buf + len, sizeof(buf) - len, | 445 | len += snprintf(buf + len, sizeof(buf) - len, |
445 | "addrmask: %pM\n", addr); | 446 | "addrmask: %pM\n", addr); |
446 | tmp = ath9k_hw_getrxfilter(sc->sc_ah); | 447 | tmp = ath9k_hw_getrxfilter(sc->sc_ah); |
448 | ath9k_ps_restore(sc); | ||
447 | len += snprintf(buf + len, sizeof(buf) - len, | 449 | len += snprintf(buf + len, sizeof(buf) - len, |
448 | "rfilt: 0x%x", tmp); | 450 | "rfilt: 0x%x", tmp); |
449 | if (tmp & ATH9K_RX_FILTER_UCAST) | 451 | if (tmp & ATH9K_RX_FILTER_UCAST) |
@@ -725,6 +727,7 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, | |||
725 | break; | 727 | break; |
726 | } | 728 | } |
727 | 729 | ||
730 | ath9k_ps_wakeup(sc); | ||
728 | len += snprintf(buf + len, size - len, | 731 | len += snprintf(buf + len, size - len, |
729 | "curbssid: %pM\n" | 732 | "curbssid: %pM\n" |
730 | "OP-Mode: %s(%i)\n" | 733 | "OP-Mode: %s(%i)\n" |
@@ -734,6 +737,7 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, | |||
734 | REG_READ(ah, AR_BEACON_PERIOD)); | 737 | REG_READ(ah, AR_BEACON_PERIOD)); |
735 | 738 | ||
736 | reg = REG_READ(ah, AR_TIMER_MODE); | 739 | reg = REG_READ(ah, AR_TIMER_MODE); |
740 | ath9k_ps_restore(sc); | ||
737 | len += snprintf(buf + len, size - len, "Timer-Mode-Register: 0x%x (", | 741 | len += snprintf(buf + len, size - len, "Timer-Mode-Register: 0x%x (", |
738 | reg); | 742 | reg); |
739 | if (reg & AR_TBTT_TIMER_EN) | 743 | if (reg & AR_TBTT_TIMER_EN) |
@@ -1050,7 +1054,9 @@ static ssize_t read_file_regval(struct file *file, char __user *user_buf, | |||
1050 | unsigned int len; | 1054 | unsigned int len; |
1051 | u32 regval; | 1055 | u32 regval; |
1052 | 1056 | ||
1057 | ath9k_ps_wakeup(sc); | ||
1053 | regval = REG_READ_D(ah, sc->debug.regidx); | 1058 | regval = REG_READ_D(ah, sc->debug.regidx); |
1059 | ath9k_ps_restore(sc); | ||
1054 | len = sprintf(buf, "0x%08x\n", regval); | 1060 | len = sprintf(buf, "0x%08x\n", regval); |
1055 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | 1061 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); |
1056 | } | 1062 | } |
@@ -1072,7 +1078,9 @@ static ssize_t write_file_regval(struct file *file, const char __user *user_buf, | |||
1072 | if (strict_strtoul(buf, 0, ®val)) | 1078 | if (strict_strtoul(buf, 0, ®val)) |
1073 | return -EINVAL; | 1079 | return -EINVAL; |
1074 | 1080 | ||
1081 | ath9k_ps_wakeup(sc); | ||
1075 | REG_WRITE_D(ah, sc->debug.regidx, regval); | 1082 | REG_WRITE_D(ah, sc->debug.regidx, regval); |
1083 | ath9k_ps_restore(sc); | ||
1076 | return count; | 1084 | return count; |
1077 | } | 1085 | } |
1078 | 1086 | ||
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 5488a324cc10..8ce6ad80f4e2 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index 8c18bed3a558..e61404dda8c5 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 3e316133f114..de99c0da52e4 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 6f714dd72365..5b1e894f3d67 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index b87db4763098..7856f0d4512d 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index c031854b569f..17f0a6806207 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 0349b3a1cc58..bc713fc28191 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 2e3a33a53406..260f1f37a60e 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 2bdcdbc14b1e..794f63094e5d 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -18,7 +18,7 @@ | |||
18 | #define HTC_USB_H | 18 | #define HTC_USB_H |
19 | 19 | ||
20 | #define MAJOR_VERSION_REQ 1 | 20 | #define MAJOR_VERSION_REQ 1 |
21 | #define MINOR_VERSION_REQ 2 | 21 | #define MINOR_VERSION_REQ 3 |
22 | 22 | ||
23 | #define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB)) | 23 | #define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB)) |
24 | 24 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index dfc7a982fc7e..5bc022087e65 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -46,15 +46,8 @@ extern struct ieee80211_ops ath9k_htc_ops; | |||
46 | extern int htc_modparam_nohwcrypt; | 46 | extern int htc_modparam_nohwcrypt; |
47 | 47 | ||
48 | enum htc_phymode { | 48 | enum htc_phymode { |
49 | HTC_MODE_AUTO = 0, | 49 | HTC_MODE_11NA = 0, |
50 | HTC_MODE_11A = 1, | 50 | HTC_MODE_11NG = 1 |
51 | HTC_MODE_11B = 2, | ||
52 | HTC_MODE_11G = 3, | ||
53 | HTC_MODE_FH = 4, | ||
54 | HTC_MODE_TURBO_A = 5, | ||
55 | HTC_MODE_TURBO_G = 6, | ||
56 | HTC_MODE_11NA = 7, | ||
57 | HTC_MODE_11NG = 8 | ||
58 | }; | 51 | }; |
59 | 52 | ||
60 | enum htc_opmode { | 53 | enum htc_opmode { |
@@ -123,18 +116,13 @@ struct ath9k_htc_target_vif { | |||
123 | u8 pad; | 116 | u8 pad; |
124 | } __packed; | 117 | } __packed; |
125 | 118 | ||
126 | #define ATH_HTC_STA_AUTH 0x0001 | ||
127 | #define ATH_HTC_STA_QOS 0x0002 | ||
128 | #define ATH_HTC_STA_ERP 0x0004 | ||
129 | #define ATH_HTC_STA_HT 0x0008 | ||
130 | |||
131 | struct ath9k_htc_target_sta { | 119 | struct ath9k_htc_target_sta { |
132 | u8 macaddr[ETH_ALEN]; | 120 | u8 macaddr[ETH_ALEN]; |
133 | u8 bssid[ETH_ALEN]; | 121 | u8 bssid[ETH_ALEN]; |
134 | u8 sta_index; | 122 | u8 sta_index; |
135 | u8 vif_index; | 123 | u8 vif_index; |
136 | u8 is_vif_sta; | 124 | u8 is_vif_sta; |
137 | __be16 flags; /* ATH_HTC_STA_* */ | 125 | __be16 flags; |
138 | __be16 htcap; | 126 | __be16 htcap; |
139 | __be16 maxampdu; | 127 | __be16 maxampdu; |
140 | u8 pad; | 128 | u8 pad; |
@@ -285,9 +273,9 @@ struct ath9k_htc_rx { | |||
285 | }; | 273 | }; |
286 | 274 | ||
287 | #define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */ | 275 | #define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */ |
288 | #define ATH9K_HTC_TX_TIMEOUT_INTERVAL 2500 /* ms */ | 276 | #define ATH9K_HTC_TX_TIMEOUT_INTERVAL 3000 /* ms */ |
289 | #define ATH9K_HTC_TX_RESERVE 10 | 277 | #define ATH9K_HTC_TX_RESERVE 10 |
290 | #define ATH9K_HTC_TX_TIMEOUT_COUNT 20 | 278 | #define ATH9K_HTC_TX_TIMEOUT_COUNT 40 |
291 | #define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE) | 279 | #define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE) |
292 | 280 | ||
293 | #define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0) | 281 | #define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0) |
@@ -450,6 +438,7 @@ struct ath9k_htc_priv { | |||
450 | u8 vif_sta_pos[ATH9K_HTC_MAX_VIF]; | 438 | u8 vif_sta_pos[ATH9K_HTC_MAX_VIF]; |
451 | u8 num_ibss_vif; | 439 | u8 num_ibss_vif; |
452 | u8 num_sta_vif; | 440 | u8 num_sta_vif; |
441 | u8 num_sta_assoc_vif; | ||
453 | u8 num_ap_vif; | 442 | u8 num_ap_vif; |
454 | 443 | ||
455 | u16 op_flags; | 444 | u16 op_flags; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 0ded2c66d5ff..aa6a73118706 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index af57fe5aab98..db2352e5cc0d 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index bfdc8a887183..61e6d3950718 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -258,7 +258,7 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid, | |||
258 | */ | 258 | */ |
259 | 259 | ||
260 | if (IS_AR7010_DEVICE(drv_info)) | 260 | if (IS_AR7010_DEVICE(drv_info)) |
261 | priv->htc->credits = 48; | 261 | priv->htc->credits = 45; |
262 | else | 262 | else |
263 | priv->htc->credits = 33; | 263 | priv->htc->credits = 33; |
264 | 264 | ||
@@ -769,11 +769,6 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
769 | hw->channel_change_time = 5000; | 769 | hw->channel_change_time = 5000; |
770 | hw->max_listen_interval = 10; | 770 | hw->max_listen_interval = 10; |
771 | 771 | ||
772 | if (AR_SREV_9271(priv->ah)) | ||
773 | hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_9271; | ||
774 | else | ||
775 | hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_7010; | ||
776 | |||
777 | hw->vif_data_size = sizeof(struct ath9k_htc_vif); | 772 | hw->vif_data_size = sizeof(struct ath9k_htc_vif); |
778 | hw->sta_data_size = sizeof(struct ath9k_htc_sta); | 773 | hw->sta_data_size = sizeof(struct ath9k_htc_sta); |
779 | 774 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 5aa104fe7eeb..7b7796895432 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -26,7 +26,7 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv, | |||
26 | { | 26 | { |
27 | enum htc_phymode mode; | 27 | enum htc_phymode mode; |
28 | 28 | ||
29 | mode = HTC_MODE_AUTO; | 29 | mode = -EINVAL; |
30 | 30 | ||
31 | switch (ichan->chanmode) { | 31 | switch (ichan->chanmode) { |
32 | case CHANNEL_G: | 32 | case CHANNEL_G: |
@@ -45,6 +45,8 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv, | |||
45 | break; | 45 | break; |
46 | } | 46 | } |
47 | 47 | ||
48 | WARN_ON(mode < 0); | ||
49 | |||
48 | return mode; | 50 | return mode; |
49 | } | 51 | } |
50 | 52 | ||
@@ -500,9 +502,6 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, | |||
500 | tsta.maxampdu = cpu_to_be16(maxampdu); | 502 | tsta.maxampdu = cpu_to_be16(maxampdu); |
501 | } | 503 | } |
502 | 504 | ||
503 | if (sta && sta->ht_cap.ht_supported) | ||
504 | tsta.flags = cpu_to_be16(ATH_HTC_STA_HT); | ||
505 | |||
506 | WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); | 505 | WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); |
507 | if (ret) { | 506 | if (ret) { |
508 | if (sta) | 507 | if (sta) |
@@ -582,7 +581,7 @@ int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv, | |||
582 | memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target)); | 581 | memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target)); |
583 | 582 | ||
584 | tcap.ampdu_limit = cpu_to_be32(0xffff); | 583 | tcap.ampdu_limit = cpu_to_be32(0xffff); |
585 | tcap.ampdu_subframes = priv->hw->max_tx_aggregation_subframes; | 584 | tcap.ampdu_subframes = 0xff; |
586 | tcap.enable_coex = enable_coex; | 585 | tcap.enable_coex = enable_coex; |
587 | tcap.tx_chainmask = priv->ah->caps.tx_chainmask; | 586 | tcap.tx_chainmask = priv->ah->caps.tx_chainmask; |
588 | 587 | ||
@@ -1165,6 +1164,8 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, | |||
1165 | 1164 | ||
1166 | ath9k_htc_set_opmode(priv); | 1165 | ath9k_htc_set_opmode(priv); |
1167 | 1166 | ||
1167 | ath9k_htc_set_bssid_mask(priv, vif); | ||
1168 | |||
1168 | /* | 1169 | /* |
1169 | * Stop ANI only if there are no associated station interfaces. | 1170 | * Stop ANI only if there are no associated station interfaces. |
1170 | */ | 1171 | */ |
@@ -1435,6 +1436,37 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, | |||
1435 | return ret; | 1436 | return ret; |
1436 | } | 1437 | } |
1437 | 1438 | ||
1439 | static void ath9k_htc_set_bssid(struct ath9k_htc_priv *priv) | ||
1440 | { | ||
1441 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
1442 | |||
1443 | ath9k_hw_write_associd(priv->ah); | ||
1444 | ath_dbg(common, ATH_DBG_CONFIG, | ||
1445 | "BSSID: %pM aid: 0x%x\n", | ||
1446 | common->curbssid, common->curaid); | ||
1447 | } | ||
1448 | |||
1449 | static void ath9k_htc_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | ||
1450 | { | ||
1451 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; | ||
1452 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
1453 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | ||
1454 | |||
1455 | if ((vif->type == NL80211_IFTYPE_STATION) && bss_conf->assoc) { | ||
1456 | common->curaid = bss_conf->aid; | ||
1457 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | ||
1458 | } | ||
1459 | } | ||
1460 | |||
1461 | static void ath9k_htc_choose_set_bssid(struct ath9k_htc_priv *priv) | ||
1462 | { | ||
1463 | if (priv->num_sta_assoc_vif == 1) { | ||
1464 | ieee80211_iterate_active_interfaces_atomic(priv->hw, | ||
1465 | ath9k_htc_bss_iter, priv); | ||
1466 | ath9k_htc_set_bssid(priv); | ||
1467 | } | ||
1468 | } | ||
1469 | |||
1438 | static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | 1470 | static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, |
1439 | struct ieee80211_vif *vif, | 1471 | struct ieee80211_vif *vif, |
1440 | struct ieee80211_bss_conf *bss_conf, | 1472 | struct ieee80211_bss_conf *bss_conf, |
@@ -1443,43 +1475,32 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
1443 | struct ath9k_htc_priv *priv = hw->priv; | 1475 | struct ath9k_htc_priv *priv = hw->priv; |
1444 | struct ath_hw *ah = priv->ah; | 1476 | struct ath_hw *ah = priv->ah; |
1445 | struct ath_common *common = ath9k_hw_common(ah); | 1477 | struct ath_common *common = ath9k_hw_common(ah); |
1446 | bool set_assoc; | ||
1447 | 1478 | ||
1448 | mutex_lock(&priv->mutex); | 1479 | mutex_lock(&priv->mutex); |
1449 | ath9k_htc_ps_wakeup(priv); | 1480 | ath9k_htc_ps_wakeup(priv); |
1450 | 1481 | ||
1451 | /* | ||
1452 | * Set the HW AID/BSSID only for the first station interface | ||
1453 | * or in IBSS mode. | ||
1454 | */ | ||
1455 | set_assoc = !!((priv->ah->opmode == NL80211_IFTYPE_ADHOC) || | ||
1456 | ((priv->ah->opmode == NL80211_IFTYPE_STATION) && | ||
1457 | (priv->num_sta_vif == 1))); | ||
1458 | |||
1459 | |||
1460 | if (changed & BSS_CHANGED_ASSOC) { | 1482 | if (changed & BSS_CHANGED_ASSOC) { |
1461 | if (set_assoc) { | 1483 | ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", |
1462 | ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", | 1484 | bss_conf->assoc); |
1463 | bss_conf->assoc); | ||
1464 | 1485 | ||
1465 | common->curaid = bss_conf->assoc ? | 1486 | bss_conf->assoc ? |
1466 | bss_conf->aid : 0; | 1487 | priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--; |
1467 | 1488 | ||
1468 | if (bss_conf->assoc) | 1489 | if (priv->ah->opmode == NL80211_IFTYPE_STATION) { |
1490 | if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1)) | ||
1469 | ath9k_htc_start_ani(priv); | 1491 | ath9k_htc_start_ani(priv); |
1470 | else | 1492 | else if (priv->num_sta_assoc_vif == 0) |
1471 | ath9k_htc_stop_ani(priv); | 1493 | ath9k_htc_stop_ani(priv); |
1472 | } | 1494 | } |
1473 | } | 1495 | } |
1474 | 1496 | ||
1475 | if (changed & BSS_CHANGED_BSSID) { | 1497 | if (changed & BSS_CHANGED_BSSID) { |
1476 | if (set_assoc) { | 1498 | if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { |
1499 | common->curaid = bss_conf->aid; | ||
1477 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | 1500 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
1478 | ath9k_hw_write_associd(ah); | 1501 | ath9k_htc_set_bssid(priv); |
1479 | 1502 | } else if (priv->ah->opmode == NL80211_IFTYPE_STATION) { | |
1480 | ath_dbg(common, ATH_DBG_CONFIG, | 1503 | ath9k_htc_choose_set_bssid(priv); |
1481 | "BSSID: %pM aid: 0x%x\n", | ||
1482 | common->curbssid, common->curaid); | ||
1483 | } | 1504 | } |
1484 | } | 1505 | } |
1485 | 1506 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index a898dac22337..2d81c700e201 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -875,6 +875,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv) | |||
875 | rfilt |= ATH9K_RX_FILTER_CONTROL; | 875 | rfilt |= ATH9K_RX_FILTER_CONTROL; |
876 | 876 | ||
877 | if ((ah->opmode == NL80211_IFTYPE_STATION) && | 877 | if ((ah->opmode == NL80211_IFTYPE_STATION) && |
878 | (priv->nvifs <= 1) && | ||
878 | !(priv->rxfilter & FIF_BCN_PRBRESP_PROMISC)) | 879 | !(priv->rxfilter & FIF_BCN_PRBRESP_PROMISC)) |
879 | rfilt |= ATH9K_RX_FILTER_MYBEACON; | 880 | rfilt |= ATH9K_RX_FILTER_MYBEACON; |
880 | else | 881 | else |
@@ -888,6 +889,9 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv) | |||
888 | if (priv->rxfilter & FIF_PSPOLL) | 889 | if (priv->rxfilter & FIF_PSPOLL) |
889 | rfilt |= ATH9K_RX_FILTER_PSPOLL; | 890 | rfilt |= ATH9K_RX_FILTER_PSPOLL; |
890 | 891 | ||
892 | if (priv->nvifs > 1) | ||
893 | rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL; | ||
894 | |||
891 | return rfilt; | 895 | return rfilt; |
892 | 896 | ||
893 | #undef RX_FILTER_PRESERVE | 897 | #undef RX_FILTER_PRESERVE |
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index cee970fdf652..1b90ed8795c3 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index 91a5305db95a..e1ffbb6bd636 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index 8b8f0445aef8..2f3e07263fcb 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index b75b5dca4e29..72543ce8f616 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2010 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 7af2773d2bfc..57435ce62792 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2010 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index b172d1509515..45c585a337e9 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index bd6d2b9d736f..c2091f1f4096 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index b60c130917f7..8e848c4d16ba 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 17ebdf1e8b7b..a198ee374b05 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -2332,6 +2332,45 @@ static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) | |||
2332 | return false; | 2332 | return false; |
2333 | } | 2333 | } |
2334 | 2334 | ||
2335 | int ath9k_tx_last_beacon(struct ieee80211_hw *hw) | ||
2336 | { | ||
2337 | struct ath_softc *sc = hw->priv; | ||
2338 | struct ath_hw *ah = sc->sc_ah; | ||
2339 | struct ieee80211_vif *vif; | ||
2340 | struct ath_vif *avp; | ||
2341 | struct ath_buf *bf; | ||
2342 | struct ath_tx_status ts; | ||
2343 | int status; | ||
2344 | |||
2345 | vif = sc->beacon.bslot[0]; | ||
2346 | if (!vif) | ||
2347 | return 0; | ||
2348 | |||
2349 | avp = (void *)vif->drv_priv; | ||
2350 | if (!avp->is_bslot_active) | ||
2351 | return 0; | ||
2352 | |||
2353 | if (!sc->beacon.tx_processed) { | ||
2354 | tasklet_disable(&sc->bcon_tasklet); | ||
2355 | |||
2356 | bf = avp->av_bcbuf; | ||
2357 | if (!bf || !bf->bf_mpdu) | ||
2358 | goto skip; | ||
2359 | |||
2360 | status = ath9k_hw_txprocdesc(ah, bf->bf_desc, &ts); | ||
2361 | if (status == -EINPROGRESS) | ||
2362 | goto skip; | ||
2363 | |||
2364 | sc->beacon.tx_processed = true; | ||
2365 | sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK); | ||
2366 | |||
2367 | skip: | ||
2368 | tasklet_enable(&sc->bcon_tasklet); | ||
2369 | } | ||
2370 | |||
2371 | return sc->beacon.tx_last; | ||
2372 | } | ||
2373 | |||
2335 | struct ieee80211_ops ath9k_ops = { | 2374 | struct ieee80211_ops ath9k_ops = { |
2336 | .tx = ath9k_tx, | 2375 | .tx = ath9k_tx, |
2337 | .start = ath9k_start, | 2376 | .start = ath9k_start, |
@@ -2356,4 +2395,5 @@ struct ieee80211_ops ath9k_ops = { | |||
2356 | .set_coverage_class = ath9k_set_coverage_class, | 2395 | .set_coverage_class = ath9k_set_coverage_class, |
2357 | .flush = ath9k_flush, | 2396 | .flush = ath9k_flush, |
2358 | .tx_frames_pending = ath9k_tx_frames_pending, | 2397 | .tx_frames_pending = ath9k_tx_frames_pending, |
2398 | .tx_last_beacon = ath9k_tx_last_beacon, | ||
2359 | }; | 2399 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 9c65459be100..b8cbfc707213 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index 9441bf8ca2fd..8b380305b0fc 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 4ccbf2ddb553..17542214c93f 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004 Video54 Technologies, Inc. | 2 | * Copyright (c) 2004 Video54 Technologies, Inc. |
3 | * Copyright (c) 2004-2009 Atheros Communications, Inc. | 3 | * Copyright (c) 2004-2011 Atheros Communications, Inc. |
4 | * | 4 | * |
5 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
6 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index 5d984b8acdb1..c3d850207bee 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004 Sam Leffler, Errno Consulting | 2 | * Copyright (c) 2004 Sam Leffler, Errno Consulting |
3 | * Copyright (c) 2004 Video54 Technologies, Inc. | 3 | * Copyright (c) 2004 Video54 Technologies, Inc. |
4 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 4 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
5 | * | 5 | * |
6 | * Permission to use, copy, modify, and/or distribute this software for any | 6 | * Permission to use, copy, modify, and/or distribute this software for any |
7 | * purpose with or without fee is hereby granted, provided that the above | 7 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 4f52e0429f99..07e35e59c9e3 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 456f3ec20fef..c18ee9921fb1 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index f9b1eb4853c4..35422fc1f2ce 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 6095eeb6e025..fde6da619f30 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 97dd1fac98b6..3779b8977d47 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index bb578690935e..4da01a9f5680 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h | |||
@@ -286,6 +286,10 @@ struct ar9170 { | |||
286 | unsigned int tx_seq_table; | 286 | unsigned int tx_seq_table; |
287 | } fw; | 287 | } fw; |
288 | 288 | ||
289 | /* interface configuration combinations */ | ||
290 | struct ieee80211_iface_limit if_comb_limits[1]; | ||
291 | struct ieee80211_iface_combination if_combs[1]; | ||
292 | |||
289 | /* reset / stuck frames/queue detection */ | 293 | /* reset / stuck frames/queue detection */ |
290 | struct work_struct restart_work; | 294 | struct work_struct restart_work; |
291 | struct work_struct ping_work; | 295 | struct work_struct ping_work; |
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index 9517ede9e2df..221957c5d373 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c | |||
@@ -151,6 +151,7 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) | |||
151 | const struct carl9170fw_chk_desc *chk_desc; | 151 | const struct carl9170fw_chk_desc *chk_desc; |
152 | const struct carl9170fw_last_desc *last_desc; | 152 | const struct carl9170fw_last_desc *last_desc; |
153 | const struct carl9170fw_txsq_desc *txsq_desc; | 153 | const struct carl9170fw_txsq_desc *txsq_desc; |
154 | u16 if_comb_types; | ||
154 | 155 | ||
155 | last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC, | 156 | last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC, |
156 | sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER); | 157 | sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER); |
@@ -268,6 +269,9 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) | |||
268 | if (SUPP(CARL9170FW_WOL)) | 269 | if (SUPP(CARL9170FW_WOL)) |
269 | device_set_wakeup_enable(&ar->udev->dev, true); | 270 | device_set_wakeup_enable(&ar->udev->dev, true); |
270 | 271 | ||
272 | if_comb_types = BIT(NL80211_IFTYPE_STATION) | | ||
273 | BIT(NL80211_IFTYPE_P2P_CLIENT); | ||
274 | |||
271 | ar->fw.vif_num = otus_desc->vif_num; | 275 | ar->fw.vif_num = otus_desc->vif_num; |
272 | ar->fw.cmd_bufs = otus_desc->cmd_bufs; | 276 | ar->fw.cmd_bufs = otus_desc->cmd_bufs; |
273 | ar->fw.address = le32_to_cpu(otus_desc->fw_address); | 277 | ar->fw.address = le32_to_cpu(otus_desc->fw_address); |
@@ -294,12 +298,25 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) | |||
294 | ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); | 298 | ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); |
295 | 299 | ||
296 | if (SUPP(CARL9170FW_WLANTX_CAB)) { | 300 | if (SUPP(CARL9170FW_WLANTX_CAB)) { |
297 | ar->hw->wiphy->interface_modes |= | 301 | if_comb_types |= |
298 | BIT(NL80211_IFTYPE_AP) | | 302 | BIT(NL80211_IFTYPE_AP) | |
299 | BIT(NL80211_IFTYPE_P2P_GO); | 303 | BIT(NL80211_IFTYPE_P2P_GO); |
300 | } | 304 | } |
301 | } | 305 | } |
302 | 306 | ||
307 | ar->if_comb_limits[0].max = ar->fw.vif_num; | ||
308 | ar->if_comb_limits[0].types = if_comb_types; | ||
309 | |||
310 | ar->if_combs[0].num_different_channels = 1; | ||
311 | ar->if_combs[0].max_interfaces = ar->fw.vif_num; | ||
312 | ar->if_combs[0].limits = ar->if_comb_limits; | ||
313 | ar->if_combs[0].n_limits = ARRAY_SIZE(ar->if_comb_limits); | ||
314 | |||
315 | ar->hw->wiphy->iface_combinations = ar->if_combs; | ||
316 | ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ar->if_combs); | ||
317 | |||
318 | ar->hw->wiphy->interface_modes |= if_comb_types; | ||
319 | |||
303 | txsq_desc = carl9170_fw_find_desc(ar, TXSQ_MAGIC, | 320 | txsq_desc = carl9170_fw_find_desc(ar, TXSQ_MAGIC, |
304 | sizeof(*txsq_desc), CARL9170FW_TXSQ_DESC_CUR_VER); | 321 | sizeof(*txsq_desc), CARL9170FW_TXSQ_DESC_CUR_VER); |
305 | 322 | ||
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 7d5c65ea94e6..54d093c2ab44 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -1570,14 +1570,8 @@ void *carl9170_alloc(size_t priv_size) | |||
1570 | INIT_LIST_HEAD(&ar->vif_list); | 1570 | INIT_LIST_HEAD(&ar->vif_list); |
1571 | init_completion(&ar->tx_flush); | 1571 | init_completion(&ar->tx_flush); |
1572 | 1572 | ||
1573 | /* | 1573 | /* firmware decides which modes we support */ |
1574 | * Note: | 1574 | hw->wiphy->interface_modes = 0; |
1575 | * IBSS/ADHOC and AP mode are only enabled, if the firmware | ||
1576 | * supports these modes. The code which will add the | ||
1577 | * additional interface_modes is in fw.c. | ||
1578 | */ | ||
1579 | hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | | ||
1580 | BIT(NL80211_IFTYPE_P2P_CLIENT); | ||
1581 | 1575 | ||
1582 | hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | | 1576 | hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | |
1583 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 1577 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c index cc11d66f15bc..3f508e59f146 100644 --- a/drivers/net/wireless/ath/hw.c +++ b/drivers/net/wireless/ath/hw.c | |||
@@ -43,7 +43,7 @@ | |||
43 | * set of ~ ( MAC XOR BSSID ) for all bssids we handle. | 43 | * set of ~ ( MAC XOR BSSID ) for all bssids we handle. |
44 | * | 44 | * |
45 | * When you do this you are essentially computing the common bits of all your | 45 | * When you do this you are essentially computing the common bits of all your |
46 | * BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with | 46 | * BSSes. Later it is assumed the hardware will "and" (&) the BSSID mask with |
47 | * the MAC address to obtain the relevant bits and compare the result with | 47 | * the MAC address to obtain the relevant bits and compare the result with |
48 | * (frame's BSSID & mask) to see if they match. | 48 | * (frame's BSSID & mask) to see if they match. |
49 | * | 49 | * |
@@ -71,8 +71,8 @@ | |||
71 | * On loop iteration for BSSID-02: | 71 | * On loop iteration for BSSID-02: |
72 | * bssid_mask &= ~(0001 ^ 1001) | 72 | * bssid_mask &= ~(0001 ^ 1001) |
73 | * bssid_mask = (1010) & ~(0001 ^ 1001) | 73 | * bssid_mask = (1010) & ~(0001 ^ 1001) |
74 | * bssid_mask = (1010) & ~(1001) | 74 | * bssid_mask = (1010) & ~(1000) |
75 | * bssid_mask = (1010) & (0110) | 75 | * bssid_mask = (1010) & (0111) |
76 | * bssid_mask = 0010 | 76 | * bssid_mask = 0010 |
77 | * | 77 | * |
78 | * A bssid_mask of 0010 means "only pay attention to the second least | 78 | * A bssid_mask of 0010 means "only pay attention to the second least |
@@ -102,11 +102,9 @@ | |||
102 | * | 102 | * |
103 | * IFRAME-02: 0001 (we should allow) | 103 | * IFRAME-02: 0001 (we should allow) |
104 | * | 104 | * |
105 | * allow = (0001 & 1010) == 1010 | ||
106 | * | ||
107 | * allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0; | 105 | * allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0; |
108 | * --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0; | 106 | * --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0; |
109 | * --> allow = (0010) == (0010) | 107 | * --> allow = (0000) == (0000) |
110 | * --> allow = 1 | 108 | * --> allow = 1 |
111 | * | 109 | * |
112 | * Other examples: | 110 | * Other examples: |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index ebc93c1bb5e7..25a78cfb7d15 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -567,6 +567,8 @@ struct b43_dma { | |||
567 | struct b43_dmaring *tx_ring_mcast; /* Multicast */ | 567 | struct b43_dmaring *tx_ring_mcast; /* Multicast */ |
568 | 568 | ||
569 | struct b43_dmaring *rx_ring; | 569 | struct b43_dmaring *rx_ring; |
570 | |||
571 | u32 translation; /* Routing bits */ | ||
570 | }; | 572 | }; |
571 | 573 | ||
572 | struct b43_pio_txqueue; | 574 | struct b43_pio_txqueue; |
@@ -705,7 +707,7 @@ enum { | |||
705 | 707 | ||
706 | /* Data structure for one wireless device (802.11 core) */ | 708 | /* Data structure for one wireless device (802.11 core) */ |
707 | struct b43_wldev { | 709 | struct b43_wldev { |
708 | struct ssb_device *dev; | 710 | struct ssb_device *sdev; |
709 | struct b43_wl *wl; | 711 | struct b43_wl *wl; |
710 | 712 | ||
711 | /* The device initialization status. | 713 | /* The device initialization status. |
@@ -879,22 +881,34 @@ static inline enum ieee80211_band b43_current_band(struct b43_wl *wl) | |||
879 | 881 | ||
880 | static inline u16 b43_read16(struct b43_wldev *dev, u16 offset) | 882 | static inline u16 b43_read16(struct b43_wldev *dev, u16 offset) |
881 | { | 883 | { |
882 | return ssb_read16(dev->dev, offset); | 884 | return ssb_read16(dev->sdev, offset); |
883 | } | 885 | } |
884 | 886 | ||
885 | static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value) | 887 | static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value) |
886 | { | 888 | { |
887 | ssb_write16(dev->dev, offset, value); | 889 | ssb_write16(dev->sdev, offset, value); |
888 | } | 890 | } |
889 | 891 | ||
890 | static inline u32 b43_read32(struct b43_wldev *dev, u16 offset) | 892 | static inline u32 b43_read32(struct b43_wldev *dev, u16 offset) |
891 | { | 893 | { |
892 | return ssb_read32(dev->dev, offset); | 894 | return ssb_read32(dev->sdev, offset); |
893 | } | 895 | } |
894 | 896 | ||
895 | static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value) | 897 | static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value) |
896 | { | 898 | { |
897 | ssb_write32(dev->dev, offset, value); | 899 | ssb_write32(dev->sdev, offset, value); |
900 | } | ||
901 | |||
902 | static inline void b43_block_read(struct b43_wldev *dev, void *buffer, | ||
903 | size_t count, u16 offset, u8 reg_width) | ||
904 | { | ||
905 | ssb_block_read(dev->sdev, buffer, count, offset, reg_width); | ||
906 | } | ||
907 | |||
908 | static inline void b43_block_write(struct b43_wldev *dev, const void *buffer, | ||
909 | size_t count, u16 offset, u8 reg_width) | ||
910 | { | ||
911 | ssb_block_write(dev->sdev, buffer, count, offset, reg_width); | ||
898 | } | 912 | } |
899 | 913 | ||
900 | static inline bool b43_using_pio_transfers(struct b43_wldev *dev) | 914 | static inline bool b43_using_pio_transfers(struct b43_wldev *dev) |
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index ff0f5ba14b2c..47d44bcff37d 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -80,7 +80,7 @@ static void op32_fill_descriptor(struct b43_dmaring *ring, | |||
80 | addr = (u32) (dmaaddr & ~SSB_DMA_TRANSLATION_MASK); | 80 | addr = (u32) (dmaaddr & ~SSB_DMA_TRANSLATION_MASK); |
81 | addrext = (u32) (dmaaddr & SSB_DMA_TRANSLATION_MASK) | 81 | addrext = (u32) (dmaaddr & SSB_DMA_TRANSLATION_MASK) |
82 | >> SSB_DMA_TRANSLATION_SHIFT; | 82 | >> SSB_DMA_TRANSLATION_SHIFT; |
83 | addr |= ssb_dma_translation(ring->dev->dev); | 83 | addr |= ring->dev->dma.translation; |
84 | ctl = bufsize & B43_DMA32_DCTL_BYTECNT; | 84 | ctl = bufsize & B43_DMA32_DCTL_BYTECNT; |
85 | if (slot == ring->nr_slots - 1) | 85 | if (slot == ring->nr_slots - 1) |
86 | ctl |= B43_DMA32_DCTL_DTABLEEND; | 86 | ctl |= B43_DMA32_DCTL_DTABLEEND; |
@@ -174,7 +174,7 @@ static void op64_fill_descriptor(struct b43_dmaring *ring, | |||
174 | addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK); | 174 | addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK); |
175 | addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK) | 175 | addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK) |
176 | >> SSB_DMA_TRANSLATION_SHIFT; | 176 | >> SSB_DMA_TRANSLATION_SHIFT; |
177 | addrhi |= (ssb_dma_translation(ring->dev->dev) << 1); | 177 | addrhi |= (ring->dev->dma.translation << 1); |
178 | if (slot == ring->nr_slots - 1) | 178 | if (slot == ring->nr_slots - 1) |
179 | ctl0 |= B43_DMA64_DCTL0_DTABLEEND; | 179 | ctl0 |= B43_DMA64_DCTL0_DTABLEEND; |
180 | if (start) | 180 | if (start) |
@@ -333,10 +333,10 @@ static inline | |||
333 | dma_addr_t dmaaddr; | 333 | dma_addr_t dmaaddr; |
334 | 334 | ||
335 | if (tx) { | 335 | if (tx) { |
336 | dmaaddr = dma_map_single(ring->dev->dev->dma_dev, | 336 | dmaaddr = dma_map_single(ring->dev->sdev->dma_dev, |
337 | buf, len, DMA_TO_DEVICE); | 337 | buf, len, DMA_TO_DEVICE); |
338 | } else { | 338 | } else { |
339 | dmaaddr = dma_map_single(ring->dev->dev->dma_dev, | 339 | dmaaddr = dma_map_single(ring->dev->sdev->dma_dev, |
340 | buf, len, DMA_FROM_DEVICE); | 340 | buf, len, DMA_FROM_DEVICE); |
341 | } | 341 | } |
342 | 342 | ||
@@ -348,10 +348,10 @@ static inline | |||
348 | dma_addr_t addr, size_t len, int tx) | 348 | dma_addr_t addr, size_t len, int tx) |
349 | { | 349 | { |
350 | if (tx) { | 350 | if (tx) { |
351 | dma_unmap_single(ring->dev->dev->dma_dev, | 351 | dma_unmap_single(ring->dev->sdev->dma_dev, |
352 | addr, len, DMA_TO_DEVICE); | 352 | addr, len, DMA_TO_DEVICE); |
353 | } else { | 353 | } else { |
354 | dma_unmap_single(ring->dev->dev->dma_dev, | 354 | dma_unmap_single(ring->dev->sdev->dma_dev, |
355 | addr, len, DMA_FROM_DEVICE); | 355 | addr, len, DMA_FROM_DEVICE); |
356 | } | 356 | } |
357 | } | 357 | } |
@@ -361,7 +361,7 @@ static inline | |||
361 | dma_addr_t addr, size_t len) | 361 | dma_addr_t addr, size_t len) |
362 | { | 362 | { |
363 | B43_WARN_ON(ring->tx); | 363 | B43_WARN_ON(ring->tx); |
364 | dma_sync_single_for_cpu(ring->dev->dev->dma_dev, | 364 | dma_sync_single_for_cpu(ring->dev->sdev->dma_dev, |
365 | addr, len, DMA_FROM_DEVICE); | 365 | addr, len, DMA_FROM_DEVICE); |
366 | } | 366 | } |
367 | 367 | ||
@@ -370,7 +370,7 @@ static inline | |||
370 | dma_addr_t addr, size_t len) | 370 | dma_addr_t addr, size_t len) |
371 | { | 371 | { |
372 | B43_WARN_ON(ring->tx); | 372 | B43_WARN_ON(ring->tx); |
373 | dma_sync_single_for_device(ring->dev->dev->dma_dev, | 373 | dma_sync_single_for_device(ring->dev->sdev->dma_dev, |
374 | addr, len, DMA_FROM_DEVICE); | 374 | addr, len, DMA_FROM_DEVICE); |
375 | } | 375 | } |
376 | 376 | ||
@@ -401,7 +401,7 @@ static int alloc_ringmemory(struct b43_dmaring *ring) | |||
401 | */ | 401 | */ |
402 | if (ring->type == B43_DMA_64BIT) | 402 | if (ring->type == B43_DMA_64BIT) |
403 | flags |= GFP_DMA; | 403 | flags |= GFP_DMA; |
404 | ring->descbase = dma_alloc_coherent(ring->dev->dev->dma_dev, | 404 | ring->descbase = dma_alloc_coherent(ring->dev->sdev->dma_dev, |
405 | B43_DMA_RINGMEMSIZE, | 405 | B43_DMA_RINGMEMSIZE, |
406 | &(ring->dmabase), flags); | 406 | &(ring->dmabase), flags); |
407 | if (!ring->descbase) { | 407 | if (!ring->descbase) { |
@@ -415,7 +415,7 @@ static int alloc_ringmemory(struct b43_dmaring *ring) | |||
415 | 415 | ||
416 | static void free_ringmemory(struct b43_dmaring *ring) | 416 | static void free_ringmemory(struct b43_dmaring *ring) |
417 | { | 417 | { |
418 | dma_free_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE, | 418 | dma_free_coherent(ring->dev->sdev->dma_dev, B43_DMA_RINGMEMSIZE, |
419 | ring->descbase, ring->dmabase); | 419 | ring->descbase, ring->dmabase); |
420 | } | 420 | } |
421 | 421 | ||
@@ -523,7 +523,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, | |||
523 | dma_addr_t addr, | 523 | dma_addr_t addr, |
524 | size_t buffersize, bool dma_to_device) | 524 | size_t buffersize, bool dma_to_device) |
525 | { | 525 | { |
526 | if (unlikely(dma_mapping_error(ring->dev->dev->dma_dev, addr))) | 526 | if (unlikely(dma_mapping_error(ring->dev->sdev->dma_dev, addr))) |
527 | return 1; | 527 | return 1; |
528 | 528 | ||
529 | switch (ring->type) { | 529 | switch (ring->type) { |
@@ -658,7 +658,7 @@ static int dmacontroller_setup(struct b43_dmaring *ring) | |||
658 | int err = 0; | 658 | int err = 0; |
659 | u32 value; | 659 | u32 value; |
660 | u32 addrext; | 660 | u32 addrext; |
661 | u32 trans = ssb_dma_translation(ring->dev->dev); | 661 | u32 trans = ring->dev->dma.translation; |
662 | 662 | ||
663 | if (ring->tx) { | 663 | if (ring->tx) { |
664 | if (ring->type == B43_DMA_64BIT) { | 664 | if (ring->type == B43_DMA_64BIT) { |
@@ -869,7 +869,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
869 | goto err_kfree_meta; | 869 | goto err_kfree_meta; |
870 | 870 | ||
871 | /* test for ability to dma to txhdr_cache */ | 871 | /* test for ability to dma to txhdr_cache */ |
872 | dma_test = dma_map_single(dev->dev->dma_dev, | 872 | dma_test = dma_map_single(dev->sdev->dma_dev, |
873 | ring->txhdr_cache, | 873 | ring->txhdr_cache, |
874 | b43_txhdr_size(dev), | 874 | b43_txhdr_size(dev), |
875 | DMA_TO_DEVICE); | 875 | DMA_TO_DEVICE); |
@@ -884,7 +884,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
884 | if (!ring->txhdr_cache) | 884 | if (!ring->txhdr_cache) |
885 | goto err_kfree_meta; | 885 | goto err_kfree_meta; |
886 | 886 | ||
887 | dma_test = dma_map_single(dev->dev->dma_dev, | 887 | dma_test = dma_map_single(dev->sdev->dma_dev, |
888 | ring->txhdr_cache, | 888 | ring->txhdr_cache, |
889 | b43_txhdr_size(dev), | 889 | b43_txhdr_size(dev), |
890 | DMA_TO_DEVICE); | 890 | DMA_TO_DEVICE); |
@@ -898,7 +898,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
898 | } | 898 | } |
899 | } | 899 | } |
900 | 900 | ||
901 | dma_unmap_single(dev->dev->dma_dev, | 901 | dma_unmap_single(dev->sdev->dma_dev, |
902 | dma_test, b43_txhdr_size(dev), | 902 | dma_test, b43_txhdr_size(dev), |
903 | DMA_TO_DEVICE); | 903 | DMA_TO_DEVICE); |
904 | } | 904 | } |
@@ -1013,9 +1013,9 @@ static int b43_dma_set_mask(struct b43_wldev *dev, u64 mask) | |||
1013 | /* Try to set the DMA mask. If it fails, try falling back to a | 1013 | /* Try to set the DMA mask. If it fails, try falling back to a |
1014 | * lower mask, as we can always also support a lower one. */ | 1014 | * lower mask, as we can always also support a lower one. */ |
1015 | while (1) { | 1015 | while (1) { |
1016 | err = dma_set_mask(dev->dev->dma_dev, mask); | 1016 | err = dma_set_mask(dev->sdev->dma_dev, mask); |
1017 | if (!err) { | 1017 | if (!err) { |
1018 | err = dma_set_coherent_mask(dev->dev->dma_dev, mask); | 1018 | err = dma_set_coherent_mask(dev->sdev->dma_dev, mask); |
1019 | if (!err) | 1019 | if (!err) |
1020 | break; | 1020 | break; |
1021 | } | 1021 | } |
@@ -1055,6 +1055,7 @@ int b43_dma_init(struct b43_wldev *dev) | |||
1055 | err = b43_dma_set_mask(dev, dmamask); | 1055 | err = b43_dma_set_mask(dev, dmamask); |
1056 | if (err) | 1056 | if (err) |
1057 | return err; | 1057 | return err; |
1058 | dma->translation = ssb_dma_translation(dev->sdev); | ||
1058 | 1059 | ||
1059 | err = -ENOMEM; | 1060 | err = -ENOMEM; |
1060 | /* setup TX DMA channels. */ | 1061 | /* setup TX DMA channels. */ |
@@ -1084,7 +1085,7 @@ int b43_dma_init(struct b43_wldev *dev) | |||
1084 | goto err_destroy_mcast; | 1085 | goto err_destroy_mcast; |
1085 | 1086 | ||
1086 | /* No support for the TX status DMA ring. */ | 1087 | /* No support for the TX status DMA ring. */ |
1087 | B43_WARN_ON(dev->dev->id.revision < 5); | 1088 | B43_WARN_ON(dev->sdev->id.revision < 5); |
1088 | 1089 | ||
1089 | b43dbg(dev->wl, "%u-bit DMA initialized\n", | 1090 | b43dbg(dev->wl, "%u-bit DMA initialized\n", |
1090 | (unsigned int)type); | 1091 | (unsigned int)type); |
diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c index c587115dd2b9..0cafafe368af 100644 --- a/drivers/net/wireless/b43/leds.c +++ b/drivers/net/wireless/b43/leds.c | |||
@@ -138,7 +138,7 @@ static int b43_register_led(struct b43_wldev *dev, struct b43_led *led, | |||
138 | led->led_dev.default_trigger = default_trigger; | 138 | led->led_dev.default_trigger = default_trigger; |
139 | led->led_dev.brightness_set = b43_led_brightness_set; | 139 | led->led_dev.brightness_set = b43_led_brightness_set; |
140 | 140 | ||
141 | err = led_classdev_register(dev->dev->dev, &led->led_dev); | 141 | err = led_classdev_register(dev->sdev->dev, &led->led_dev); |
142 | if (err) { | 142 | if (err) { |
143 | b43warn(dev->wl, "LEDs: Failed to register %s\n", name); | 143 | b43warn(dev->wl, "LEDs: Failed to register %s\n", name); |
144 | led->wl = NULL; | 144 | led->wl = NULL; |
@@ -215,7 +215,7 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev, | |||
215 | enum b43_led_behaviour *behaviour, | 215 | enum b43_led_behaviour *behaviour, |
216 | bool *activelow) | 216 | bool *activelow) |
217 | { | 217 | { |
218 | struct ssb_bus *bus = dev->dev->bus; | 218 | struct ssb_bus *bus = dev->sdev->bus; |
219 | u8 sprom[4]; | 219 | u8 sprom[4]; |
220 | 220 | ||
221 | sprom[0] = bus->sprom.gpio0; | 221 | sprom[0] = bus->sprom.gpio0; |
diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c index 94e4f1378fc3..2ef7d4b38540 100644 --- a/drivers/net/wireless/b43/lo.c +++ b/drivers/net/wireless/b43/lo.c | |||
@@ -98,7 +98,7 @@ static u16 lo_measure_feedthrough(struct b43_wldev *dev, | |||
98 | rfover |= pga; | 98 | rfover |= pga; |
99 | rfover |= lna; | 99 | rfover |= lna; |
100 | rfover |= trsw_rx; | 100 | rfover |= trsw_rx; |
101 | if ((dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) | 101 | if ((dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) |
102 | && phy->rev > 6) | 102 | && phy->rev > 6) |
103 | rfover |= B43_PHY_RFOVERVAL_EXTLNA; | 103 | rfover |= B43_PHY_RFOVERVAL_EXTLNA; |
104 | 104 | ||
@@ -387,7 +387,7 @@ struct lo_g_saved_values { | |||
387 | static void lo_measure_setup(struct b43_wldev *dev, | 387 | static void lo_measure_setup(struct b43_wldev *dev, |
388 | struct lo_g_saved_values *sav) | 388 | struct lo_g_saved_values *sav) |
389 | { | 389 | { |
390 | struct ssb_sprom *sprom = &dev->dev->bus->sprom; | 390 | struct ssb_sprom *sprom = &dev->sdev->bus->sprom; |
391 | struct b43_phy *phy = &dev->phy; | 391 | struct b43_phy *phy = &dev->phy; |
392 | struct b43_phy_g *gphy = phy->g; | 392 | struct b43_phy_g *gphy = phy->g; |
393 | struct b43_txpower_lo_control *lo = gphy->lo_control; | 393 | struct b43_txpower_lo_control *lo = gphy->lo_control; |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 5a43984bdcea..eb4159686985 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -548,7 +548,7 @@ void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) | |||
548 | { | 548 | { |
549 | u32 low, high; | 549 | u32 low, high; |
550 | 550 | ||
551 | B43_WARN_ON(dev->dev->id.revision < 3); | 551 | B43_WARN_ON(dev->sdev->id.revision < 3); |
552 | 552 | ||
553 | /* The hardware guarantees us an atomic read, if we | 553 | /* The hardware guarantees us an atomic read, if we |
554 | * read the low register first. */ | 554 | * read the low register first. */ |
@@ -586,7 +586,7 @@ static void b43_tsf_write_locked(struct b43_wldev *dev, u64 tsf) | |||
586 | { | 586 | { |
587 | u32 low, high; | 587 | u32 low, high; |
588 | 588 | ||
589 | B43_WARN_ON(dev->dev->id.revision < 3); | 589 | B43_WARN_ON(dev->sdev->id.revision < 3); |
590 | 590 | ||
591 | low = tsf; | 591 | low = tsf; |
592 | high = (tsf >> 32); | 592 | high = (tsf >> 32); |
@@ -714,7 +714,7 @@ void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on) | |||
714 | b43_ram_write(dev, i * 4, buffer[i]); | 714 | b43_ram_write(dev, i * 4, buffer[i]); |
715 | 715 | ||
716 | b43_write16(dev, 0x0568, 0x0000); | 716 | b43_write16(dev, 0x0568, 0x0000); |
717 | if (dev->dev->id.revision < 11) | 717 | if (dev->sdev->id.revision < 11) |
718 | b43_write16(dev, 0x07C0, 0x0000); | 718 | b43_write16(dev, 0x07C0, 0x0000); |
719 | else | 719 | else |
720 | b43_write16(dev, 0x07C0, 0x0100); | 720 | b43_write16(dev, 0x07C0, 0x0100); |
@@ -1132,7 +1132,7 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) | |||
1132 | b43_write32(dev, B43_MMIO_MACCTL, macctl); | 1132 | b43_write32(dev, B43_MMIO_MACCTL, macctl); |
1133 | /* Commit write */ | 1133 | /* Commit write */ |
1134 | b43_read32(dev, B43_MMIO_MACCTL); | 1134 | b43_read32(dev, B43_MMIO_MACCTL); |
1135 | if (awake && dev->dev->id.revision >= 5) { | 1135 | if (awake && dev->sdev->id.revision >= 5) { |
1136 | /* Wait for the microcode to wake up. */ | 1136 | /* Wait for the microcode to wake up. */ |
1137 | for (i = 0; i < 100; i++) { | 1137 | for (i = 0; i < 100; i++) { |
1138 | ucstat = b43_shm_read16(dev, B43_SHM_SHARED, | 1138 | ucstat = b43_shm_read16(dev, B43_SHM_SHARED, |
@@ -1144,29 +1144,35 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) | |||
1144 | } | 1144 | } |
1145 | } | 1145 | } |
1146 | 1146 | ||
1147 | void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) | 1147 | static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, u32 flags) |
1148 | { | 1148 | { |
1149 | u32 tmslow; | 1149 | u32 tmslow; |
1150 | u32 macctl; | ||
1151 | 1150 | ||
1152 | flags |= B43_TMSLOW_PHYCLKEN; | 1151 | flags |= B43_TMSLOW_PHYCLKEN; |
1153 | flags |= B43_TMSLOW_PHYRESET; | 1152 | flags |= B43_TMSLOW_PHYRESET; |
1154 | if (dev->phy.type == B43_PHYTYPE_N) | 1153 | if (dev->phy.type == B43_PHYTYPE_N) |
1155 | flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */ | 1154 | flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */ |
1156 | ssb_device_enable(dev->dev, flags); | 1155 | ssb_device_enable(dev->sdev, flags); |
1157 | msleep(2); /* Wait for the PLL to turn on. */ | 1156 | msleep(2); /* Wait for the PLL to turn on. */ |
1158 | 1157 | ||
1159 | /* Now take the PHY out of Reset again */ | 1158 | /* Now take the PHY out of Reset again */ |
1160 | tmslow = ssb_read32(dev->dev, SSB_TMSLOW); | 1159 | tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); |
1161 | tmslow |= SSB_TMSLOW_FGC; | 1160 | tmslow |= SSB_TMSLOW_FGC; |
1162 | tmslow &= ~B43_TMSLOW_PHYRESET; | 1161 | tmslow &= ~B43_TMSLOW_PHYRESET; |
1163 | ssb_write32(dev->dev, SSB_TMSLOW, tmslow); | 1162 | ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); |
1164 | ssb_read32(dev->dev, SSB_TMSLOW); /* flush */ | 1163 | ssb_read32(dev->sdev, SSB_TMSLOW); /* flush */ |
1165 | msleep(1); | 1164 | msleep(1); |
1166 | tmslow &= ~SSB_TMSLOW_FGC; | 1165 | tmslow &= ~SSB_TMSLOW_FGC; |
1167 | ssb_write32(dev->dev, SSB_TMSLOW, tmslow); | 1166 | ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); |
1168 | ssb_read32(dev->dev, SSB_TMSLOW); /* flush */ | 1167 | ssb_read32(dev->sdev, SSB_TMSLOW); /* flush */ |
1169 | msleep(1); | 1168 | msleep(1); |
1169 | } | ||
1170 | |||
1171 | void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) | ||
1172 | { | ||
1173 | u32 macctl; | ||
1174 | |||
1175 | b43_ssb_wireless_core_reset(dev, flags); | ||
1170 | 1176 | ||
1171 | /* Turn Analog ON, but only if we already know the PHY-type. | 1177 | /* Turn Analog ON, but only if we already know the PHY-type. |
1172 | * This protects against very early setup where we don't know the | 1178 | * This protects against very early setup where we don't know the |
@@ -1215,7 +1221,7 @@ static void drain_txstatus_queue(struct b43_wldev *dev) | |||
1215 | { | 1221 | { |
1216 | u32 dummy; | 1222 | u32 dummy; |
1217 | 1223 | ||
1218 | if (dev->dev->id.revision < 5) | 1224 | if (dev->sdev->id.revision < 5) |
1219 | return; | 1225 | return; |
1220 | /* Read all entries from the microcode TXstatus FIFO | 1226 | /* Read all entries from the microcode TXstatus FIFO |
1221 | * and throw them away. | 1227 | * and throw them away. |
@@ -1421,9 +1427,9 @@ u8 b43_ieee80211_antenna_sanitize(struct b43_wldev *dev, | |||
1421 | 1427 | ||
1422 | /* Get the mask of available antennas. */ | 1428 | /* Get the mask of available antennas. */ |
1423 | if (dev->phy.gmode) | 1429 | if (dev->phy.gmode) |
1424 | antenna_mask = dev->dev->bus->sprom.ant_available_bg; | 1430 | antenna_mask = dev->sdev->bus->sprom.ant_available_bg; |
1425 | else | 1431 | else |
1426 | antenna_mask = dev->dev->bus->sprom.ant_available_a; | 1432 | antenna_mask = dev->sdev->bus->sprom.ant_available_a; |
1427 | 1433 | ||
1428 | if (!(antenna_mask & (1 << (antenna_nr - 1)))) { | 1434 | if (!(antenna_mask & (1 << (antenna_nr - 1)))) { |
1429 | /* This antenna is not available. Fall back to default. */ | 1435 | /* This antenna is not available. Fall back to default. */ |
@@ -1638,7 +1644,7 @@ static void b43_beacon_update_trigger_work(struct work_struct *work) | |||
1638 | mutex_lock(&wl->mutex); | 1644 | mutex_lock(&wl->mutex); |
1639 | dev = wl->current_dev; | 1645 | dev = wl->current_dev; |
1640 | if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { | 1646 | if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { |
1641 | if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) { | 1647 | if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { |
1642 | /* wl->mutex is enough. */ | 1648 | /* wl->mutex is enough. */ |
1643 | b43_do_beacon_update_trigger_work(dev); | 1649 | b43_do_beacon_update_trigger_work(dev); |
1644 | mmiowb(); | 1650 | mmiowb(); |
@@ -1683,7 +1689,7 @@ static void b43_update_templates(struct b43_wl *wl) | |||
1683 | static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) | 1689 | static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) |
1684 | { | 1690 | { |
1685 | b43_time_lock(dev); | 1691 | b43_time_lock(dev); |
1686 | if (dev->dev->id.revision >= 3) { | 1692 | if (dev->sdev->id.revision >= 3) { |
1687 | b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16)); | 1693 | b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16)); |
1688 | b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10)); | 1694 | b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10)); |
1689 | } else { | 1695 | } else { |
@@ -2057,7 +2063,7 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx, | |||
2057 | B43_WARN_ON(1); | 2063 | B43_WARN_ON(1); |
2058 | return -ENOSYS; | 2064 | return -ENOSYS; |
2059 | } | 2065 | } |
2060 | err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev); | 2066 | err = request_firmware(&blob, ctx->fwname, ctx->dev->sdev->dev); |
2061 | if (err == -ENOENT) { | 2067 | if (err == -ENOENT) { |
2062 | snprintf(ctx->errors[ctx->req_type], | 2068 | snprintf(ctx->errors[ctx->req_type], |
2063 | sizeof(ctx->errors[ctx->req_type]), | 2069 | sizeof(ctx->errors[ctx->req_type]), |
@@ -2107,13 +2113,12 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) | |||
2107 | { | 2113 | { |
2108 | struct b43_wldev *dev = ctx->dev; | 2114 | struct b43_wldev *dev = ctx->dev; |
2109 | struct b43_firmware *fw = &ctx->dev->fw; | 2115 | struct b43_firmware *fw = &ctx->dev->fw; |
2110 | const u8 rev = ctx->dev->dev->id.revision; | 2116 | const u8 rev = ctx->dev->sdev->id.revision; |
2111 | const char *filename; | 2117 | const char *filename; |
2112 | u32 tmshigh; | 2118 | u32 tmshigh; |
2113 | int err; | 2119 | int err; |
2114 | 2120 | ||
2115 | /* Get microcode */ | 2121 | /* Get microcode */ |
2116 | tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH); | ||
2117 | if ((rev >= 5) && (rev <= 10)) | 2122 | if ((rev >= 5) && (rev <= 10)) |
2118 | filename = "ucode5"; | 2123 | filename = "ucode5"; |
2119 | else if ((rev >= 11) && (rev <= 12)) | 2124 | else if ((rev >= 11) && (rev <= 12)) |
@@ -2152,6 +2157,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) | |||
2152 | switch (dev->phy.type) { | 2157 | switch (dev->phy.type) { |
2153 | case B43_PHYTYPE_A: | 2158 | case B43_PHYTYPE_A: |
2154 | if ((rev >= 5) && (rev <= 10)) { | 2159 | if ((rev >= 5) && (rev <= 10)) { |
2160 | tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); | ||
2155 | if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) | 2161 | if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) |
2156 | filename = "a0g1initvals5"; | 2162 | filename = "a0g1initvals5"; |
2157 | else | 2163 | else |
@@ -2196,6 +2202,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) | |||
2196 | switch (dev->phy.type) { | 2202 | switch (dev->phy.type) { |
2197 | case B43_PHYTYPE_A: | 2203 | case B43_PHYTYPE_A: |
2198 | if ((rev >= 5) && (rev <= 10)) { | 2204 | if ((rev >= 5) && (rev <= 10)) { |
2205 | tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); | ||
2199 | if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) | 2206 | if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) |
2200 | filename = "a0g1bsinitvals5"; | 2207 | filename = "a0g1bsinitvals5"; |
2201 | else | 2208 | else |
@@ -2441,7 +2448,7 @@ static int b43_upload_microcode(struct b43_wldev *dev) | |||
2441 | 2448 | ||
2442 | snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u", | 2449 | snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u", |
2443 | dev->fw.rev, dev->fw.patch); | 2450 | dev->fw.rev, dev->fw.patch); |
2444 | wiphy->hw_version = dev->dev->id.coreid; | 2451 | wiphy->hw_version = dev->sdev->id.coreid; |
2445 | 2452 | ||
2446 | if (b43_is_old_txhdr_format(dev)) { | 2453 | if (b43_is_old_txhdr_format(dev)) { |
2447 | /* We're over the deadline, but we keep support for old fw | 2454 | /* We're over the deadline, but we keep support for old fw |
@@ -2557,10 +2564,20 @@ out: | |||
2557 | /* Initialize the GPIOs | 2564 | /* Initialize the GPIOs |
2558 | * http://bcm-specs.sipsolutions.net/GPIO | 2565 | * http://bcm-specs.sipsolutions.net/GPIO |
2559 | */ | 2566 | */ |
2567 | static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev) | ||
2568 | { | ||
2569 | struct ssb_bus *bus = dev->sdev->bus; | ||
2570 | |||
2571 | #ifdef CONFIG_SSB_DRIVER_PCICORE | ||
2572 | return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev); | ||
2573 | #else | ||
2574 | return bus->chipco.dev; | ||
2575 | #endif | ||
2576 | } | ||
2577 | |||
2560 | static int b43_gpio_init(struct b43_wldev *dev) | 2578 | static int b43_gpio_init(struct b43_wldev *dev) |
2561 | { | 2579 | { |
2562 | struct ssb_bus *bus = dev->dev->bus; | 2580 | struct ssb_device *gpiodev; |
2563 | struct ssb_device *gpiodev, *pcidev = NULL; | ||
2564 | u32 mask, set; | 2581 | u32 mask, set; |
2565 | 2582 | ||
2566 | b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) | 2583 | b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) |
@@ -2571,7 +2588,7 @@ static int b43_gpio_init(struct b43_wldev *dev) | |||
2571 | 2588 | ||
2572 | mask = 0x0000001F; | 2589 | mask = 0x0000001F; |
2573 | set = 0x0000000F; | 2590 | set = 0x0000000F; |
2574 | if (dev->dev->bus->chip_id == 0x4301) { | 2591 | if (dev->sdev->bus->chip_id == 0x4301) { |
2575 | mask |= 0x0060; | 2592 | mask |= 0x0060; |
2576 | set |= 0x0060; | 2593 | set |= 0x0060; |
2577 | } | 2594 | } |
@@ -2582,25 +2599,21 @@ static int b43_gpio_init(struct b43_wldev *dev) | |||
2582 | mask |= 0x0180; | 2599 | mask |= 0x0180; |
2583 | set |= 0x0180; | 2600 | set |= 0x0180; |
2584 | } | 2601 | } |
2585 | if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) { | 2602 | if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) { |
2586 | b43_write16(dev, B43_MMIO_GPIO_MASK, | 2603 | b43_write16(dev, B43_MMIO_GPIO_MASK, |
2587 | b43_read16(dev, B43_MMIO_GPIO_MASK) | 2604 | b43_read16(dev, B43_MMIO_GPIO_MASK) |
2588 | | 0x0200); | 2605 | | 0x0200); |
2589 | mask |= 0x0200; | 2606 | mask |= 0x0200; |
2590 | set |= 0x0200; | 2607 | set |= 0x0200; |
2591 | } | 2608 | } |
2592 | if (dev->dev->id.revision >= 2) | 2609 | if (dev->sdev->id.revision >= 2) |
2593 | mask |= 0x0010; /* FIXME: This is redundant. */ | 2610 | mask |= 0x0010; /* FIXME: This is redundant. */ |
2594 | 2611 | ||
2595 | #ifdef CONFIG_SSB_DRIVER_PCICORE | 2612 | gpiodev = b43_ssb_gpio_dev(dev); |
2596 | pcidev = bus->pcicore.dev; | 2613 | if (gpiodev) |
2597 | #endif | 2614 | ssb_write32(gpiodev, B43_GPIO_CONTROL, |
2598 | gpiodev = bus->chipco.dev ? : pcidev; | 2615 | (ssb_read32(gpiodev, B43_GPIO_CONTROL) |
2599 | if (!gpiodev) | 2616 | & mask) | set); |
2600 | return 0; | ||
2601 | ssb_write32(gpiodev, B43_GPIO_CONTROL, | ||
2602 | (ssb_read32(gpiodev, B43_GPIO_CONTROL) | ||
2603 | & mask) | set); | ||
2604 | 2617 | ||
2605 | return 0; | 2618 | return 0; |
2606 | } | 2619 | } |
@@ -2608,16 +2621,11 @@ static int b43_gpio_init(struct b43_wldev *dev) | |||
2608 | /* Turn off all GPIO stuff. Call this on module unload, for example. */ | 2621 | /* Turn off all GPIO stuff. Call this on module unload, for example. */ |
2609 | static void b43_gpio_cleanup(struct b43_wldev *dev) | 2622 | static void b43_gpio_cleanup(struct b43_wldev *dev) |
2610 | { | 2623 | { |
2611 | struct ssb_bus *bus = dev->dev->bus; | 2624 | struct ssb_device *gpiodev; |
2612 | struct ssb_device *gpiodev, *pcidev = NULL; | ||
2613 | 2625 | ||
2614 | #ifdef CONFIG_SSB_DRIVER_PCICORE | 2626 | gpiodev = b43_ssb_gpio_dev(dev); |
2615 | pcidev = bus->pcicore.dev; | 2627 | if (gpiodev) |
2616 | #endif | 2628 | ssb_write32(gpiodev, B43_GPIO_CONTROL, 0); |
2617 | gpiodev = bus->chipco.dev ? : pcidev; | ||
2618 | if (!gpiodev) | ||
2619 | return; | ||
2620 | ssb_write32(gpiodev, B43_GPIO_CONTROL, 0); | ||
2621 | } | 2629 | } |
2622 | 2630 | ||
2623 | /* http://bcm-specs.sipsolutions.net/EnableMac */ | 2631 | /* http://bcm-specs.sipsolutions.net/EnableMac */ |
@@ -2689,12 +2697,12 @@ out: | |||
2689 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */ | 2697 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */ |
2690 | void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on) | 2698 | void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on) |
2691 | { | 2699 | { |
2692 | u32 tmslow = ssb_read32(dev->dev, SSB_TMSLOW); | 2700 | u32 tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); |
2693 | if (on) | 2701 | if (on) |
2694 | tmslow |= B43_TMSLOW_MACPHYCLKEN; | 2702 | tmslow |= B43_TMSLOW_MACPHYCLKEN; |
2695 | else | 2703 | else |
2696 | tmslow &= ~B43_TMSLOW_MACPHYCLKEN; | 2704 | tmslow &= ~B43_TMSLOW_MACPHYCLKEN; |
2697 | ssb_write32(dev->dev, SSB_TMSLOW, tmslow); | 2705 | ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); |
2698 | } | 2706 | } |
2699 | 2707 | ||
2700 | static void b43_adjust_opmode(struct b43_wldev *dev) | 2708 | static void b43_adjust_opmode(struct b43_wldev *dev) |
@@ -2733,15 +2741,15 @@ static void b43_adjust_opmode(struct b43_wldev *dev) | |||
2733 | /* Workaround: On old hardware the HW-MAC-address-filter | 2741 | /* Workaround: On old hardware the HW-MAC-address-filter |
2734 | * doesn't work properly, so always run promisc in filter | 2742 | * doesn't work properly, so always run promisc in filter |
2735 | * it in software. */ | 2743 | * it in software. */ |
2736 | if (dev->dev->id.revision <= 4) | 2744 | if (dev->sdev->id.revision <= 4) |
2737 | ctl |= B43_MACCTL_PROMISC; | 2745 | ctl |= B43_MACCTL_PROMISC; |
2738 | 2746 | ||
2739 | b43_write32(dev, B43_MMIO_MACCTL, ctl); | 2747 | b43_write32(dev, B43_MMIO_MACCTL, ctl); |
2740 | 2748 | ||
2741 | cfp_pretbtt = 2; | 2749 | cfp_pretbtt = 2; |
2742 | if ((ctl & B43_MACCTL_INFRA) && !(ctl & B43_MACCTL_AP)) { | 2750 | if ((ctl & B43_MACCTL_INFRA) && !(ctl & B43_MACCTL_AP)) { |
2743 | if (dev->dev->bus->chip_id == 0x4306 && | 2751 | if (dev->sdev->bus->chip_id == 0x4306 && |
2744 | dev->dev->bus->chip_rev == 3) | 2752 | dev->sdev->bus->chip_rev == 3) |
2745 | cfp_pretbtt = 100; | 2753 | cfp_pretbtt = 100; |
2746 | else | 2754 | else |
2747 | cfp_pretbtt = 50; | 2755 | cfp_pretbtt = 50; |
@@ -2899,7 +2907,7 @@ static int b43_chip_init(struct b43_wldev *dev) | |||
2899 | b43_write16(dev, 0x005E, value16); | 2907 | b43_write16(dev, 0x005E, value16); |
2900 | } | 2908 | } |
2901 | b43_write32(dev, 0x0100, 0x01000000); | 2909 | b43_write32(dev, 0x0100, 0x01000000); |
2902 | if (dev->dev->id.revision < 5) | 2910 | if (dev->sdev->id.revision < 5) |
2903 | b43_write32(dev, 0x010C, 0x01000000); | 2911 | b43_write32(dev, 0x010C, 0x01000000); |
2904 | 2912 | ||
2905 | b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) | 2913 | b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) |
@@ -2914,7 +2922,7 @@ static int b43_chip_init(struct b43_wldev *dev) | |||
2914 | /* Initially set the wireless operation mode. */ | 2922 | /* Initially set the wireless operation mode. */ |
2915 | b43_adjust_opmode(dev); | 2923 | b43_adjust_opmode(dev); |
2916 | 2924 | ||
2917 | if (dev->dev->id.revision < 3) { | 2925 | if (dev->sdev->id.revision < 3) { |
2918 | b43_write16(dev, 0x060E, 0x0000); | 2926 | b43_write16(dev, 0x060E, 0x0000); |
2919 | b43_write16(dev, 0x0610, 0x8000); | 2927 | b43_write16(dev, 0x0610, 0x8000); |
2920 | b43_write16(dev, 0x0604, 0x0000); | 2928 | b43_write16(dev, 0x0604, 0x0000); |
@@ -2934,7 +2942,7 @@ static int b43_chip_init(struct b43_wldev *dev) | |||
2934 | b43_mac_phy_clock_set(dev, true); | 2942 | b43_mac_phy_clock_set(dev, true); |
2935 | 2943 | ||
2936 | b43_write16(dev, B43_MMIO_POWERUP_DELAY, | 2944 | b43_write16(dev, B43_MMIO_POWERUP_DELAY, |
2937 | dev->dev->bus->chipco.fast_pwrup_delay); | 2945 | dev->sdev->bus->chipco.fast_pwrup_delay); |
2938 | 2946 | ||
2939 | err = 0; | 2947 | err = 0; |
2940 | b43dbg(dev->wl, "Chip initialized\n"); | 2948 | b43dbg(dev->wl, "Chip initialized\n"); |
@@ -3097,7 +3105,7 @@ static int b43_validate_chipaccess(struct b43_wldev *dev) | |||
3097 | b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0); | 3105 | b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0); |
3098 | b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4); | 3106 | b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4); |
3099 | 3107 | ||
3100 | if ((dev->dev->id.revision >= 3) && (dev->dev->id.revision <= 10)) { | 3108 | if ((dev->sdev->id.revision >= 3) && (dev->sdev->id.revision <= 10)) { |
3101 | /* The 32bit register shadows the two 16bit registers | 3109 | /* The 32bit register shadows the two 16bit registers |
3102 | * with update sideeffects. Validate this. */ | 3110 | * with update sideeffects. Validate this. */ |
3103 | b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA); | 3111 | b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA); |
@@ -3450,7 +3458,7 @@ static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf) | |||
3450 | 3458 | ||
3451 | static void b43_put_phy_into_reset(struct b43_wldev *dev) | 3459 | static void b43_put_phy_into_reset(struct b43_wldev *dev) |
3452 | { | 3460 | { |
3453 | struct ssb_device *sdev = dev->dev; | 3461 | struct ssb_device *sdev = dev->sdev; |
3454 | u32 tmslow; | 3462 | u32 tmslow; |
3455 | 3463 | ||
3456 | tmslow = ssb_read32(sdev, SSB_TMSLOW); | 3464 | tmslow = ssb_read32(sdev, SSB_TMSLOW); |
@@ -3946,7 +3954,7 @@ redo: | |||
3946 | 3954 | ||
3947 | /* Disable interrupts on the device. */ | 3955 | /* Disable interrupts on the device. */ |
3948 | b43_set_status(dev, B43_STAT_INITIALIZED); | 3956 | b43_set_status(dev, B43_STAT_INITIALIZED); |
3949 | if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) { | 3957 | if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { |
3950 | /* wl->mutex is locked. That is enough. */ | 3958 | /* wl->mutex is locked. That is enough. */ |
3951 | b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); | 3959 | b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); |
3952 | b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */ | 3960 | b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */ |
@@ -3959,11 +3967,11 @@ redo: | |||
3959 | /* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */ | 3967 | /* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */ |
3960 | orig_dev = dev; | 3968 | orig_dev = dev; |
3961 | mutex_unlock(&wl->mutex); | 3969 | mutex_unlock(&wl->mutex); |
3962 | if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) { | 3970 | if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { |
3963 | b43_sdio_free_irq(dev); | 3971 | b43_sdio_free_irq(dev); |
3964 | } else { | 3972 | } else { |
3965 | synchronize_irq(dev->dev->irq); | 3973 | synchronize_irq(dev->sdev->irq); |
3966 | free_irq(dev->dev->irq, dev); | 3974 | free_irq(dev->sdev->irq, dev); |
3967 | } | 3975 | } |
3968 | mutex_lock(&wl->mutex); | 3976 | mutex_lock(&wl->mutex); |
3969 | dev = wl->current_dev; | 3977 | dev = wl->current_dev; |
@@ -3996,18 +4004,19 @@ static int b43_wireless_core_start(struct b43_wldev *dev) | |||
3996 | B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED); | 4004 | B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED); |
3997 | 4005 | ||
3998 | drain_txstatus_queue(dev); | 4006 | drain_txstatus_queue(dev); |
3999 | if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) { | 4007 | if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { |
4000 | err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler); | 4008 | err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler); |
4001 | if (err) { | 4009 | if (err) { |
4002 | b43err(dev->wl, "Cannot request SDIO IRQ\n"); | 4010 | b43err(dev->wl, "Cannot request SDIO IRQ\n"); |
4003 | goto out; | 4011 | goto out; |
4004 | } | 4012 | } |
4005 | } else { | 4013 | } else { |
4006 | err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler, | 4014 | err = request_threaded_irq(dev->sdev->irq, b43_interrupt_handler, |
4007 | b43_interrupt_thread_handler, | 4015 | b43_interrupt_thread_handler, |
4008 | IRQF_SHARED, KBUILD_MODNAME, dev); | 4016 | IRQF_SHARED, KBUILD_MODNAME, dev); |
4009 | if (err) { | 4017 | if (err) { |
4010 | b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq); | 4018 | b43err(dev->wl, "Cannot request IRQ-%d\n", |
4019 | dev->sdev->irq); | ||
4011 | goto out; | 4020 | goto out; |
4012 | } | 4021 | } |
4013 | } | 4022 | } |
@@ -4087,10 +4096,10 @@ static int b43_phy_versioning(struct b43_wldev *dev) | |||
4087 | analog_type, phy_type, phy_rev); | 4096 | analog_type, phy_type, phy_rev); |
4088 | 4097 | ||
4089 | /* Get RADIO versioning */ | 4098 | /* Get RADIO versioning */ |
4090 | if (dev->dev->bus->chip_id == 0x4317) { | 4099 | if (dev->sdev->bus->chip_id == 0x4317) { |
4091 | if (dev->dev->bus->chip_rev == 0) | 4100 | if (dev->sdev->bus->chip_rev == 0) |
4092 | tmp = 0x3205017F; | 4101 | tmp = 0x3205017F; |
4093 | else if (dev->dev->bus->chip_rev == 1) | 4102 | else if (dev->sdev->bus->chip_rev == 1) |
4094 | tmp = 0x4205017F; | 4103 | tmp = 0x4205017F; |
4095 | else | 4104 | else |
4096 | tmp = 0x5205017F; | 4105 | tmp = 0x5205017F; |
@@ -4195,7 +4204,7 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev) | |||
4195 | 4204 | ||
4196 | static void b43_bluetooth_coext_enable(struct b43_wldev *dev) | 4205 | static void b43_bluetooth_coext_enable(struct b43_wldev *dev) |
4197 | { | 4206 | { |
4198 | struct ssb_sprom *sprom = &dev->dev->bus->sprom; | 4207 | struct ssb_sprom *sprom = &dev->sdev->bus->sprom; |
4199 | u64 hf; | 4208 | u64 hf; |
4200 | 4209 | ||
4201 | if (!modparam_btcoex) | 4210 | if (!modparam_btcoex) |
@@ -4222,16 +4231,16 @@ static void b43_bluetooth_coext_disable(struct b43_wldev *dev) | |||
4222 | 4231 | ||
4223 | static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev) | 4232 | static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev) |
4224 | { | 4233 | { |
4225 | struct ssb_bus *bus = dev->dev->bus; | 4234 | struct ssb_bus *bus = dev->sdev->bus; |
4226 | u32 tmp; | 4235 | u32 tmp; |
4227 | 4236 | ||
4228 | if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) || | 4237 | if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) || |
4229 | (bus->chip_id == 0x4312)) { | 4238 | (bus->chip_id == 0x4312)) { |
4230 | tmp = ssb_read32(dev->dev, SSB_IMCFGLO); | 4239 | tmp = ssb_read32(dev->sdev, SSB_IMCFGLO); |
4231 | tmp &= ~SSB_IMCFGLO_REQTO; | 4240 | tmp &= ~SSB_IMCFGLO_REQTO; |
4232 | tmp &= ~SSB_IMCFGLO_SERTO; | 4241 | tmp &= ~SSB_IMCFGLO_SERTO; |
4233 | tmp |= 0x3; | 4242 | tmp |= 0x3; |
4234 | ssb_write32(dev->dev, SSB_IMCFGLO, tmp); | 4243 | ssb_write32(dev->sdev, SSB_IMCFGLO, tmp); |
4235 | ssb_commit_settings(bus); | 4244 | ssb_commit_settings(bus); |
4236 | } | 4245 | } |
4237 | } | 4246 | } |
@@ -4301,14 +4310,14 @@ static void b43_wireless_core_exit(struct b43_wldev *dev) | |||
4301 | dev->wl->current_beacon = NULL; | 4310 | dev->wl->current_beacon = NULL; |
4302 | } | 4311 | } |
4303 | 4312 | ||
4304 | ssb_device_disable(dev->dev, 0); | 4313 | ssb_device_disable(dev->sdev, 0); |
4305 | ssb_bus_may_powerdown(dev->dev->bus); | 4314 | ssb_bus_may_powerdown(dev->sdev->bus); |
4306 | } | 4315 | } |
4307 | 4316 | ||
4308 | /* Initialize a wireless core */ | 4317 | /* Initialize a wireless core */ |
4309 | static int b43_wireless_core_init(struct b43_wldev *dev) | 4318 | static int b43_wireless_core_init(struct b43_wldev *dev) |
4310 | { | 4319 | { |
4311 | struct ssb_bus *bus = dev->dev->bus; | 4320 | struct ssb_bus *bus = dev->sdev->bus; |
4312 | struct ssb_sprom *sprom = &bus->sprom; | 4321 | struct ssb_sprom *sprom = &bus->sprom; |
4313 | struct b43_phy *phy = &dev->phy; | 4322 | struct b43_phy *phy = &dev->phy; |
4314 | int err; | 4323 | int err; |
@@ -4320,7 +4329,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | |||
4320 | err = ssb_bus_powerup(bus, 0); | 4329 | err = ssb_bus_powerup(bus, 0); |
4321 | if (err) | 4330 | if (err) |
4322 | goto out; | 4331 | goto out; |
4323 | if (!ssb_device_is_enabled(dev->dev)) { | 4332 | if (!ssb_device_is_enabled(dev->sdev)) { |
4324 | tmp = phy->gmode ? B43_TMSLOW_GMODE : 0; | 4333 | tmp = phy->gmode ? B43_TMSLOW_GMODE : 0; |
4325 | b43_wireless_core_reset(dev, tmp); | 4334 | b43_wireless_core_reset(dev, tmp); |
4326 | } | 4335 | } |
@@ -4330,7 +4339,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | |||
4330 | phy->ops->prepare_structs(dev); | 4339 | phy->ops->prepare_structs(dev); |
4331 | 4340 | ||
4332 | /* Enable IRQ routing to this device. */ | 4341 | /* Enable IRQ routing to this device. */ |
4333 | ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev); | 4342 | ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->sdev); |
4334 | 4343 | ||
4335 | b43_imcfglo_timeouts_workaround(dev); | 4344 | b43_imcfglo_timeouts_workaround(dev); |
4336 | b43_bluetooth_coext_disable(dev); | 4345 | b43_bluetooth_coext_disable(dev); |
@@ -4343,7 +4352,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | |||
4343 | if (err) | 4352 | if (err) |
4344 | goto err_busdown; | 4353 | goto err_busdown; |
4345 | b43_shm_write16(dev, B43_SHM_SHARED, | 4354 | b43_shm_write16(dev, B43_SHM_SHARED, |
4346 | B43_SHM_SH_WLCOREREV, dev->dev->id.revision); | 4355 | B43_SHM_SH_WLCOREREV, dev->sdev->id.revision); |
4347 | hf = b43_hf_read(dev); | 4356 | hf = b43_hf_read(dev); |
4348 | if (phy->type == B43_PHYTYPE_G) { | 4357 | if (phy->type == B43_PHYTYPE_G) { |
4349 | hf |= B43_HF_SYMW; | 4358 | hf |= B43_HF_SYMW; |
@@ -4390,8 +4399,8 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | |||
4390 | /* Maximum Contention Window */ | 4399 | /* Maximum Contention Window */ |
4391 | b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); | 4400 | b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); |
4392 | 4401 | ||
4393 | if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) || | 4402 | if ((dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA) || |
4394 | (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) || | 4403 | (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) || |
4395 | dev->use_pio) { | 4404 | dev->use_pio) { |
4396 | dev->__using_pio_transfers = 1; | 4405 | dev->__using_pio_transfers = 1; |
4397 | err = b43_pio_init(dev); | 4406 | err = b43_pio_init(dev); |
@@ -4728,7 +4737,7 @@ static void b43_wireless_core_detach(struct b43_wldev *dev) | |||
4728 | static int b43_wireless_core_attach(struct b43_wldev *dev) | 4737 | static int b43_wireless_core_attach(struct b43_wldev *dev) |
4729 | { | 4738 | { |
4730 | struct b43_wl *wl = dev->wl; | 4739 | struct b43_wl *wl = dev->wl; |
4731 | struct ssb_bus *bus = dev->dev->bus; | 4740 | struct ssb_bus *bus = dev->sdev->bus; |
4732 | struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL; | 4741 | struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL; |
4733 | int err; | 4742 | int err; |
4734 | bool have_2ghz_phy = 0, have_5ghz_phy = 0; | 4743 | bool have_2ghz_phy = 0, have_5ghz_phy = 0; |
@@ -4747,10 +4756,10 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
4747 | goto out; | 4756 | goto out; |
4748 | } | 4757 | } |
4749 | /* Get the PHY type. */ | 4758 | /* Get the PHY type. */ |
4750 | if (dev->dev->id.revision >= 5) { | 4759 | if (dev->sdev->id.revision >= 5) { |
4751 | u32 tmshigh; | 4760 | u32 tmshigh; |
4752 | 4761 | ||
4753 | tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH); | 4762 | tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); |
4754 | have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY); | 4763 | have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY); |
4755 | have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY); | 4764 | have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY); |
4756 | } else | 4765 | } else |
@@ -4823,7 +4832,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
4823 | INIT_WORK(&dev->restart_work, b43_chip_reset); | 4832 | INIT_WORK(&dev->restart_work, b43_chip_reset); |
4824 | 4833 | ||
4825 | dev->phy.ops->switch_analog(dev, 0); | 4834 | dev->phy.ops->switch_analog(dev, 0); |
4826 | ssb_device_disable(dev->dev, 0); | 4835 | ssb_device_disable(dev->sdev, 0); |
4827 | ssb_bus_may_powerdown(bus); | 4836 | ssb_bus_may_powerdown(bus); |
4828 | 4837 | ||
4829 | out: | 4838 | out: |
@@ -4864,7 +4873,7 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) | |||
4864 | goto out; | 4873 | goto out; |
4865 | 4874 | ||
4866 | wldev->use_pio = b43_modparam_pio; | 4875 | wldev->use_pio = b43_modparam_pio; |
4867 | wldev->dev = dev; | 4876 | wldev->sdev = dev; |
4868 | wldev->wl = wl; | 4877 | wldev->wl = wl; |
4869 | b43_set_status(wldev, B43_STAT_UNINIT); | 4878 | b43_set_status(wldev, B43_STAT_UNINIT); |
4870 | wldev->bad_frames_preempt = modparam_bad_frames_preempt; | 4879 | wldev->bad_frames_preempt = modparam_bad_frames_preempt; |
@@ -4925,19 +4934,16 @@ static void b43_wireless_exit(struct ssb_device *dev, struct b43_wl *wl) | |||
4925 | ieee80211_free_hw(hw); | 4934 | ieee80211_free_hw(hw); |
4926 | } | 4935 | } |
4927 | 4936 | ||
4928 | static int b43_wireless_init(struct ssb_device *dev) | 4937 | static struct b43_wl *b43_wireless_init(struct ssb_device *dev) |
4929 | { | 4938 | { |
4930 | struct ssb_sprom *sprom = &dev->bus->sprom; | 4939 | struct ssb_sprom *sprom = &dev->bus->sprom; |
4931 | struct ieee80211_hw *hw; | 4940 | struct ieee80211_hw *hw; |
4932 | struct b43_wl *wl; | 4941 | struct b43_wl *wl; |
4933 | int err = -ENOMEM; | ||
4934 | |||
4935 | b43_sprom_fixup(dev->bus); | ||
4936 | 4942 | ||
4937 | hw = ieee80211_alloc_hw(sizeof(*wl), &b43_hw_ops); | 4943 | hw = ieee80211_alloc_hw(sizeof(*wl), &b43_hw_ops); |
4938 | if (!hw) { | 4944 | if (!hw) { |
4939 | b43err(NULL, "Could not allocate ieee80211 device\n"); | 4945 | b43err(NULL, "Could not allocate ieee80211 device\n"); |
4940 | goto out; | 4946 | return ERR_PTR(-ENOMEM); |
4941 | } | 4947 | } |
4942 | wl = hw_to_b43_wl(hw); | 4948 | wl = hw_to_b43_wl(hw); |
4943 | 4949 | ||
@@ -4971,12 +4977,9 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4971 | INIT_WORK(&wl->tx_work, b43_tx_work); | 4977 | INIT_WORK(&wl->tx_work, b43_tx_work); |
4972 | skb_queue_head_init(&wl->tx_queue); | 4978 | skb_queue_head_init(&wl->tx_queue); |
4973 | 4979 | ||
4974 | ssb_set_devtypedata(dev, wl); | ||
4975 | b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n", | 4980 | b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n", |
4976 | dev->bus->chip_id, dev->id.revision); | 4981 | dev->bus->chip_id, dev->id.revision); |
4977 | err = 0; | 4982 | return wl; |
4978 | out: | ||
4979 | return err; | ||
4980 | } | 4983 | } |
4981 | 4984 | ||
4982 | static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id) | 4985 | static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id) |
@@ -4989,11 +4992,14 @@ static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id) | |||
4989 | if (!wl) { | 4992 | if (!wl) { |
4990 | /* Probing the first core. Must setup common struct b43_wl */ | 4993 | /* Probing the first core. Must setup common struct b43_wl */ |
4991 | first = 1; | 4994 | first = 1; |
4992 | err = b43_wireless_init(dev); | 4995 | b43_sprom_fixup(dev->bus); |
4993 | if (err) | 4996 | wl = b43_wireless_init(dev); |
4997 | if (IS_ERR(wl)) { | ||
4998 | err = PTR_ERR(wl); | ||
4994 | goto out; | 4999 | goto out; |
4995 | wl = ssb_get_devtypedata(dev); | 5000 | } |
4996 | B43_WARN_ON(!wl); | 5001 | ssb_set_devtypedata(dev, wl); |
5002 | B43_WARN_ON(ssb_get_devtypedata(dev) != wl); | ||
4997 | } | 5003 | } |
4998 | err = b43_one_core_attach(dev, wl); | 5004 | err = b43_one_core_attach(dev, wl); |
4999 | if (err) | 5005 | if (err) |
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c index b6428ec16dd6..b01c8ced57c3 100644 --- a/drivers/net/wireless/b43/phy_a.c +++ b/drivers/net/wireless/b43/phy_a.c | |||
@@ -265,7 +265,7 @@ static void hardware_pctl_init_aphy(struct b43_wldev *dev) | |||
265 | 265 | ||
266 | void b43_phy_inita(struct b43_wldev *dev) | 266 | void b43_phy_inita(struct b43_wldev *dev) |
267 | { | 267 | { |
268 | struct ssb_bus *bus = dev->dev->bus; | 268 | struct ssb_bus *bus = dev->sdev->bus; |
269 | struct b43_phy *phy = &dev->phy; | 269 | struct b43_phy *phy = &dev->phy; |
270 | 270 | ||
271 | /* This lowlevel A-PHY init is also called from G-PHY init. | 271 | /* This lowlevel A-PHY init is also called from G-PHY init. |
@@ -311,7 +311,7 @@ void b43_phy_inita(struct b43_wldev *dev) | |||
311 | } | 311 | } |
312 | 312 | ||
313 | if ((phy->type == B43_PHYTYPE_G) && | 313 | if ((phy->type == B43_PHYTYPE_G) && |
314 | (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) { | 314 | (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) { |
315 | b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF); | 315 | b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF); |
316 | } | 316 | } |
317 | } | 317 | } |
@@ -323,17 +323,17 @@ static int b43_aphy_init_tssi2dbm_table(struct b43_wldev *dev) | |||
323 | struct b43_phy_a *aphy = phy->a; | 323 | struct b43_phy_a *aphy = phy->a; |
324 | s16 pab0, pab1, pab2; | 324 | s16 pab0, pab1, pab2; |
325 | 325 | ||
326 | pab0 = (s16) (dev->dev->bus->sprom.pa1b0); | 326 | pab0 = (s16) (dev->sdev->bus->sprom.pa1b0); |
327 | pab1 = (s16) (dev->dev->bus->sprom.pa1b1); | 327 | pab1 = (s16) (dev->sdev->bus->sprom.pa1b1); |
328 | pab2 = (s16) (dev->dev->bus->sprom.pa1b2); | 328 | pab2 = (s16) (dev->sdev->bus->sprom.pa1b2); |
329 | 329 | ||
330 | if (pab0 != 0 && pab1 != 0 && pab2 != 0 && | 330 | if (pab0 != 0 && pab1 != 0 && pab2 != 0 && |
331 | pab0 != -1 && pab1 != -1 && pab2 != -1) { | 331 | pab0 != -1 && pab1 != -1 && pab2 != -1) { |
332 | /* The pabX values are set in SPROM. Use them. */ | 332 | /* The pabX values are set in SPROM. Use them. */ |
333 | if ((s8) dev->dev->bus->sprom.itssi_a != 0 && | 333 | if ((s8) dev->sdev->bus->sprom.itssi_a != 0 && |
334 | (s8) dev->dev->bus->sprom.itssi_a != -1) | 334 | (s8) dev->sdev->bus->sprom.itssi_a != -1) |
335 | aphy->tgt_idle_tssi = | 335 | aphy->tgt_idle_tssi = |
336 | (s8) (dev->dev->bus->sprom.itssi_a); | 336 | (s8) (dev->sdev->bus->sprom.itssi_a); |
337 | else | 337 | else |
338 | aphy->tgt_idle_tssi = 62; | 338 | aphy->tgt_idle_tssi = 62; |
339 | aphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0, | 339 | aphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0, |
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index b5c5ce94d3fd..e46b2f4f0920 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c | |||
@@ -168,7 +168,7 @@ void b43_phy_lock(struct b43_wldev *dev) | |||
168 | B43_WARN_ON(dev->phy.phy_locked); | 168 | B43_WARN_ON(dev->phy.phy_locked); |
169 | dev->phy.phy_locked = 1; | 169 | dev->phy.phy_locked = 1; |
170 | #endif | 170 | #endif |
171 | B43_WARN_ON(dev->dev->id.revision < 3); | 171 | B43_WARN_ON(dev->sdev->id.revision < 3); |
172 | 172 | ||
173 | if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) | 173 | if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) |
174 | b43_power_saving_ctl_bits(dev, B43_PS_AWAKE); | 174 | b43_power_saving_ctl_bits(dev, B43_PS_AWAKE); |
@@ -180,7 +180,7 @@ void b43_phy_unlock(struct b43_wldev *dev) | |||
180 | B43_WARN_ON(!dev->phy.phy_locked); | 180 | B43_WARN_ON(!dev->phy.phy_locked); |
181 | dev->phy.phy_locked = 0; | 181 | dev->phy.phy_locked = 0; |
182 | #endif | 182 | #endif |
183 | B43_WARN_ON(dev->dev->id.revision < 3); | 183 | B43_WARN_ON(dev->sdev->id.revision < 3); |
184 | 184 | ||
185 | if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) | 185 | if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) |
186 | b43_power_saving_ctl_bits(dev, 0); | 186 | b43_power_saving_ctl_bits(dev, 0); |
@@ -368,8 +368,8 @@ void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags) | |||
368 | /* The next check will be needed in two seconds, or later. */ | 368 | /* The next check will be needed in two seconds, or later. */ |
369 | phy->next_txpwr_check_time = round_jiffies(now + (HZ * 2)); | 369 | phy->next_txpwr_check_time = round_jiffies(now + (HZ * 2)); |
370 | 370 | ||
371 | if ((dev->dev->bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && | 371 | if ((dev->sdev->bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && |
372 | (dev->dev->bus->boardinfo.type == SSB_BOARD_BU4306)) | 372 | (dev->sdev->bus->boardinfo.type == SSB_BOARD_BU4306)) |
373 | return; /* No software txpower adjustment needed */ | 373 | return; /* No software txpower adjustment needed */ |
374 | 374 | ||
375 | result = phy->ops->recalc_txpower(dev, !!(flags & B43_TXPWR_IGNORE_TSSI)); | 375 | result = phy->ops->recalc_txpower(dev, !!(flags & B43_TXPWR_IGNORE_TSSI)); |
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c index be4828167012..1758a282f913 100644 --- a/drivers/net/wireless/b43/phy_g.c +++ b/drivers/net/wireless/b43/phy_g.c | |||
@@ -718,7 +718,7 @@ static void b43_calc_nrssi_threshold(struct b43_wldev *dev) | |||
718 | B43_WARN_ON(phy->type != B43_PHYTYPE_G); | 718 | B43_WARN_ON(phy->type != B43_PHYTYPE_G); |
719 | 719 | ||
720 | if (!phy->gmode || | 720 | if (!phy->gmode || |
721 | !(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { | 721 | !(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { |
722 | tmp16 = b43_nrssi_hw_read(dev, 0x20); | 722 | tmp16 = b43_nrssi_hw_read(dev, 0x20); |
723 | if (tmp16 >= 0x20) | 723 | if (tmp16 >= 0x20) |
724 | tmp16 -= 0x40; | 724 | tmp16 -= 0x40; |
@@ -1114,7 +1114,7 @@ static u16 radio2050_rfover_val(struct b43_wldev *dev, | |||
1114 | { | 1114 | { |
1115 | struct b43_phy *phy = &dev->phy; | 1115 | struct b43_phy *phy = &dev->phy; |
1116 | struct b43_phy_g *gphy = phy->g; | 1116 | struct b43_phy_g *gphy = phy->g; |
1117 | struct ssb_sprom *sprom = &(dev->dev->bus->sprom); | 1117 | struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); |
1118 | 1118 | ||
1119 | if (!phy->gmode) | 1119 | if (!phy->gmode) |
1120 | return 0; | 1120 | return 0; |
@@ -1491,7 +1491,7 @@ static u16 b43_radio_init2050(struct b43_wldev *dev) | |||
1491 | 1491 | ||
1492 | static void b43_phy_initb5(struct b43_wldev *dev) | 1492 | static void b43_phy_initb5(struct b43_wldev *dev) |
1493 | { | 1493 | { |
1494 | struct ssb_bus *bus = dev->dev->bus; | 1494 | struct ssb_bus *bus = dev->sdev->bus; |
1495 | struct b43_phy *phy = &dev->phy; | 1495 | struct b43_phy *phy = &dev->phy; |
1496 | struct b43_phy_g *gphy = phy->g; | 1496 | struct b43_phy_g *gphy = phy->g; |
1497 | u16 offset, value; | 1497 | u16 offset, value; |
@@ -1620,7 +1620,7 @@ static void b43_phy_initb6(struct b43_wldev *dev) | |||
1620 | b43_radio_write16(dev, 0x5A, 0x88); | 1620 | b43_radio_write16(dev, 0x5A, 0x88); |
1621 | b43_radio_write16(dev, 0x5B, 0x6B); | 1621 | b43_radio_write16(dev, 0x5B, 0x6B); |
1622 | b43_radio_write16(dev, 0x5C, 0x0F); | 1622 | b43_radio_write16(dev, 0x5C, 0x0F); |
1623 | if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) { | 1623 | if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) { |
1624 | b43_radio_write16(dev, 0x5D, 0xFA); | 1624 | b43_radio_write16(dev, 0x5D, 0xFA); |
1625 | b43_radio_write16(dev, 0x5E, 0xD8); | 1625 | b43_radio_write16(dev, 0x5E, 0xD8); |
1626 | } else { | 1626 | } else { |
@@ -1787,7 +1787,7 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev) | |||
1787 | b43_phy_set(dev, B43_PHY_RFOVER, 0x0100); | 1787 | b43_phy_set(dev, B43_PHY_RFOVER, 0x0100); |
1788 | b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xCFFF); | 1788 | b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xCFFF); |
1789 | 1789 | ||
1790 | if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) { | 1790 | if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) { |
1791 | if (phy->rev >= 7) { | 1791 | if (phy->rev >= 7) { |
1792 | b43_phy_set(dev, B43_PHY_RFOVER, 0x0800); | 1792 | b43_phy_set(dev, B43_PHY_RFOVER, 0x0800); |
1793 | b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x8000); | 1793 | b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x8000); |
@@ -1922,7 +1922,7 @@ static void b43_hardware_pctl_init_gphy(struct b43_wldev *dev) | |||
1922 | /* Initialize B/G PHY power control */ | 1922 | /* Initialize B/G PHY power control */ |
1923 | static void b43_phy_init_pctl(struct b43_wldev *dev) | 1923 | static void b43_phy_init_pctl(struct b43_wldev *dev) |
1924 | { | 1924 | { |
1925 | struct ssb_bus *bus = dev->dev->bus; | 1925 | struct ssb_bus *bus = dev->sdev->bus; |
1926 | struct b43_phy *phy = &dev->phy; | 1926 | struct b43_phy *phy = &dev->phy; |
1927 | struct b43_phy_g *gphy = phy->g; | 1927 | struct b43_phy_g *gphy = phy->g; |
1928 | struct b43_rfatt old_rfatt; | 1928 | struct b43_rfatt old_rfatt; |
@@ -2053,7 +2053,7 @@ static void b43_phy_initg(struct b43_wldev *dev) | |||
2053 | if (phy->rev >= 6) { | 2053 | if (phy->rev >= 6) { |
2054 | b43_phy_maskset(dev, B43_PHY_CCK(0x36), 0x0FFF, (gphy->lo_control->tx_bias << 12)); | 2054 | b43_phy_maskset(dev, B43_PHY_CCK(0x36), 0x0FFF, (gphy->lo_control->tx_bias << 12)); |
2055 | } | 2055 | } |
2056 | if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) | 2056 | if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) |
2057 | b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075); | 2057 | b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075); |
2058 | else | 2058 | else |
2059 | b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F); | 2059 | b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F); |
@@ -2066,7 +2066,7 @@ static void b43_phy_initg(struct b43_wldev *dev) | |||
2066 | b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078); | 2066 | b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078); |
2067 | } | 2067 | } |
2068 | 2068 | ||
2069 | if (!(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { | 2069 | if (!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { |
2070 | /* The specs state to update the NRSSI LT with | 2070 | /* The specs state to update the NRSSI LT with |
2071 | * the value 0x7FFFFFFF here. I think that is some weird | 2071 | * the value 0x7FFFFFFF here. I think that is some weird |
2072 | * compiler optimization in the original driver. | 2072 | * compiler optimization in the original driver. |
@@ -2088,8 +2088,8 @@ static void b43_phy_initg(struct b43_wldev *dev) | |||
2088 | /* FIXME: The spec says in the following if, the 0 should be replaced | 2088 | /* FIXME: The spec says in the following if, the 0 should be replaced |
2089 | 'if OFDM may not be used in the current locale' | 2089 | 'if OFDM may not be used in the current locale' |
2090 | but OFDM is legal everywhere */ | 2090 | but OFDM is legal everywhere */ |
2091 | if ((dev->dev->bus->chip_id == 0x4306 | 2091 | if ((dev->sdev->bus->chip_id == 0x4306 |
2092 | && dev->dev->bus->chip_package == 2) || 0) { | 2092 | && dev->sdev->bus->chip_package == 2) || 0) { |
2093 | b43_phy_mask(dev, B43_PHY_CRS0, 0xBFFF); | 2093 | b43_phy_mask(dev, B43_PHY_CRS0, 0xBFFF); |
2094 | b43_phy_mask(dev, B43_PHY_OFDM(0xC3), 0x7FFF); | 2094 | b43_phy_mask(dev, B43_PHY_OFDM(0xC3), 0x7FFF); |
2095 | } | 2095 | } |
@@ -2105,7 +2105,7 @@ void b43_gphy_channel_switch(struct b43_wldev *dev, | |||
2105 | b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel)); | 2105 | b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel)); |
2106 | 2106 | ||
2107 | if (channel == 14) { | 2107 | if (channel == 14) { |
2108 | if (dev->dev->bus->sprom.country_code == | 2108 | if (dev->sdev->bus->sprom.country_code == |
2109 | SSB_SPROM1CCODE_JAPAN) | 2109 | SSB_SPROM1CCODE_JAPAN) |
2110 | b43_hf_write(dev, | 2110 | b43_hf_write(dev, |
2111 | b43_hf_read(dev) & ~B43_HF_ACPR); | 2111 | b43_hf_read(dev) & ~B43_HF_ACPR); |
@@ -2136,7 +2136,7 @@ static void default_baseband_attenuation(struct b43_wldev *dev, | |||
2136 | static void default_radio_attenuation(struct b43_wldev *dev, | 2136 | static void default_radio_attenuation(struct b43_wldev *dev, |
2137 | struct b43_rfatt *rf) | 2137 | struct b43_rfatt *rf) |
2138 | { | 2138 | { |
2139 | struct ssb_bus *bus = dev->dev->bus; | 2139 | struct ssb_bus *bus = dev->sdev->bus; |
2140 | struct b43_phy *phy = &dev->phy; | 2140 | struct b43_phy *phy = &dev->phy; |
2141 | 2141 | ||
2142 | rf->with_padmix = 0; | 2142 | rf->with_padmix = 0; |
@@ -2384,11 +2384,11 @@ static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev) | |||
2384 | struct b43_phy_g *gphy = phy->g; | 2384 | struct b43_phy_g *gphy = phy->g; |
2385 | s16 pab0, pab1, pab2; | 2385 | s16 pab0, pab1, pab2; |
2386 | 2386 | ||
2387 | pab0 = (s16) (dev->dev->bus->sprom.pa0b0); | 2387 | pab0 = (s16) (dev->sdev->bus->sprom.pa0b0); |
2388 | pab1 = (s16) (dev->dev->bus->sprom.pa0b1); | 2388 | pab1 = (s16) (dev->sdev->bus->sprom.pa0b1); |
2389 | pab2 = (s16) (dev->dev->bus->sprom.pa0b2); | 2389 | pab2 = (s16) (dev->sdev->bus->sprom.pa0b2); |
2390 | 2390 | ||
2391 | B43_WARN_ON((dev->dev->bus->chip_id == 0x4301) && | 2391 | B43_WARN_ON((dev->sdev->bus->chip_id == 0x4301) && |
2392 | (phy->radio_ver != 0x2050)); /* Not supported anymore */ | 2392 | (phy->radio_ver != 0x2050)); /* Not supported anymore */ |
2393 | 2393 | ||
2394 | gphy->dyn_tssi_tbl = 0; | 2394 | gphy->dyn_tssi_tbl = 0; |
@@ -2396,10 +2396,10 @@ static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev) | |||
2396 | if (pab0 != 0 && pab1 != 0 && pab2 != 0 && | 2396 | if (pab0 != 0 && pab1 != 0 && pab2 != 0 && |
2397 | pab0 != -1 && pab1 != -1 && pab2 != -1) { | 2397 | pab0 != -1 && pab1 != -1 && pab2 != -1) { |
2398 | /* The pabX values are set in SPROM. Use them. */ | 2398 | /* The pabX values are set in SPROM. Use them. */ |
2399 | if ((s8) dev->dev->bus->sprom.itssi_bg != 0 && | 2399 | if ((s8) dev->sdev->bus->sprom.itssi_bg != 0 && |
2400 | (s8) dev->dev->bus->sprom.itssi_bg != -1) { | 2400 | (s8) dev->sdev->bus->sprom.itssi_bg != -1) { |
2401 | gphy->tgt_idle_tssi = | 2401 | gphy->tgt_idle_tssi = |
2402 | (s8) (dev->dev->bus->sprom.itssi_bg); | 2402 | (s8) (dev->sdev->bus->sprom.itssi_bg); |
2403 | } else | 2403 | } else |
2404 | gphy->tgt_idle_tssi = 62; | 2404 | gphy->tgt_idle_tssi = 62; |
2405 | gphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0, | 2405 | gphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0, |
@@ -2840,7 +2840,7 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev) | |||
2840 | B43_TXCTL_TXMIX; | 2840 | B43_TXCTL_TXMIX; |
2841 | rfatt += 2; | 2841 | rfatt += 2; |
2842 | bbatt += 2; | 2842 | bbatt += 2; |
2843 | } else if (dev->dev->bus->sprom. | 2843 | } else if (dev->sdev->bus->sprom. |
2844 | boardflags_lo & | 2844 | boardflags_lo & |
2845 | B43_BFL_PACTRL) { | 2845 | B43_BFL_PACTRL) { |
2846 | bbatt += 4 * (rfatt - 2); | 2846 | bbatt += 4 * (rfatt - 2); |
@@ -2914,14 +2914,14 @@ static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev, | |||
2914 | estimated_pwr = b43_gphy_estimate_power_out(dev, average_tssi); | 2914 | estimated_pwr = b43_gphy_estimate_power_out(dev, average_tssi); |
2915 | 2915 | ||
2916 | B43_WARN_ON(phy->type != B43_PHYTYPE_G); | 2916 | B43_WARN_ON(phy->type != B43_PHYTYPE_G); |
2917 | max_pwr = dev->dev->bus->sprom.maxpwr_bg; | 2917 | max_pwr = dev->sdev->bus->sprom.maxpwr_bg; |
2918 | if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) | 2918 | if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) |
2919 | max_pwr -= 3; /* minus 0.75 */ | 2919 | max_pwr -= 3; /* minus 0.75 */ |
2920 | if (unlikely(max_pwr >= INT_TO_Q52(30/*dBm*/))) { | 2920 | if (unlikely(max_pwr >= INT_TO_Q52(30/*dBm*/))) { |
2921 | b43warn(dev->wl, | 2921 | b43warn(dev->wl, |
2922 | "Invalid max-TX-power value in SPROM.\n"); | 2922 | "Invalid max-TX-power value in SPROM.\n"); |
2923 | max_pwr = INT_TO_Q52(20); /* fake it */ | 2923 | max_pwr = INT_TO_Q52(20); /* fake it */ |
2924 | dev->dev->bus->sprom.maxpwr_bg = max_pwr; | 2924 | dev->sdev->bus->sprom.maxpwr_bg = max_pwr; |
2925 | } | 2925 | } |
2926 | 2926 | ||
2927 | /* Get desired power (in Q5.2) */ | 2927 | /* Get desired power (in Q5.2) */ |
@@ -3014,7 +3014,7 @@ static void b43_gphy_op_pwork_60sec(struct b43_wldev *dev) | |||
3014 | { | 3014 | { |
3015 | struct b43_phy *phy = &dev->phy; | 3015 | struct b43_phy *phy = &dev->phy; |
3016 | 3016 | ||
3017 | if (!(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) | 3017 | if (!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) |
3018 | return; | 3018 | return; |
3019 | 3019 | ||
3020 | b43_mac_suspend(dev); | 3020 | b43_mac_suspend(dev); |
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index fd50eb116243..012c8da2f944 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c | |||
@@ -86,7 +86,7 @@ static void b43_lpphy_op_free(struct b43_wldev *dev) | |||
86 | static void lpphy_read_band_sprom(struct b43_wldev *dev) | 86 | static void lpphy_read_band_sprom(struct b43_wldev *dev) |
87 | { | 87 | { |
88 | struct b43_phy_lp *lpphy = dev->phy.lp; | 88 | struct b43_phy_lp *lpphy = dev->phy.lp; |
89 | struct ssb_bus *bus = dev->dev->bus; | 89 | struct ssb_bus *bus = dev->sdev->bus; |
90 | u16 cckpo, maxpwr; | 90 | u16 cckpo, maxpwr; |
91 | u32 ofdmpo; | 91 | u32 ofdmpo; |
92 | int i; | 92 | int i; |
@@ -214,7 +214,7 @@ static void lpphy_table_init(struct b43_wldev *dev) | |||
214 | 214 | ||
215 | static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) | 215 | static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) |
216 | { | 216 | { |
217 | struct ssb_bus *bus = dev->dev->bus; | 217 | struct ssb_bus *bus = dev->sdev->bus; |
218 | struct b43_phy_lp *lpphy = dev->phy.lp; | 218 | struct b43_phy_lp *lpphy = dev->phy.lp; |
219 | u16 tmp, tmp2; | 219 | u16 tmp, tmp2; |
220 | 220 | ||
@@ -412,7 +412,7 @@ static void lpphy_restore_dig_flt_state(struct b43_wldev *dev) | |||
412 | 412 | ||
413 | static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) | 413 | static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) |
414 | { | 414 | { |
415 | struct ssb_bus *bus = dev->dev->bus; | 415 | struct ssb_bus *bus = dev->sdev->bus; |
416 | struct b43_phy_lp *lpphy = dev->phy.lp; | 416 | struct b43_phy_lp *lpphy = dev->phy.lp; |
417 | 417 | ||
418 | b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50); | 418 | b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50); |
@@ -519,7 +519,7 @@ struct b2062_freqdata { | |||
519 | static void lpphy_2062_init(struct b43_wldev *dev) | 519 | static void lpphy_2062_init(struct b43_wldev *dev) |
520 | { | 520 | { |
521 | struct b43_phy_lp *lpphy = dev->phy.lp; | 521 | struct b43_phy_lp *lpphy = dev->phy.lp; |
522 | struct ssb_bus *bus = dev->dev->bus; | 522 | struct ssb_bus *bus = dev->sdev->bus; |
523 | u32 crystalfreq, tmp, ref; | 523 | u32 crystalfreq, tmp, ref; |
524 | unsigned int i; | 524 | unsigned int i; |
525 | const struct b2062_freqdata *fd = NULL; | 525 | const struct b2062_freqdata *fd = NULL; |
@@ -697,7 +697,7 @@ static void lpphy_radio_init(struct b43_wldev *dev) | |||
697 | lpphy_sync_stx(dev); | 697 | lpphy_sync_stx(dev); |
698 | b43_phy_write(dev, B43_PHY_OFDM(0xF0), 0x5F80); | 698 | b43_phy_write(dev, B43_PHY_OFDM(0xF0), 0x5F80); |
699 | b43_phy_write(dev, B43_PHY_OFDM(0xF1), 0); | 699 | b43_phy_write(dev, B43_PHY_OFDM(0xF1), 0); |
700 | if (dev->dev->bus->chip_id == 0x4325) { | 700 | if (dev->sdev->bus->chip_id == 0x4325) { |
701 | // TODO SSB PMU recalibration | 701 | // TODO SSB PMU recalibration |
702 | } | 702 | } |
703 | } | 703 | } |
@@ -1289,7 +1289,7 @@ finish: | |||
1289 | 1289 | ||
1290 | static void lpphy_rev2plus_rc_calib(struct b43_wldev *dev) | 1290 | static void lpphy_rev2plus_rc_calib(struct b43_wldev *dev) |
1291 | { | 1291 | { |
1292 | struct ssb_bus *bus = dev->dev->bus; | 1292 | struct ssb_bus *bus = dev->sdev->bus; |
1293 | u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; | 1293 | u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; |
1294 | u8 tmp = b43_radio_read(dev, B2063_RX_BB_SP8) & 0xFF; | 1294 | u8 tmp = b43_radio_read(dev, B2063_RX_BB_SP8) & 0xFF; |
1295 | int i; | 1295 | int i; |
@@ -1840,7 +1840,7 @@ static void lpphy_papd_cal(struct b43_wldev *dev, struct lpphy_tx_gains gains, | |||
1840 | static void lpphy_papd_cal_txpwr(struct b43_wldev *dev) | 1840 | static void lpphy_papd_cal_txpwr(struct b43_wldev *dev) |
1841 | { | 1841 | { |
1842 | struct b43_phy_lp *lpphy = dev->phy.lp; | 1842 | struct b43_phy_lp *lpphy = dev->phy.lp; |
1843 | struct ssb_bus *bus = dev->dev->bus; | 1843 | struct ssb_bus *bus = dev->sdev->bus; |
1844 | struct lpphy_tx_gains gains, oldgains; | 1844 | struct lpphy_tx_gains gains, oldgains; |
1845 | int old_txpctl, old_afe_ovr, old_rf, old_bbmult; | 1845 | int old_txpctl, old_afe_ovr, old_rf, old_bbmult; |
1846 | 1846 | ||
@@ -1870,7 +1870,7 @@ static int lpphy_rx_iq_cal(struct b43_wldev *dev, bool noise, bool tx, | |||
1870 | bool rx, bool pa, struct lpphy_tx_gains *gains) | 1870 | bool rx, bool pa, struct lpphy_tx_gains *gains) |
1871 | { | 1871 | { |
1872 | struct b43_phy_lp *lpphy = dev->phy.lp; | 1872 | struct b43_phy_lp *lpphy = dev->phy.lp; |
1873 | struct ssb_bus *bus = dev->dev->bus; | 1873 | struct ssb_bus *bus = dev->sdev->bus; |
1874 | const struct lpphy_rx_iq_comp *iqcomp = NULL; | 1874 | const struct lpphy_rx_iq_comp *iqcomp = NULL; |
1875 | struct lpphy_tx_gains nogains, oldgains; | 1875 | struct lpphy_tx_gains nogains, oldgains; |
1876 | u16 tmp; | 1876 | u16 tmp; |
@@ -2408,7 +2408,7 @@ static const struct b206x_channel b2063_chantbl[] = { | |||
2408 | 2408 | ||
2409 | static void lpphy_b2062_reset_pll_bias(struct b43_wldev *dev) | 2409 | static void lpphy_b2062_reset_pll_bias(struct b43_wldev *dev) |
2410 | { | 2410 | { |
2411 | struct ssb_bus *bus = dev->dev->bus; | 2411 | struct ssb_bus *bus = dev->sdev->bus; |
2412 | 2412 | ||
2413 | b43_radio_write(dev, B2062_S_RFPLL_CTL2, 0xFF); | 2413 | b43_radio_write(dev, B2062_S_RFPLL_CTL2, 0xFF); |
2414 | udelay(20); | 2414 | udelay(20); |
@@ -2432,7 +2432,7 @@ static int lpphy_b2062_tune(struct b43_wldev *dev, | |||
2432 | unsigned int channel) | 2432 | unsigned int channel) |
2433 | { | 2433 | { |
2434 | struct b43_phy_lp *lpphy = dev->phy.lp; | 2434 | struct b43_phy_lp *lpphy = dev->phy.lp; |
2435 | struct ssb_bus *bus = dev->dev->bus; | 2435 | struct ssb_bus *bus = dev->sdev->bus; |
2436 | const struct b206x_channel *chandata = NULL; | 2436 | const struct b206x_channel *chandata = NULL; |
2437 | u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; | 2437 | u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; |
2438 | u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; | 2438 | u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; |
@@ -2522,7 +2522,7 @@ static void lpphy_b2063_vco_calib(struct b43_wldev *dev) | |||
2522 | static int lpphy_b2063_tune(struct b43_wldev *dev, | 2522 | static int lpphy_b2063_tune(struct b43_wldev *dev, |
2523 | unsigned int channel) | 2523 | unsigned int channel) |
2524 | { | 2524 | { |
2525 | struct ssb_bus *bus = dev->dev->bus; | 2525 | struct ssb_bus *bus = dev->sdev->bus; |
2526 | 2526 | ||
2527 | static const struct b206x_channel *chandata = NULL; | 2527 | static const struct b206x_channel *chandata = NULL; |
2528 | u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; | 2528 | u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; |
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index b075a3f82a43..9ed65157bef5 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
@@ -299,7 +299,7 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable) | |||
299 | static void b43_nphy_tx_power_fix(struct b43_wldev *dev) | 299 | static void b43_nphy_tx_power_fix(struct b43_wldev *dev) |
300 | { | 300 | { |
301 | struct b43_phy_n *nphy = dev->phy.n; | 301 | struct b43_phy_n *nphy = dev->phy.n; |
302 | struct ssb_sprom *sprom = &(dev->dev->bus->sprom); | 302 | struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); |
303 | 303 | ||
304 | u8 txpi[2], bbmult, i; | 304 | u8 txpi[2], bbmult, i; |
305 | u16 tmp, radio_gain, dac_gain; | 305 | u16 tmp, radio_gain, dac_gain; |
@@ -423,8 +423,8 @@ static void b43_radio_init2055_pre(struct b43_wldev *dev) | |||
423 | static void b43_radio_init2055_post(struct b43_wldev *dev) | 423 | static void b43_radio_init2055_post(struct b43_wldev *dev) |
424 | { | 424 | { |
425 | struct b43_phy_n *nphy = dev->phy.n; | 425 | struct b43_phy_n *nphy = dev->phy.n; |
426 | struct ssb_sprom *sprom = &(dev->dev->bus->sprom); | 426 | struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); |
427 | struct ssb_boardinfo *binfo = &(dev->dev->bus->boardinfo); | 427 | struct ssb_boardinfo *binfo = &(dev->sdev->bus->boardinfo); |
428 | int i; | 428 | int i; |
429 | u16 val; | 429 | u16 val; |
430 | bool workaround = false; | 430 | bool workaround = false; |
@@ -609,12 +609,12 @@ static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force) | |||
609 | if (dev->phy.type != B43_PHYTYPE_N) | 609 | if (dev->phy.type != B43_PHYTYPE_N) |
610 | return; | 610 | return; |
611 | 611 | ||
612 | tmslow = ssb_read32(dev->dev, SSB_TMSLOW); | 612 | tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); |
613 | if (force) | 613 | if (force) |
614 | tmslow |= SSB_TMSLOW_FGC; | 614 | tmslow |= SSB_TMSLOW_FGC; |
615 | else | 615 | else |
616 | tmslow &= ~SSB_TMSLOW_FGC; | 616 | tmslow &= ~SSB_TMSLOW_FGC; |
617 | ssb_write32(dev->dev, SSB_TMSLOW, tmslow); | 617 | ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); |
618 | } | 618 | } |
619 | 619 | ||
620 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */ | 620 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */ |
@@ -959,7 +959,7 @@ static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init) | |||
959 | b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0); | 959 | b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0); |
960 | b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0); | 960 | b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0); |
961 | 961 | ||
962 | ssb_chipco_gpio_control(&dev->dev->bus->chipco, 0xFC00, | 962 | ssb_chipco_gpio_control(&dev->sdev->bus->chipco, 0xFC00, |
963 | 0xFC00); | 963 | 0xFC00); |
964 | b43_write32(dev, B43_MMIO_MACCTL, | 964 | b43_write32(dev, B43_MMIO_MACCTL, |
965 | b43_read32(dev, B43_MMIO_MACCTL) & | 965 | b43_read32(dev, B43_MMIO_MACCTL) & |
@@ -983,7 +983,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) | |||
983 | { | 983 | { |
984 | u16 tmp; | 984 | u16 tmp; |
985 | 985 | ||
986 | if (dev->dev->id.revision == 16) | 986 | if (dev->sdev->id.revision == 16) |
987 | b43_mac_suspend(dev); | 987 | b43_mac_suspend(dev); |
988 | 988 | ||
989 | tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL); | 989 | tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL); |
@@ -993,7 +993,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) | |||
993 | tmp |= (val & mask); | 993 | tmp |= (val & mask); |
994 | b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp); | 994 | b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp); |
995 | 995 | ||
996 | if (dev->dev->id.revision == 16) | 996 | if (dev->sdev->id.revision == 16) |
997 | b43_mac_enable(dev); | 997 | b43_mac_enable(dev); |
998 | 998 | ||
999 | return tmp; | 999 | return tmp; |
@@ -1168,7 +1168,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) | |||
1168 | static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) | 1168 | static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) |
1169 | { | 1169 | { |
1170 | struct b43_phy_n *nphy = dev->phy.n; | 1170 | struct b43_phy_n *nphy = dev->phy.n; |
1171 | struct ssb_sprom *sprom = &(dev->dev->bus->sprom); | 1171 | struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); |
1172 | 1172 | ||
1173 | /* PHY rev 0, 1, 2 */ | 1173 | /* PHY rev 0, 1, 2 */ |
1174 | u8 i, j; | 1174 | u8 i, j; |
@@ -1373,7 +1373,7 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) | |||
1373 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ | 1373 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ |
1374 | static void b43_nphy_workarounds(struct b43_wldev *dev) | 1374 | static void b43_nphy_workarounds(struct b43_wldev *dev) |
1375 | { | 1375 | { |
1376 | struct ssb_bus *bus = dev->dev->bus; | 1376 | struct ssb_bus *bus = dev->sdev->bus; |
1377 | struct b43_phy *phy = &dev->phy; | 1377 | struct b43_phy *phy = &dev->phy; |
1378 | struct b43_phy_n *nphy = phy->n; | 1378 | struct b43_phy_n *nphy = phy->n; |
1379 | 1379 | ||
@@ -3586,7 +3586,7 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask) | |||
3586 | */ | 3586 | */ |
3587 | int b43_phy_initn(struct b43_wldev *dev) | 3587 | int b43_phy_initn(struct b43_wldev *dev) |
3588 | { | 3588 | { |
3589 | struct ssb_bus *bus = dev->dev->bus; | 3589 | struct ssb_bus *bus = dev->sdev->bus; |
3590 | struct b43_phy *phy = &dev->phy; | 3590 | struct b43_phy *phy = &dev->phy; |
3591 | struct b43_phy_n *nphy = phy->n; | 3591 | struct b43_phy_n *nphy = phy->n; |
3592 | u8 tx_pwr_state; | 3592 | u8 tx_pwr_state; |
@@ -3601,7 +3601,7 @@ int b43_phy_initn(struct b43_wldev *dev) | |||
3601 | if ((dev->phy.rev >= 3) && | 3601 | if ((dev->phy.rev >= 3) && |
3602 | (bus->sprom.boardflags_lo & B43_BFL_EXTLNA) && | 3602 | (bus->sprom.boardflags_lo & B43_BFL_EXTLNA) && |
3603 | (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) { | 3603 | (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) { |
3604 | chipco_set32(&dev->dev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40); | 3604 | chipco_set32(&dev->sdev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40); |
3605 | } | 3605 | } |
3606 | nphy->deaf_count = 0; | 3606 | nphy->deaf_count = 0; |
3607 | b43_nphy_tables_init(dev); | 3607 | b43_nphy_tables_init(dev); |
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index aa12273ae716..72ab94df7569 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c | |||
@@ -111,7 +111,7 @@ static u16 index_to_pioqueue_base(struct b43_wldev *dev, | |||
111 | B43_MMIO_PIO11_BASE5, | 111 | B43_MMIO_PIO11_BASE5, |
112 | }; | 112 | }; |
113 | 113 | ||
114 | if (dev->dev->id.revision >= 11) { | 114 | if (dev->sdev->id.revision >= 11) { |
115 | B43_WARN_ON(index >= ARRAY_SIZE(bases_rev11)); | 115 | B43_WARN_ON(index >= ARRAY_SIZE(bases_rev11)); |
116 | return bases_rev11[index]; | 116 | return bases_rev11[index]; |
117 | } | 117 | } |
@@ -121,14 +121,14 @@ static u16 index_to_pioqueue_base(struct b43_wldev *dev, | |||
121 | 121 | ||
122 | static u16 pio_txqueue_offset(struct b43_wldev *dev) | 122 | static u16 pio_txqueue_offset(struct b43_wldev *dev) |
123 | { | 123 | { |
124 | if (dev->dev->id.revision >= 11) | 124 | if (dev->sdev->id.revision >= 11) |
125 | return 0x18; | 125 | return 0x18; |
126 | return 0; | 126 | return 0; |
127 | } | 127 | } |
128 | 128 | ||
129 | static u16 pio_rxqueue_offset(struct b43_wldev *dev) | 129 | static u16 pio_rxqueue_offset(struct b43_wldev *dev) |
130 | { | 130 | { |
131 | if (dev->dev->id.revision >= 11) | 131 | if (dev->sdev->id.revision >= 11) |
132 | return 0x38; | 132 | return 0x38; |
133 | return 8; | 133 | return 8; |
134 | } | 134 | } |
@@ -144,7 +144,7 @@ static struct b43_pio_txqueue *b43_setup_pioqueue_tx(struct b43_wldev *dev, | |||
144 | if (!q) | 144 | if (!q) |
145 | return NULL; | 145 | return NULL; |
146 | q->dev = dev; | 146 | q->dev = dev; |
147 | q->rev = dev->dev->id.revision; | 147 | q->rev = dev->sdev->id.revision; |
148 | q->mmio_base = index_to_pioqueue_base(dev, index) + | 148 | q->mmio_base = index_to_pioqueue_base(dev, index) + |
149 | pio_txqueue_offset(dev); | 149 | pio_txqueue_offset(dev); |
150 | q->index = index; | 150 | q->index = index; |
@@ -178,7 +178,7 @@ static struct b43_pio_rxqueue *b43_setup_pioqueue_rx(struct b43_wldev *dev, | |||
178 | if (!q) | 178 | if (!q) |
179 | return NULL; | 179 | return NULL; |
180 | q->dev = dev; | 180 | q->dev = dev; |
181 | q->rev = dev->dev->id.revision; | 181 | q->rev = dev->sdev->id.revision; |
182 | q->mmio_base = index_to_pioqueue_base(dev, index) + | 182 | q->mmio_base = index_to_pioqueue_base(dev, index) + |
183 | pio_rxqueue_offset(dev); | 183 | pio_rxqueue_offset(dev); |
184 | 184 | ||
@@ -339,7 +339,7 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q, | |||
339 | ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI; | 339 | ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI; |
340 | b43_piotx_write16(q, B43_PIO_TXCTL, ctl); | 340 | b43_piotx_write16(q, B43_PIO_TXCTL, ctl); |
341 | 341 | ||
342 | ssb_block_write(dev->dev, data, (data_len & ~1), | 342 | b43_block_write(dev, data, (data_len & ~1), |
343 | q->mmio_base + B43_PIO_TXDATA, | 343 | q->mmio_base + B43_PIO_TXDATA, |
344 | sizeof(u16)); | 344 | sizeof(u16)); |
345 | if (data_len & 1) { | 345 | if (data_len & 1) { |
@@ -351,7 +351,7 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q, | |||
351 | b43_piotx_write16(q, B43_PIO_TXCTL, ctl); | 351 | b43_piotx_write16(q, B43_PIO_TXCTL, ctl); |
352 | tail[0] = data[data_len - 1]; | 352 | tail[0] = data[data_len - 1]; |
353 | tail[1] = 0; | 353 | tail[1] = 0; |
354 | ssb_block_write(dev->dev, tail, 2, | 354 | b43_block_write(dev, tail, 2, |
355 | q->mmio_base + B43_PIO_TXDATA, | 355 | q->mmio_base + B43_PIO_TXDATA, |
356 | sizeof(u16)); | 356 | sizeof(u16)); |
357 | } | 357 | } |
@@ -393,7 +393,7 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q, | |||
393 | B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_24_31; | 393 | B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_24_31; |
394 | b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); | 394 | b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); |
395 | 395 | ||
396 | ssb_block_write(dev->dev, data, (data_len & ~3), | 396 | b43_block_write(dev, data, (data_len & ~3), |
397 | q->mmio_base + B43_PIO8_TXDATA, | 397 | q->mmio_base + B43_PIO8_TXDATA, |
398 | sizeof(u32)); | 398 | sizeof(u32)); |
399 | if (data_len & 3) { | 399 | if (data_len & 3) { |
@@ -421,7 +421,7 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q, | |||
421 | break; | 421 | break; |
422 | } | 422 | } |
423 | b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); | 423 | b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); |
424 | ssb_block_write(dev->dev, tail, 4, | 424 | b43_block_write(dev, tail, 4, |
425 | q->mmio_base + B43_PIO8_TXDATA, | 425 | q->mmio_base + B43_PIO8_TXDATA, |
426 | sizeof(u32)); | 426 | sizeof(u32)); |
427 | } | 427 | } |
@@ -657,11 +657,11 @@ data_ready: | |||
657 | 657 | ||
658 | /* Get the preamble (RX header) */ | 658 | /* Get the preamble (RX header) */ |
659 | if (q->rev >= 8) { | 659 | if (q->rev >= 8) { |
660 | ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr), | 660 | b43_block_read(dev, rxhdr, sizeof(*rxhdr), |
661 | q->mmio_base + B43_PIO8_RXDATA, | 661 | q->mmio_base + B43_PIO8_RXDATA, |
662 | sizeof(u32)); | 662 | sizeof(u32)); |
663 | } else { | 663 | } else { |
664 | ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr), | 664 | b43_block_read(dev, rxhdr, sizeof(*rxhdr), |
665 | q->mmio_base + B43_PIO_RXDATA, | 665 | q->mmio_base + B43_PIO_RXDATA, |
666 | sizeof(u16)); | 666 | sizeof(u16)); |
667 | } | 667 | } |
@@ -697,7 +697,7 @@ data_ready: | |||
697 | skb_reserve(skb, 2); | 697 | skb_reserve(skb, 2); |
698 | skb_put(skb, len + padding); | 698 | skb_put(skb, len + padding); |
699 | if (q->rev >= 8) { | 699 | if (q->rev >= 8) { |
700 | ssb_block_read(dev->dev, skb->data + padding, (len & ~3), | 700 | b43_block_read(dev, skb->data + padding, (len & ~3), |
701 | q->mmio_base + B43_PIO8_RXDATA, | 701 | q->mmio_base + B43_PIO8_RXDATA, |
702 | sizeof(u32)); | 702 | sizeof(u32)); |
703 | if (len & 3) { | 703 | if (len & 3) { |
@@ -705,7 +705,7 @@ data_ready: | |||
705 | BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4); | 705 | BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4); |
706 | 706 | ||
707 | /* Read the last few bytes. */ | 707 | /* Read the last few bytes. */ |
708 | ssb_block_read(dev->dev, tail, 4, | 708 | b43_block_read(dev, tail, 4, |
709 | q->mmio_base + B43_PIO8_RXDATA, | 709 | q->mmio_base + B43_PIO8_RXDATA, |
710 | sizeof(u32)); | 710 | sizeof(u32)); |
711 | switch (len & 3) { | 711 | switch (len & 3) { |
@@ -724,7 +724,7 @@ data_ready: | |||
724 | } | 724 | } |
725 | } | 725 | } |
726 | } else { | 726 | } else { |
727 | ssb_block_read(dev->dev, skb->data + padding, (len & ~1), | 727 | b43_block_read(dev, skb->data + padding, (len & ~1), |
728 | q->mmio_base + B43_PIO_RXDATA, | 728 | q->mmio_base + B43_PIO_RXDATA, |
729 | sizeof(u16)); | 729 | sizeof(u16)); |
730 | if (len & 1) { | 730 | if (len & 1) { |
@@ -732,7 +732,7 @@ data_ready: | |||
732 | BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2); | 732 | BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2); |
733 | 733 | ||
734 | /* Read the last byte. */ | 734 | /* Read the last byte. */ |
735 | ssb_block_read(dev->dev, tail, 2, | 735 | b43_block_read(dev, tail, 2, |
736 | q->mmio_base + B43_PIO_RXDATA, | 736 | q->mmio_base + B43_PIO_RXDATA, |
737 | sizeof(u16)); | 737 | sizeof(u16)); |
738 | skb->data[len + padding - 1] = tail[0]; | 738 | skb->data[len + padding - 1] = tail[0]; |
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index 86bc0a0f735c..a617efe38289 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c | |||
@@ -37,7 +37,7 @@ void b43_rfkill_poll(struct ieee80211_hw *hw) | |||
37 | { | 37 | { |
38 | struct b43_wl *wl = hw_to_b43_wl(hw); | 38 | struct b43_wl *wl = hw_to_b43_wl(hw); |
39 | struct b43_wldev *dev = wl->current_dev; | 39 | struct b43_wldev *dev = wl->current_dev; |
40 | struct ssb_bus *bus = dev->dev->bus; | 40 | struct ssb_bus *bus = dev->sdev->bus; |
41 | bool enabled; | 41 | bool enabled; |
42 | bool brought_up = false; | 42 | bool brought_up = false; |
43 | 43 | ||
@@ -47,7 +47,7 @@ void b43_rfkill_poll(struct ieee80211_hw *hw) | |||
47 | mutex_unlock(&wl->mutex); | 47 | mutex_unlock(&wl->mutex); |
48 | return; | 48 | return; |
49 | } | 49 | } |
50 | ssb_device_enable(dev->dev, 0); | 50 | ssb_device_enable(dev->sdev, 0); |
51 | brought_up = true; | 51 | brought_up = true; |
52 | } | 52 | } |
53 | 53 | ||
@@ -63,7 +63,7 @@ void b43_rfkill_poll(struct ieee80211_hw *hw) | |||
63 | } | 63 | } |
64 | 64 | ||
65 | if (brought_up) { | 65 | if (brought_up) { |
66 | ssb_device_disable(dev->dev, 0); | 66 | ssb_device_disable(dev->sdev, 0); |
67 | ssb_bus_may_powerdown(bus); | 67 | ssb_bus_may_powerdown(bus); |
68 | } | 68 | } |
69 | 69 | ||
diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c index 09e2dfd7b175..808e25b79703 100644 --- a/drivers/net/wireless/b43/sdio.c +++ b/drivers/net/wireless/b43/sdio.c | |||
@@ -66,7 +66,7 @@ static void b43_sdio_interrupt_dispatcher(struct sdio_func *func) | |||
66 | int b43_sdio_request_irq(struct b43_wldev *dev, | 66 | int b43_sdio_request_irq(struct b43_wldev *dev, |
67 | void (*handler)(struct b43_wldev *dev)) | 67 | void (*handler)(struct b43_wldev *dev)) |
68 | { | 68 | { |
69 | struct ssb_bus *bus = dev->dev->bus; | 69 | struct ssb_bus *bus = dev->sdev->bus; |
70 | struct sdio_func *func = bus->host_sdio; | 70 | struct sdio_func *func = bus->host_sdio; |
71 | struct b43_sdio *sdio = sdio_get_drvdata(func); | 71 | struct b43_sdio *sdio = sdio_get_drvdata(func); |
72 | int err; | 72 | int err; |
@@ -82,7 +82,7 @@ int b43_sdio_request_irq(struct b43_wldev *dev, | |||
82 | 82 | ||
83 | void b43_sdio_free_irq(struct b43_wldev *dev) | 83 | void b43_sdio_free_irq(struct b43_wldev *dev) |
84 | { | 84 | { |
85 | struct ssb_bus *bus = dev->dev->bus; | 85 | struct ssb_bus *bus = dev->sdev->bus; |
86 | struct sdio_func *func = bus->host_sdio; | 86 | struct sdio_func *func = bus->host_sdio; |
87 | struct b43_sdio *sdio = sdio_get_drvdata(func); | 87 | struct b43_sdio *sdio = sdio_get_drvdata(func); |
88 | 88 | ||
diff --git a/drivers/net/wireless/b43/sysfs.c b/drivers/net/wireless/b43/sysfs.c index f1ae4e05a32c..57af619725c3 100644 --- a/drivers/net/wireless/b43/sysfs.c +++ b/drivers/net/wireless/b43/sysfs.c | |||
@@ -140,7 +140,7 @@ static DEVICE_ATTR(interference, 0644, | |||
140 | 140 | ||
141 | int b43_sysfs_register(struct b43_wldev *wldev) | 141 | int b43_sysfs_register(struct b43_wldev *wldev) |
142 | { | 142 | { |
143 | struct device *dev = wldev->dev->dev; | 143 | struct device *dev = wldev->sdev->dev; |
144 | 144 | ||
145 | B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED); | 145 | B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED); |
146 | 146 | ||
@@ -149,7 +149,7 @@ int b43_sysfs_register(struct b43_wldev *wldev) | |||
149 | 149 | ||
150 | void b43_sysfs_unregister(struct b43_wldev *wldev) | 150 | void b43_sysfs_unregister(struct b43_wldev *wldev) |
151 | { | 151 | { |
152 | struct device *dev = wldev->dev->dev; | 152 | struct device *dev = wldev->sdev->dev; |
153 | 153 | ||
154 | device_remove_file(dev, &dev_attr_interference); | 154 | device_remove_file(dev, &dev_attr_interference); |
155 | } | 155 | } |
diff --git a/drivers/net/wireless/b43/tables_lpphy.c b/drivers/net/wireless/b43/tables_lpphy.c index 61027ee84fb5..59df3c64af63 100644 --- a/drivers/net/wireless/b43/tables_lpphy.c +++ b/drivers/net/wireless/b43/tables_lpphy.c | |||
@@ -2304,7 +2304,7 @@ void lpphy_rev0_1_table_init(struct b43_wldev *dev) | |||
2304 | 2304 | ||
2305 | void lpphy_rev2plus_table_init(struct b43_wldev *dev) | 2305 | void lpphy_rev2plus_table_init(struct b43_wldev *dev) |
2306 | { | 2306 | { |
2307 | struct ssb_bus *bus = dev->dev->bus; | 2307 | struct ssb_bus *bus = dev->sdev->bus; |
2308 | int i; | 2308 | int i; |
2309 | 2309 | ||
2310 | B43_WARN_ON(dev->phy.rev < 2); | 2310 | B43_WARN_ON(dev->phy.rev < 2); |
@@ -2416,7 +2416,7 @@ void lpphy_write_gain_table_bulk(struct b43_wldev *dev, int offset, int count, | |||
2416 | 2416 | ||
2417 | void lpphy_init_tx_gain_table(struct b43_wldev *dev) | 2417 | void lpphy_init_tx_gain_table(struct b43_wldev *dev) |
2418 | { | 2418 | { |
2419 | struct ssb_bus *bus = dev->dev->bus; | 2419 | struct ssb_bus *bus = dev->sdev->bus; |
2420 | 2420 | ||
2421 | switch (dev->phy.rev) { | 2421 | switch (dev->phy.rev) { |
2422 | case 0: | 2422 | case 0: |
diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c index 9a335da65b42..8f4db448ec33 100644 --- a/drivers/net/wireless/b43/wa.c +++ b/drivers/net/wireless/b43/wa.c | |||
@@ -458,7 +458,7 @@ static void b43_wa_rssi_adc(struct b43_wldev *dev) | |||
458 | 458 | ||
459 | static void b43_wa_boards_a(struct b43_wldev *dev) | 459 | static void b43_wa_boards_a(struct b43_wldev *dev) |
460 | { | 460 | { |
461 | struct ssb_bus *bus = dev->dev->bus; | 461 | struct ssb_bus *bus = dev->sdev->bus; |
462 | 462 | ||
463 | if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM && | 463 | if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM && |
464 | bus->boardinfo.type == SSB_BOARD_BU4306 && | 464 | bus->boardinfo.type == SSB_BOARD_BU4306 && |
@@ -486,7 +486,7 @@ static void b43_wa_boards_a(struct b43_wldev *dev) | |||
486 | 486 | ||
487 | static void b43_wa_boards_g(struct b43_wldev *dev) | 487 | static void b43_wa_boards_g(struct b43_wldev *dev) |
488 | { | 488 | { |
489 | struct ssb_bus *bus = dev->dev->bus; | 489 | struct ssb_bus *bus = dev->sdev->bus; |
490 | struct b43_phy *phy = &dev->phy; | 490 | struct b43_phy *phy = &dev->phy; |
491 | 491 | ||
492 | if (bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM || | 492 | if (bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM || |
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index e5be381c17bc..c8f99aebe01f 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -547,7 +547,7 @@ static s8 b43_rssi_postprocess(struct b43_wldev *dev, | |||
547 | else | 547 | else |
548 | tmp -= 3; | 548 | tmp -= 3; |
549 | } else { | 549 | } else { |
550 | if (dev->dev->bus->sprom. | 550 | if (dev->sdev->bus->sprom. |
551 | boardflags_lo & B43_BFL_RSSI) { | 551 | boardflags_lo & B43_BFL_RSSI) { |
552 | if (in_rssi > 63) | 552 | if (in_rssi > 63) |
553 | in_rssi = 63; | 553 | in_rssi = 63; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index b4c81931e136..61d4a11f566b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -171,10 +171,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) | |||
171 | 171 | ||
172 | static struct iwl_lib_ops iwl1000_lib = { | 172 | static struct iwl_lib_ops iwl1000_lib = { |
173 | .set_hw_params = iwl1000_hw_set_hw_params, | 173 | .set_hw_params = iwl1000_hw_set_hw_params, |
174 | .txq_set_sched = iwlagn_txq_set_sched, | ||
175 | .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, | ||
176 | .txq_free_tfd = iwl_hw_txq_free_tfd, | ||
177 | .txq_init = iwl_hw_tx_queue_init, | ||
178 | .rx_handler_setup = iwlagn_rx_handler_setup, | 174 | .rx_handler_setup = iwlagn_rx_handler_setup, |
179 | .setup_deferred_work = iwlagn_setup_deferred_work, | 175 | .setup_deferred_work = iwlagn_setup_deferred_work, |
180 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | 176 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 89b8da7a6c8b..86feec86d130 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
@@ -195,9 +195,9 @@ static int iwl2030_hw_channel_switch(struct iwl_priv *priv, | |||
195 | struct ieee80211_vif *vif = ctx->vif; | 195 | struct ieee80211_vif *vif = ctx->vif; |
196 | struct iwl_host_cmd hcmd = { | 196 | struct iwl_host_cmd hcmd = { |
197 | .id = REPLY_CHANNEL_SWITCH, | 197 | .id = REPLY_CHANNEL_SWITCH, |
198 | .len = sizeof(cmd), | 198 | .len = { sizeof(cmd), }, |
199 | .flags = CMD_SYNC, | 199 | .flags = CMD_SYNC, |
200 | .data = &cmd, | 200 | .data = { &cmd, }, |
201 | }; | 201 | }; |
202 | 202 | ||
203 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; | 203 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; |
@@ -252,10 +252,6 @@ static int iwl2030_hw_channel_switch(struct iwl_priv *priv, | |||
252 | 252 | ||
253 | static struct iwl_lib_ops iwl2000_lib = { | 253 | static struct iwl_lib_ops iwl2000_lib = { |
254 | .set_hw_params = iwl2000_hw_set_hw_params, | 254 | .set_hw_params = iwl2000_hw_set_hw_params, |
255 | .txq_set_sched = iwlagn_txq_set_sched, | ||
256 | .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, | ||
257 | .txq_free_tfd = iwl_hw_txq_free_tfd, | ||
258 | .txq_init = iwl_hw_tx_queue_init, | ||
259 | .rx_handler_setup = iwlagn_rx_handler_setup, | 255 | .rx_handler_setup = iwlagn_rx_handler_setup, |
260 | .setup_deferred_work = iwlagn_bt_setup_deferred_work, | 256 | .setup_deferred_work = iwlagn_bt_setup_deferred_work, |
261 | .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, | 257 | .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 98f81df166e3..a70b8cfafda1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -282,9 +282,9 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, | |||
282 | struct ieee80211_vif *vif = ctx->vif; | 282 | struct ieee80211_vif *vif = ctx->vif; |
283 | struct iwl_host_cmd hcmd = { | 283 | struct iwl_host_cmd hcmd = { |
284 | .id = REPLY_CHANNEL_SWITCH, | 284 | .id = REPLY_CHANNEL_SWITCH, |
285 | .len = sizeof(cmd), | 285 | .len = { sizeof(cmd), }, |
286 | .flags = CMD_SYNC, | 286 | .flags = CMD_SYNC, |
287 | .data = &cmd, | 287 | .data = { &cmd, }, |
288 | }; | 288 | }; |
289 | 289 | ||
290 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; | 290 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; |
@@ -339,10 +339,6 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, | |||
339 | 339 | ||
340 | static struct iwl_lib_ops iwl5000_lib = { | 340 | static struct iwl_lib_ops iwl5000_lib = { |
341 | .set_hw_params = iwl5000_hw_set_hw_params, | 341 | .set_hw_params = iwl5000_hw_set_hw_params, |
342 | .txq_set_sched = iwlagn_txq_set_sched, | ||
343 | .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, | ||
344 | .txq_free_tfd = iwl_hw_txq_free_tfd, | ||
345 | .txq_init = iwl_hw_tx_queue_init, | ||
346 | .rx_handler_setup = iwlagn_rx_handler_setup, | 342 | .rx_handler_setup = iwlagn_rx_handler_setup, |
347 | .setup_deferred_work = iwlagn_setup_deferred_work, | 343 | .setup_deferred_work = iwlagn_setup_deferred_work, |
348 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | 344 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, |
@@ -374,10 +370,6 @@ static struct iwl_lib_ops iwl5000_lib = { | |||
374 | 370 | ||
375 | static struct iwl_lib_ops iwl5150_lib = { | 371 | static struct iwl_lib_ops iwl5150_lib = { |
376 | .set_hw_params = iwl5150_hw_set_hw_params, | 372 | .set_hw_params = iwl5150_hw_set_hw_params, |
377 | .txq_set_sched = iwlagn_txq_set_sched, | ||
378 | .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, | ||
379 | .txq_free_tfd = iwl_hw_txq_free_tfd, | ||
380 | .txq_init = iwl_hw_tx_queue_init, | ||
381 | .rx_handler_setup = iwlagn_rx_handler_setup, | 373 | .rx_handler_setup = iwlagn_rx_handler_setup, |
382 | .setup_deferred_work = iwlagn_setup_deferred_work, | 374 | .setup_deferred_work = iwlagn_setup_deferred_work, |
383 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | 375 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index a7921f9a03c6..f8c710db6e6f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -221,9 +221,9 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | |||
221 | struct ieee80211_vif *vif = ctx->vif; | 221 | struct ieee80211_vif *vif = ctx->vif; |
222 | struct iwl_host_cmd hcmd = { | 222 | struct iwl_host_cmd hcmd = { |
223 | .id = REPLY_CHANNEL_SWITCH, | 223 | .id = REPLY_CHANNEL_SWITCH, |
224 | .len = sizeof(cmd), | 224 | .len = { sizeof(cmd), }, |
225 | .flags = CMD_SYNC, | 225 | .flags = CMD_SYNC, |
226 | .data = &cmd, | 226 | .data = { &cmd, }, |
227 | }; | 227 | }; |
228 | 228 | ||
229 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; | 229 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; |
@@ -278,10 +278,6 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | |||
278 | 278 | ||
279 | static struct iwl_lib_ops iwl6000_lib = { | 279 | static struct iwl_lib_ops iwl6000_lib = { |
280 | .set_hw_params = iwl6000_hw_set_hw_params, | 280 | .set_hw_params = iwl6000_hw_set_hw_params, |
281 | .txq_set_sched = iwlagn_txq_set_sched, | ||
282 | .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, | ||
283 | .txq_free_tfd = iwl_hw_txq_free_tfd, | ||
284 | .txq_init = iwl_hw_tx_queue_init, | ||
285 | .rx_handler_setup = iwlagn_rx_handler_setup, | 281 | .rx_handler_setup = iwlagn_rx_handler_setup, |
286 | .setup_deferred_work = iwlagn_setup_deferred_work, | 282 | .setup_deferred_work = iwlagn_setup_deferred_work, |
287 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | 283 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, |
@@ -314,10 +310,6 @@ static struct iwl_lib_ops iwl6000_lib = { | |||
314 | 310 | ||
315 | static struct iwl_lib_ops iwl6030_lib = { | 311 | static struct iwl_lib_ops iwl6030_lib = { |
316 | .set_hw_params = iwl6000_hw_set_hw_params, | 312 | .set_hw_params = iwl6000_hw_set_hw_params, |
317 | .txq_set_sched = iwlagn_txq_set_sched, | ||
318 | .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, | ||
319 | .txq_free_tfd = iwl_hw_txq_free_tfd, | ||
320 | .txq_init = iwl_hw_tx_queue_init, | ||
321 | .rx_handler_setup = iwlagn_bt_rx_handler_setup, | 313 | .rx_handler_setup = iwlagn_bt_rx_handler_setup, |
322 | .setup_deferred_work = iwlagn_bt_setup_deferred_work, | 314 | .setup_deferred_work = iwlagn_bt_setup_deferred_work, |
323 | .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, | 315 | .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 39d1e47a0978..c9255def1080 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c | |||
@@ -87,14 +87,14 @@ int iwl_send_calib_results(struct iwl_priv *priv) | |||
87 | 87 | ||
88 | struct iwl_host_cmd hcmd = { | 88 | struct iwl_host_cmd hcmd = { |
89 | .id = REPLY_PHY_CALIBRATION_CMD, | 89 | .id = REPLY_PHY_CALIBRATION_CMD, |
90 | .flags = CMD_SIZE_HUGE, | ||
91 | }; | 90 | }; |
92 | 91 | ||
93 | for (i = 0; i < IWL_CALIB_MAX; i++) { | 92 | for (i = 0; i < IWL_CALIB_MAX; i++) { |
94 | if ((BIT(i) & priv->hw_params.calib_init_cfg) && | 93 | if ((BIT(i) & priv->hw_params.calib_init_cfg) && |
95 | priv->calib_results[i].buf) { | 94 | priv->calib_results[i].buf) { |
96 | hcmd.len = priv->calib_results[i].buf_len; | 95 | hcmd.len[0] = priv->calib_results[i].buf_len; |
97 | hcmd.data = priv->calib_results[i].buf; | 96 | hcmd.data[0] = priv->calib_results[i].buf; |
97 | hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; | ||
98 | ret = iwl_send_cmd_sync(priv, &hcmd); | 98 | ret = iwl_send_cmd_sync(priv, &hcmd); |
99 | if (ret) { | 99 | if (ret) { |
100 | IWL_ERR(priv, "Error %d iteration %d\n", | 100 | IWL_ERR(priv, "Error %d iteration %d\n", |
@@ -456,9 +456,9 @@ static int iwl_sensitivity_write(struct iwl_priv *priv) | |||
456 | struct iwl_sensitivity_data *data = NULL; | 456 | struct iwl_sensitivity_data *data = NULL; |
457 | struct iwl_host_cmd cmd_out = { | 457 | struct iwl_host_cmd cmd_out = { |
458 | .id = SENSITIVITY_CMD, | 458 | .id = SENSITIVITY_CMD, |
459 | .len = sizeof(struct iwl_sensitivity_cmd), | 459 | .len = { sizeof(struct iwl_sensitivity_cmd), }, |
460 | .flags = CMD_ASYNC, | 460 | .flags = CMD_ASYNC, |
461 | .data = &cmd, | 461 | .data = { &cmd, }, |
462 | }; | 462 | }; |
463 | 463 | ||
464 | data = &(priv->sensitivity_data); | 464 | data = &(priv->sensitivity_data); |
@@ -491,9 +491,9 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv) | |||
491 | struct iwl_sensitivity_data *data = NULL; | 491 | struct iwl_sensitivity_data *data = NULL; |
492 | struct iwl_host_cmd cmd_out = { | 492 | struct iwl_host_cmd cmd_out = { |
493 | .id = SENSITIVITY_CMD, | 493 | .id = SENSITIVITY_CMD, |
494 | .len = sizeof(struct iwl_enhance_sensitivity_cmd), | 494 | .len = { sizeof(struct iwl_enhance_sensitivity_cmd), }, |
495 | .flags = CMD_ASYNC, | 495 | .flags = CMD_ASYNC, |
496 | .data = &cmd, | 496 | .data = { &cmd, }, |
497 | }; | 497 | }; |
498 | 498 | ||
499 | data = &(priv->sensitivity_data); | 499 | data = &(priv->sensitivity_data); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 8e79653aed9a..f803fb62f8bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -1140,8 +1140,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
1140 | { | 1140 | { |
1141 | struct iwl_host_cmd cmd = { | 1141 | struct iwl_host_cmd cmd = { |
1142 | .id = REPLY_SCAN_CMD, | 1142 | .id = REPLY_SCAN_CMD, |
1143 | .len = sizeof(struct iwl_scan_cmd), | 1143 | .len = { sizeof(struct iwl_scan_cmd), }, |
1144 | .flags = CMD_SIZE_HUGE, | ||
1145 | }; | 1144 | }; |
1146 | struct iwl_scan_cmd *scan; | 1145 | struct iwl_scan_cmd *scan; |
1147 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 1146 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
@@ -1425,10 +1424,11 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
1425 | return -EIO; | 1424 | return -EIO; |
1426 | } | 1425 | } |
1427 | 1426 | ||
1428 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + | 1427 | cmd.len[0] += le16_to_cpu(scan->tx_cmd.len) + |
1429 | scan->channel_count * sizeof(struct iwl_scan_channel); | 1428 | scan->channel_count * sizeof(struct iwl_scan_channel); |
1430 | cmd.data = scan; | 1429 | cmd.data[0] = scan; |
1431 | scan->len = cpu_to_le16(cmd.len); | 1430 | cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; |
1431 | scan->len = cpu_to_le16(cmd.len[0]); | ||
1432 | 1432 | ||
1433 | /* set scan bit here for PAN params */ | 1433 | /* set scan bit here for PAN params */ |
1434 | set_bit(STATUS_SCAN_HW, &priv->status); | 1434 | set_bit(STATUS_SCAN_HW, &priv->status); |
@@ -1520,9 +1520,9 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) | |||
1520 | struct iwl_txfifo_flush_cmd flush_cmd; | 1520 | struct iwl_txfifo_flush_cmd flush_cmd; |
1521 | struct iwl_host_cmd cmd = { | 1521 | struct iwl_host_cmd cmd = { |
1522 | .id = REPLY_TXFIFO_FLUSH, | 1522 | .id = REPLY_TXFIFO_FLUSH, |
1523 | .len = sizeof(struct iwl_txfifo_flush_cmd), | 1523 | .len = { sizeof(struct iwl_txfifo_flush_cmd), }, |
1524 | .flags = CMD_SYNC, | 1524 | .flags = CMD_SYNC, |
1525 | .data = &flush_cmd, | 1525 | .data = { &flush_cmd, }, |
1526 | }; | 1526 | }; |
1527 | 1527 | ||
1528 | might_sleep(); | 1528 | might_sleep(); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 91f26556ac23..592b0cfcf717 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -335,6 +335,32 @@ static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data, | |||
335 | return tid; | 335 | return tid; |
336 | } | 336 | } |
337 | 337 | ||
338 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
339 | static void rs_program_fix_rate(struct iwl_priv *priv, | ||
340 | struct iwl_lq_sta *lq_sta) | ||
341 | { | ||
342 | struct iwl_station_priv *sta_priv = | ||
343 | container_of(lq_sta, struct iwl_station_priv, lq_sta); | ||
344 | struct iwl_rxon_context *ctx = sta_priv->common.ctx; | ||
345 | |||
346 | lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */ | ||
347 | lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ | ||
348 | lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ | ||
349 | lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ | ||
350 | |||
351 | lq_sta->dbg_fixed_rate = priv->dbg_fixed_rate; | ||
352 | |||
353 | IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n", | ||
354 | lq_sta->lq.sta_id, priv->dbg_fixed_rate); | ||
355 | |||
356 | if (priv->dbg_fixed_rate) { | ||
357 | rs_fill_link_cmd(NULL, lq_sta, priv->dbg_fixed_rate); | ||
358 | iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC, | ||
359 | false); | ||
360 | } | ||
361 | } | ||
362 | #endif | ||
363 | |||
338 | /* | 364 | /* |
339 | get the traffic load value for tid | 365 | get the traffic load value for tid |
340 | */ | 366 | */ |
@@ -1046,7 +1072,10 @@ done: | |||
1046 | /* See if there's a better rate or modulation mode to try. */ | 1072 | /* See if there's a better rate or modulation mode to try. */ |
1047 | if (sta && sta->supp_rates[sband->band]) | 1073 | if (sta && sta->supp_rates[sband->band]) |
1048 | rs_rate_scale_perform(priv, skb, sta, lq_sta); | 1074 | rs_rate_scale_perform(priv, skb, sta, lq_sta); |
1049 | 1075 | #ifdef CONFIG_MAC80211_DEBUGFS | |
1076 | if (priv->dbg_fixed_rate != lq_sta->dbg_fixed_rate) | ||
1077 | rs_program_fix_rate(priv, lq_sta); | ||
1078 | #endif | ||
1050 | if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) | 1079 | if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) |
1051 | rs_bt_update_lq(priv, ctx, lq_sta); | 1080 | rs_bt_update_lq(priv, ctx, lq_sta); |
1052 | } | 1081 | } |
@@ -2170,11 +2199,11 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search) | |||
2170 | * setup rate table in uCode | 2199 | * setup rate table in uCode |
2171 | * return rate_n_flags as used in the table | 2200 | * return rate_n_flags as used in the table |
2172 | */ | 2201 | */ |
2173 | static u32 rs_update_rate_tbl(struct iwl_priv *priv, | 2202 | static void rs_update_rate_tbl(struct iwl_priv *priv, |
2174 | struct iwl_rxon_context *ctx, | 2203 | struct iwl_rxon_context *ctx, |
2175 | struct iwl_lq_sta *lq_sta, | 2204 | struct iwl_lq_sta *lq_sta, |
2176 | struct iwl_scale_tbl_info *tbl, | 2205 | struct iwl_scale_tbl_info *tbl, |
2177 | int index, u8 is_green) | 2206 | int index, u8 is_green) |
2178 | { | 2207 | { |
2179 | u32 rate; | 2208 | u32 rate; |
2180 | 2209 | ||
@@ -2182,8 +2211,6 @@ static u32 rs_update_rate_tbl(struct iwl_priv *priv, | |||
2182 | rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); | 2211 | rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); |
2183 | rs_fill_link_cmd(priv, lq_sta, rate); | 2212 | rs_fill_link_cmd(priv, lq_sta, rate); |
2184 | iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false); | 2213 | iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false); |
2185 | |||
2186 | return rate; | ||
2187 | } | 2214 | } |
2188 | 2215 | ||
2189 | /* | 2216 | /* |
@@ -2212,7 +2239,6 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
2212 | u8 update_lq = 0; | 2239 | u8 update_lq = 0; |
2213 | struct iwl_scale_tbl_info *tbl, *tbl1; | 2240 | struct iwl_scale_tbl_info *tbl, *tbl1; |
2214 | u16 rate_scale_index_msk = 0; | 2241 | u16 rate_scale_index_msk = 0; |
2215 | u32 rate; | ||
2216 | u8 is_green = 0; | 2242 | u8 is_green = 0; |
2217 | u8 active_tbl = 0; | 2243 | u8 active_tbl = 0; |
2218 | u8 done_search = 0; | 2244 | u8 done_search = 0; |
@@ -2299,8 +2325,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
2299 | tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); | 2325 | tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); |
2300 | /* get "active" rate info */ | 2326 | /* get "active" rate info */ |
2301 | index = iwl_hwrate_to_plcp_idx(tbl->current_rate); | 2327 | index = iwl_hwrate_to_plcp_idx(tbl->current_rate); |
2302 | rate = rs_update_rate_tbl(priv, ctx, lq_sta, | 2328 | rs_update_rate_tbl(priv, ctx, lq_sta, tbl, |
2303 | tbl, index, is_green); | 2329 | index, is_green); |
2304 | } | 2330 | } |
2305 | return; | 2331 | return; |
2306 | } | 2332 | } |
@@ -2541,8 +2567,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
2541 | lq_update: | 2567 | lq_update: |
2542 | /* Replace uCode's rate table for the destination station. */ | 2568 | /* Replace uCode's rate table for the destination station. */ |
2543 | if (update_lq) | 2569 | if (update_lq) |
2544 | rate = rs_update_rate_tbl(priv, ctx, lq_sta, | 2570 | rs_update_rate_tbl(priv, ctx, lq_sta, tbl, index, is_green); |
2545 | tbl, index, is_green); | ||
2546 | 2571 | ||
2547 | if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) { | 2572 | if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) { |
2548 | /* Should we stay with this modulation mode, | 2573 | /* Should we stay with this modulation mode, |
@@ -2871,6 +2896,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i | |||
2871 | lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; | 2896 | lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; |
2872 | lq_sta->is_agg = 0; | 2897 | lq_sta->is_agg = 0; |
2873 | 2898 | ||
2899 | priv->dbg_fixed_rate = 0; | ||
2874 | #ifdef CONFIG_MAC80211_DEBUGFS | 2900 | #ifdef CONFIG_MAC80211_DEBUGFS |
2875 | lq_sta->dbg_fixed_rate = 0; | 2901 | lq_sta->dbg_fixed_rate = 0; |
2876 | #endif | 2902 | #endif |
@@ -3045,7 +3071,6 @@ static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta, | |||
3045 | IWL_DEBUG_RATE(priv, "leave\n"); | 3071 | IWL_DEBUG_RATE(priv, "leave\n"); |
3046 | } | 3072 | } |
3047 | 3073 | ||
3048 | |||
3049 | #ifdef CONFIG_MAC80211_DEBUGFS | 3074 | #ifdef CONFIG_MAC80211_DEBUGFS |
3050 | static int open_file_generic(struct inode *inode, struct file *file) | 3075 | static int open_file_generic(struct inode *inode, struct file *file) |
3051 | { | 3076 | { |
@@ -3070,6 +3095,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, | |||
3070 | IWL_DEBUG_RATE(priv, "Fixed rate ON\n"); | 3095 | IWL_DEBUG_RATE(priv, "Fixed rate ON\n"); |
3071 | } else { | 3096 | } else { |
3072 | lq_sta->dbg_fixed_rate = 0; | 3097 | lq_sta->dbg_fixed_rate = 0; |
3098 | priv->dbg_fixed_rate = 0; | ||
3073 | IWL_ERR(priv, | 3099 | IWL_ERR(priv, |
3074 | "Invalid antenna selection 0x%X, Valid is 0x%X\n", | 3100 | "Invalid antenna selection 0x%X, Valid is 0x%X\n", |
3075 | ant_sel_tx, valid_tx_ant); | 3101 | ant_sel_tx, valid_tx_ant); |
@@ -3088,9 +3114,7 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, | |||
3088 | char buf[64]; | 3114 | char buf[64]; |
3089 | size_t buf_size; | 3115 | size_t buf_size; |
3090 | u32 parsed_rate; | 3116 | u32 parsed_rate; |
3091 | struct iwl_station_priv *sta_priv = | 3117 | |
3092 | container_of(lq_sta, struct iwl_station_priv, lq_sta); | ||
3093 | struct iwl_rxon_context *ctx = sta_priv->common.ctx; | ||
3094 | 3118 | ||
3095 | priv = lq_sta->drv; | 3119 | priv = lq_sta->drv; |
3096 | memset(buf, 0, sizeof(buf)); | 3120 | memset(buf, 0, sizeof(buf)); |
@@ -3099,23 +3123,11 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, | |||
3099 | return -EFAULT; | 3123 | return -EFAULT; |
3100 | 3124 | ||
3101 | if (sscanf(buf, "%x", &parsed_rate) == 1) | 3125 | if (sscanf(buf, "%x", &parsed_rate) == 1) |
3102 | lq_sta->dbg_fixed_rate = parsed_rate; | 3126 | priv->dbg_fixed_rate = lq_sta->dbg_fixed_rate = parsed_rate; |
3103 | else | 3127 | else |
3104 | lq_sta->dbg_fixed_rate = 0; | 3128 | priv->dbg_fixed_rate = lq_sta->dbg_fixed_rate = 0; |
3105 | 3129 | ||
3106 | lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */ | 3130 | rs_program_fix_rate(priv, lq_sta); |
3107 | lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ | ||
3108 | lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ | ||
3109 | lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ | ||
3110 | |||
3111 | IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n", | ||
3112 | lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate); | ||
3113 | |||
3114 | if (lq_sta->dbg_fixed_rate) { | ||
3115 | rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate); | ||
3116 | iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC, | ||
3117 | false); | ||
3118 | } | ||
3119 | 3131 | ||
3120 | return count; | 3132 | return count; |
3121 | } | 3133 | } |
@@ -3143,7 +3155,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, | |||
3143 | lq_sta->total_failed, lq_sta->total_success, | 3155 | lq_sta->total_failed, lq_sta->total_success, |
3144 | lq_sta->active_legacy_rate); | 3156 | lq_sta->active_legacy_rate); |
3145 | desc += sprintf(buff+desc, "fixed rate 0x%X\n", | 3157 | desc += sprintf(buff+desc, "fixed rate 0x%X\n", |
3146 | lq_sta->dbg_fixed_rate); | 3158 | priv->dbg_fixed_rate); |
3147 | desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", | 3159 | desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", |
3148 | (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "", | 3160 | (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "", |
3149 | (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "", | 3161 | (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "", |
@@ -3254,14 +3266,10 @@ static const struct file_operations rs_sta_dbgfs_stats_table_ops = { | |||
3254 | static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file, | 3266 | static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file, |
3255 | char __user *user_buf, size_t count, loff_t *ppos) | 3267 | char __user *user_buf, size_t count, loff_t *ppos) |
3256 | { | 3268 | { |
3257 | char buff[120]; | ||
3258 | int desc = 0; | ||
3259 | |||
3260 | struct iwl_lq_sta *lq_sta = file->private_data; | 3269 | struct iwl_lq_sta *lq_sta = file->private_data; |
3261 | struct iwl_priv *priv; | ||
3262 | struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl]; | 3270 | struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl]; |
3263 | 3271 | char buff[120]; | |
3264 | priv = lq_sta->drv; | 3272 | int desc = 0; |
3265 | 3273 | ||
3266 | if (is_Ht(tbl->lq_type)) | 3274 | if (is_Ht(tbl->lq_type)) |
3267 | desc += sprintf(buff+desc, | 3275 | desc += sprintf(buff+desc, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 02387430f7fe..a95ad84c5377 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
@@ -289,7 +289,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
289 | /* cast away the const for active_rxon in this function */ | 289 | /* cast away the const for active_rxon in this function */ |
290 | struct iwl_rxon_cmd *active = (void *)&ctx->active; | 290 | struct iwl_rxon_cmd *active = (void *)&ctx->active; |
291 | bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); | 291 | bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); |
292 | bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK); | ||
293 | int ret; | 292 | int ret; |
294 | 293 | ||
295 | lockdep_assert_held(&priv->mutex); | 294 | lockdep_assert_held(&priv->mutex); |
@@ -389,11 +388,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
389 | * AP station must be done after the BSSID is set to correctly | 388 | * AP station must be done after the BSSID is set to correctly |
390 | * set up filters in the device. | 389 | * set up filters in the device. |
391 | */ | 390 | */ |
392 | if ((old_assoc && new_assoc) || !new_assoc) { | 391 | ret = iwlagn_rxon_disconn(priv, ctx); |
393 | ret = iwlagn_rxon_disconn(priv, ctx); | 392 | if (ret) |
394 | if (ret) | 393 | return ret; |
395 | return ret; | ||
396 | } | ||
397 | 394 | ||
398 | if (new_assoc) | 395 | if (new_assoc) |
399 | return iwlagn_rxon_connect(priv, ctx); | 396 | return iwlagn_rxon_connect(priv, ctx); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 079275f2c64d..0bd722cee5ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c | |||
@@ -144,7 +144,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, | |||
144 | size_t cmd_size = sizeof(struct iwl_wep_cmd); | 144 | size_t cmd_size = sizeof(struct iwl_wep_cmd); |
145 | struct iwl_host_cmd cmd = { | 145 | struct iwl_host_cmd cmd = { |
146 | .id = ctx->wep_key_cmd, | 146 | .id = ctx->wep_key_cmd, |
147 | .data = wep_cmd, | 147 | .data = { wep_cmd, }, |
148 | .flags = CMD_SYNC, | 148 | .flags = CMD_SYNC, |
149 | }; | 149 | }; |
150 | 150 | ||
@@ -172,7 +172,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, | |||
172 | 172 | ||
173 | cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX; | 173 | cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX; |
174 | 174 | ||
175 | cmd.len = cmd_size; | 175 | cmd.len[0] = cmd_size; |
176 | 176 | ||
177 | if (not_empty || send_if_empty) | 177 | if (not_empty || send_if_empty) |
178 | return iwl_send_cmd(priv, &cmd); | 178 | return iwl_send_cmd(priv, &cmd); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 342de780a366..4974cd7837cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
@@ -755,12 +755,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
755 | spin_unlock(&priv->sta_lock); | 755 | spin_unlock(&priv->sta_lock); |
756 | 756 | ||
757 | /* Attach buffers to TFD */ | 757 | /* Attach buffers to TFD */ |
758 | priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, | 758 | iwlagn_txq_attach_buf_to_tfd(priv, txq, txcmd_phys, firstlen, 1); |
759 | txcmd_phys, firstlen, 1, 0); | ||
760 | if (secondlen > 0) | 759 | if (secondlen > 0) |
761 | priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, | 760 | iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr, |
762 | phys_addr, secondlen, | 761 | secondlen, 0); |
763 | 0, 0); | ||
764 | 762 | ||
765 | scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + | 763 | scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + |
766 | offsetof(struct iwl_tx_cmd, scratch); | 764 | offsetof(struct iwl_tx_cmd, scratch); |
@@ -916,7 +914,7 @@ int iwlagn_txq_ctx_alloc(struct iwl_priv *priv) | |||
916 | spin_lock_irqsave(&priv->lock, flags); | 914 | spin_lock_irqsave(&priv->lock, flags); |
917 | 915 | ||
918 | /* Turn off all Tx DMA fifos */ | 916 | /* Turn off all Tx DMA fifos */ |
919 | priv->cfg->ops->lib->txq_set_sched(priv, 0); | 917 | iwlagn_txq_set_sched(priv, 0); |
920 | 918 | ||
921 | /* Tell NIC where to find the "keep warm" buffer */ | 919 | /* Tell NIC where to find the "keep warm" buffer */ |
922 | iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); | 920 | iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); |
@@ -954,7 +952,7 @@ void iwlagn_txq_ctx_reset(struct iwl_priv *priv) | |||
954 | spin_lock_irqsave(&priv->lock, flags); | 952 | spin_lock_irqsave(&priv->lock, flags); |
955 | 953 | ||
956 | /* Turn off all Tx DMA fifos */ | 954 | /* Turn off all Tx DMA fifos */ |
957 | priv->cfg->ops->lib->txq_set_sched(priv, 0); | 955 | iwlagn_txq_set_sched(priv, 0); |
958 | 956 | ||
959 | /* Tell NIC where to find the "keep warm" buffer */ | 957 | /* Tell NIC where to find the "keep warm" buffer */ |
960 | iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); | 958 | iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); |
@@ -980,7 +978,7 @@ void iwlagn_txq_ctx_stop(struct iwl_priv *priv) | |||
980 | /* Turn off all Tx DMA fifos */ | 978 | /* Turn off all Tx DMA fifos */ |
981 | spin_lock_irqsave(&priv->lock, flags); | 979 | spin_lock_irqsave(&priv->lock, flags); |
982 | 980 | ||
983 | priv->cfg->ops->lib->txq_set_sched(priv, 0); | 981 | iwlagn_txq_set_sched(priv, 0); |
984 | 982 | ||
985 | /* Stop each Tx DMA channel, and wait for it to be idle */ | 983 | /* Stop each Tx DMA channel, and wait for it to be idle */ |
986 | for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) { | 984 | for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) { |
@@ -1263,7 +1261,7 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | |||
1263 | 1261 | ||
1264 | iwlagn_txq_inval_byte_cnt_tbl(priv, txq); | 1262 | iwlagn_txq_inval_byte_cnt_tbl(priv, txq); |
1265 | 1263 | ||
1266 | priv->cfg->ops->lib->txq_free_tfd(priv, txq); | 1264 | iwlagn_txq_free_tfd(priv, txq); |
1267 | } | 1265 | } |
1268 | return nfreed; | 1266 | return nfreed; |
1269 | } | 1267 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 8bda0e8d6661..97de5d9de67b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | |||
@@ -217,8 +217,8 @@ static int iwlagn_send_calib_cfg(struct iwl_priv *priv) | |||
217 | struct iwl_calib_cfg_cmd calib_cfg_cmd; | 217 | struct iwl_calib_cfg_cmd calib_cfg_cmd; |
218 | struct iwl_host_cmd cmd = { | 218 | struct iwl_host_cmd cmd = { |
219 | .id = CALIBRATION_CFG_CMD, | 219 | .id = CALIBRATION_CFG_CMD, |
220 | .len = sizeof(struct iwl_calib_cfg_cmd), | 220 | .len = { sizeof(struct iwl_calib_cfg_cmd), }, |
221 | .data = &calib_cfg_cmd, | 221 | .data = { &calib_cfg_cmd, }, |
222 | }; | 222 | }; |
223 | 223 | ||
224 | memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd)); | 224 | memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd)); |
@@ -440,7 +440,7 @@ static int iwlagn_alive_notify(struct iwl_priv *priv) | |||
440 | IWL_MASK(0, priv->hw_params.max_txq_num)); | 440 | IWL_MASK(0, priv->hw_params.max_txq_num)); |
441 | 441 | ||
442 | /* Activate all Tx DMA/FIFO channels */ | 442 | /* Activate all Tx DMA/FIFO channels */ |
443 | priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7)); | 443 | iwlagn_txq_set_sched(priv, IWL_MASK(0, 7)); |
444 | 444 | ||
445 | /* map queues to FIFOs */ | 445 | /* map queues to FIFOs */ |
446 | if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) | 446 | if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 08e3cae4fa5a..11c6c1169e78 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -134,12 +134,10 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) | |||
134 | struct iwl_tx_beacon_cmd *tx_beacon_cmd; | 134 | struct iwl_tx_beacon_cmd *tx_beacon_cmd; |
135 | struct iwl_host_cmd cmd = { | 135 | struct iwl_host_cmd cmd = { |
136 | .id = REPLY_TX_BEACON, | 136 | .id = REPLY_TX_BEACON, |
137 | .flags = CMD_SIZE_HUGE, | ||
138 | }; | 137 | }; |
139 | u32 frame_size; | 138 | u32 frame_size; |
140 | u32 rate_flags; | 139 | u32 rate_flags; |
141 | u32 rate; | 140 | u32 rate; |
142 | int err; | ||
143 | 141 | ||
144 | /* | 142 | /* |
145 | * We have to set up the TX command, the TX Beacon command, and the | 143 | * We have to set up the TX command, the TX Beacon command, and the |
@@ -156,17 +154,15 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) | |||
156 | if (WARN_ON(!priv->beacon_skb)) | 154 | if (WARN_ON(!priv->beacon_skb)) |
157 | return -EINVAL; | 155 | return -EINVAL; |
158 | 156 | ||
159 | /* Allocate beacon memory */ | 157 | /* Allocate beacon command */ |
160 | tx_beacon_cmd = kzalloc(sizeof(*tx_beacon_cmd) + priv->beacon_skb->len, | 158 | if (!priv->beacon_cmd) |
161 | GFP_KERNEL); | 159 | priv->beacon_cmd = kzalloc(sizeof(*tx_beacon_cmd), GFP_KERNEL); |
160 | tx_beacon_cmd = priv->beacon_cmd; | ||
162 | if (!tx_beacon_cmd) | 161 | if (!tx_beacon_cmd) |
163 | return -ENOMEM; | 162 | return -ENOMEM; |
164 | 163 | ||
165 | frame_size = priv->beacon_skb->len; | 164 | frame_size = priv->beacon_skb->len; |
166 | 165 | ||
167 | /* Set up TX beacon contents */ | ||
168 | memcpy(tx_beacon_cmd->frame, priv->beacon_skb->data, frame_size); | ||
169 | |||
170 | /* Set up TX command fields */ | 166 | /* Set up TX command fields */ |
171 | tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); | 167 | tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); |
172 | tx_beacon_cmd->tx.sta_id = priv->beacon_ctx->bcast_sta_id; | 168 | tx_beacon_cmd->tx.sta_id = priv->beacon_ctx->bcast_sta_id; |
@@ -175,7 +171,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) | |||
175 | TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK; | 171 | TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK; |
176 | 172 | ||
177 | /* Set up TX beacon command fields */ | 173 | /* Set up TX beacon command fields */ |
178 | iwl_set_beacon_tim(priv, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame, | 174 | iwl_set_beacon_tim(priv, tx_beacon_cmd, priv->beacon_skb->data, |
179 | frame_size); | 175 | frame_size); |
180 | 176 | ||
181 | /* Set up packet rate and flags */ | 177 | /* Set up packet rate and flags */ |
@@ -189,164 +185,14 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) | |||
189 | rate_flags); | 185 | rate_flags); |
190 | 186 | ||
191 | /* Submit command */ | 187 | /* Submit command */ |
192 | cmd.len = sizeof(*tx_beacon_cmd) + frame_size; | 188 | cmd.len[0] = sizeof(*tx_beacon_cmd); |
193 | cmd.data = tx_beacon_cmd; | 189 | cmd.data[0] = tx_beacon_cmd; |
194 | 190 | cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; | |
195 | err = iwl_send_cmd_sync(priv, &cmd); | 191 | cmd.len[1] = frame_size; |
196 | 192 | cmd.data[1] = priv->beacon_skb->data; | |
197 | /* Free temporary storage */ | 193 | cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY; |
198 | kfree(tx_beacon_cmd); | ||
199 | |||
200 | return err; | ||
201 | } | ||
202 | |||
203 | static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) | ||
204 | { | ||
205 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | ||
206 | 194 | ||
207 | dma_addr_t addr = get_unaligned_le32(&tb->lo); | 195 | return iwl_send_cmd_sync(priv, &cmd); |
208 | if (sizeof(dma_addr_t) > sizeof(u32)) | ||
209 | addr |= | ||
210 | ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16; | ||
211 | |||
212 | return addr; | ||
213 | } | ||
214 | |||
215 | static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx) | ||
216 | { | ||
217 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | ||
218 | |||
219 | return le16_to_cpu(tb->hi_n_len) >> 4; | ||
220 | } | ||
221 | |||
222 | static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx, | ||
223 | dma_addr_t addr, u16 len) | ||
224 | { | ||
225 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | ||
226 | u16 hi_n_len = len << 4; | ||
227 | |||
228 | put_unaligned_le32(addr, &tb->lo); | ||
229 | if (sizeof(dma_addr_t) > sizeof(u32)) | ||
230 | hi_n_len |= ((addr >> 16) >> 16) & 0xF; | ||
231 | |||
232 | tb->hi_n_len = cpu_to_le16(hi_n_len); | ||
233 | |||
234 | tfd->num_tbs = idx + 1; | ||
235 | } | ||
236 | |||
237 | static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) | ||
238 | { | ||
239 | return tfd->num_tbs & 0x1f; | ||
240 | } | ||
241 | |||
242 | /** | ||
243 | * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] | ||
244 | * @priv - driver private data | ||
245 | * @txq - tx queue | ||
246 | * | ||
247 | * Does NOT advance any TFD circular buffer read/write indexes | ||
248 | * Does NOT free the TFD itself (which is within circular buffer) | ||
249 | */ | ||
250 | void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) | ||
251 | { | ||
252 | struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)txq->tfds; | ||
253 | struct iwl_tfd *tfd; | ||
254 | struct pci_dev *dev = priv->pci_dev; | ||
255 | int index = txq->q.read_ptr; | ||
256 | int i; | ||
257 | int num_tbs; | ||
258 | |||
259 | tfd = &tfd_tmp[index]; | ||
260 | |||
261 | /* Sanity check on number of chunks */ | ||
262 | num_tbs = iwl_tfd_get_num_tbs(tfd); | ||
263 | |||
264 | if (num_tbs >= IWL_NUM_OF_TBS) { | ||
265 | IWL_ERR(priv, "Too many chunks: %i\n", num_tbs); | ||
266 | /* @todo issue fatal error, it is quite serious situation */ | ||
267 | return; | ||
268 | } | ||
269 | |||
270 | /* Unmap tx_cmd */ | ||
271 | if (num_tbs) | ||
272 | pci_unmap_single(dev, | ||
273 | dma_unmap_addr(&txq->meta[index], mapping), | ||
274 | dma_unmap_len(&txq->meta[index], len), | ||
275 | PCI_DMA_BIDIRECTIONAL); | ||
276 | |||
277 | /* Unmap chunks, if any. */ | ||
278 | for (i = 1; i < num_tbs; i++) | ||
279 | pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i), | ||
280 | iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE); | ||
281 | |||
282 | /* free SKB */ | ||
283 | if (txq->txb) { | ||
284 | struct sk_buff *skb; | ||
285 | |||
286 | skb = txq->txb[txq->q.read_ptr].skb; | ||
287 | |||
288 | /* can be called from irqs-disabled context */ | ||
289 | if (skb) { | ||
290 | dev_kfree_skb_any(skb); | ||
291 | txq->txb[txq->q.read_ptr].skb = NULL; | ||
292 | } | ||
293 | } | ||
294 | } | ||
295 | |||
296 | int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, | ||
297 | struct iwl_tx_queue *txq, | ||
298 | dma_addr_t addr, u16 len, | ||
299 | u8 reset, u8 pad) | ||
300 | { | ||
301 | struct iwl_queue *q; | ||
302 | struct iwl_tfd *tfd, *tfd_tmp; | ||
303 | u32 num_tbs; | ||
304 | |||
305 | q = &txq->q; | ||
306 | tfd_tmp = (struct iwl_tfd *)txq->tfds; | ||
307 | tfd = &tfd_tmp[q->write_ptr]; | ||
308 | |||
309 | if (reset) | ||
310 | memset(tfd, 0, sizeof(*tfd)); | ||
311 | |||
312 | num_tbs = iwl_tfd_get_num_tbs(tfd); | ||
313 | |||
314 | /* Each TFD can point to a maximum 20 Tx buffers */ | ||
315 | if (num_tbs >= IWL_NUM_OF_TBS) { | ||
316 | IWL_ERR(priv, "Error can not send more than %d chunks\n", | ||
317 | IWL_NUM_OF_TBS); | ||
318 | return -EINVAL; | ||
319 | } | ||
320 | |||
321 | if (WARN_ON(addr & ~DMA_BIT_MASK(36))) | ||
322 | return -EINVAL; | ||
323 | |||
324 | if (unlikely(addr & ~IWL_TX_DMA_MASK)) | ||
325 | IWL_ERR(priv, "Unaligned address = %llx\n", | ||
326 | (unsigned long long)addr); | ||
327 | |||
328 | iwl_tfd_set_tb(tfd, num_tbs, addr, len); | ||
329 | |||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | /* | ||
334 | * Tell nic where to find circular buffer of Tx Frame Descriptors for | ||
335 | * given Tx queue, and enable the DMA channel used for that queue. | ||
336 | * | ||
337 | * supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA | ||
338 | * channels supported in hardware. | ||
339 | */ | ||
340 | int iwl_hw_tx_queue_init(struct iwl_priv *priv, | ||
341 | struct iwl_tx_queue *txq) | ||
342 | { | ||
343 | int txq_id = txq->q.id; | ||
344 | |||
345 | /* Circular buffer (TFD queue in DRAM) physical base address */ | ||
346 | iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), | ||
347 | txq->q.dma_addr >> 8); | ||
348 | |||
349 | return 0; | ||
350 | } | 196 | } |
351 | 197 | ||
352 | static void iwl_bg_beacon_update(struct work_struct *work) | 198 | static void iwl_bg_beacon_update(struct work_struct *work) |
@@ -1776,10 +1622,7 @@ static const char *desc_lookup(u32 num) | |||
1776 | 1622 | ||
1777 | void iwl_dump_nic_error_log(struct iwl_priv *priv) | 1623 | void iwl_dump_nic_error_log(struct iwl_priv *priv) |
1778 | { | 1624 | { |
1779 | u32 data2, line; | 1625 | u32 base; |
1780 | u32 desc, time, count, base, data1; | ||
1781 | u32 blink1, blink2, ilink1, ilink2; | ||
1782 | u32 pc, hcmd; | ||
1783 | struct iwl_error_event_table table; | 1626 | struct iwl_error_event_table table; |
1784 | 1627 | ||
1785 | base = priv->device_pointers.error_event_table; | 1628 | base = priv->device_pointers.error_event_table; |
@@ -1802,37 +1645,40 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
1802 | 1645 | ||
1803 | iwl_read_targ_mem_words(priv, base, &table, sizeof(table)); | 1646 | iwl_read_targ_mem_words(priv, base, &table, sizeof(table)); |
1804 | 1647 | ||
1805 | count = table.valid; | 1648 | if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { |
1806 | |||
1807 | if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { | ||
1808 | IWL_ERR(priv, "Start IWL Error Log Dump:\n"); | 1649 | IWL_ERR(priv, "Start IWL Error Log Dump:\n"); |
1809 | IWL_ERR(priv, "Status: 0x%08lX, count: %d\n", | 1650 | IWL_ERR(priv, "Status: 0x%08lX, count: %d\n", |
1810 | priv->status, count); | 1651 | priv->status, table.valid); |
1811 | } | 1652 | } |
1812 | 1653 | ||
1813 | desc = table.error_id; | 1654 | priv->isr_stats.err_code = table.error_id; |
1814 | priv->isr_stats.err_code = desc; | 1655 | |
1815 | pc = table.pc; | 1656 | trace_iwlwifi_dev_ucode_error(priv, table.error_id, table.tsf_low, |
1816 | blink1 = table.blink1; | 1657 | table.data1, table.data2, table.line, |
1817 | blink2 = table.blink2; | 1658 | table.blink1, table.blink2, table.ilink1, |
1818 | ilink1 = table.ilink1; | 1659 | table.ilink2, table.bcon_time, table.gp1, |
1819 | ilink2 = table.ilink2; | 1660 | table.gp2, table.gp3, table.ucode_ver, |
1820 | data1 = table.data1; | 1661 | table.hw_ver, table.brd_ver); |
1821 | data2 = table.data2; | 1662 | IWL_ERR(priv, "0x%08X | %-28s\n", table.error_id, |
1822 | line = table.line; | 1663 | desc_lookup(table.error_id)); |
1823 | time = table.tsf_low; | 1664 | IWL_ERR(priv, "0x%08X | uPc\n", table.pc); |
1824 | hcmd = table.hcmd; | 1665 | IWL_ERR(priv, "0x%08X | branchlink1\n", table.blink1); |
1825 | 1666 | IWL_ERR(priv, "0x%08X | branchlink2\n", table.blink2); | |
1826 | trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line, | 1667 | IWL_ERR(priv, "0x%08X | interruptlink1\n", table.ilink1); |
1827 | blink1, blink2, ilink1, ilink2); | 1668 | IWL_ERR(priv, "0x%08X | interruptlink2\n", table.ilink2); |
1828 | 1669 | IWL_ERR(priv, "0x%08X | data1\n", table.data1); | |
1829 | IWL_ERR(priv, "Desc Time " | 1670 | IWL_ERR(priv, "0x%08X | data2\n", table.data2); |
1830 | "data1 data2 line\n"); | 1671 | IWL_ERR(priv, "0x%08X | line\n", table.line); |
1831 | IWL_ERR(priv, "%-28s (0x%04X) %010u 0x%08X 0x%08X %u\n", | 1672 | IWL_ERR(priv, "0x%08X | beacon time\n", table.bcon_time); |
1832 | desc_lookup(desc), desc, time, data1, data2, line); | 1673 | IWL_ERR(priv, "0x%08X | tsf low\n", table.tsf_low); |
1833 | IWL_ERR(priv, "pc blink1 blink2 ilink1 ilink2 hcmd\n"); | 1674 | IWL_ERR(priv, "0x%08X | tsf hi\n", table.tsf_hi); |
1834 | IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X 0x%05X 0x%05X\n", | 1675 | IWL_ERR(priv, "0x%08X | time gp1\n", table.gp1); |
1835 | pc, blink1, blink2, ilink1, ilink2, hcmd); | 1676 | IWL_ERR(priv, "0x%08X | time gp2\n", table.gp2); |
1677 | IWL_ERR(priv, "0x%08X | time gp3\n", table.gp3); | ||
1678 | IWL_ERR(priv, "0x%08X | uCode version\n", table.ucode_ver); | ||
1679 | IWL_ERR(priv, "0x%08X | hw version\n", table.hw_ver); | ||
1680 | IWL_ERR(priv, "0x%08X | board version\n", table.brd_ver); | ||
1681 | IWL_ERR(priv, "0x%08X | hcmd\n", table.hcmd); | ||
1836 | } | 1682 | } |
1837 | 1683 | ||
1838 | #define EVENT_START_OFFSET (4 * sizeof(u32)) | 1684 | #define EVENT_START_OFFSET (4 * sizeof(u32)) |
@@ -2114,8 +1960,8 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg) | |||
2114 | struct iwl_calib_cfg_cmd calib_cfg_cmd; | 1960 | struct iwl_calib_cfg_cmd calib_cfg_cmd; |
2115 | struct iwl_host_cmd cmd = { | 1961 | struct iwl_host_cmd cmd = { |
2116 | .id = CALIBRATION_CFG_CMD, | 1962 | .id = CALIBRATION_CFG_CMD, |
2117 | .len = sizeof(struct iwl_calib_cfg_cmd), | 1963 | .len = { sizeof(struct iwl_calib_cfg_cmd), }, |
2118 | .data = &calib_cfg_cmd, | 1964 | .data = { &calib_cfg_cmd, }, |
2119 | }; | 1965 | }; |
2120 | 1966 | ||
2121 | memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd)); | 1967 | memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd)); |
@@ -3395,6 +3241,7 @@ static void iwl_uninit_drv(struct iwl_priv *priv) | |||
3395 | iwlcore_free_geos(priv); | 3241 | iwlcore_free_geos(priv); |
3396 | iwl_free_channel_map(priv); | 3242 | iwl_free_channel_map(priv); |
3397 | kfree(priv->scan_cmd); | 3243 | kfree(priv->scan_cmd); |
3244 | kfree(priv->beacon_cmd); | ||
3398 | } | 3245 | } |
3399 | 3246 | ||
3400 | struct ieee80211_ops iwlagn_hw_ops = { | 3247 | struct ieee80211_ops iwlagn_hw_ops = { |
@@ -3812,6 +3659,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
3812 | */ | 3659 | */ |
3813 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 3660 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
3814 | 3661 | ||
3662 | iwl_testmode_cleanup(priv); | ||
3815 | iwl_leds_exit(priv); | 3663 | iwl_leds_exit(priv); |
3816 | 3664 | ||
3817 | if (priv->mac80211_registered) { | 3665 | if (priv->mac80211_registered) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index fe33fe8aa418..2495fe7a58cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -191,12 +191,10 @@ int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); | |||
191 | void iwl_setup_rx_handlers(struct iwl_priv *priv); | 191 | void iwl_setup_rx_handlers(struct iwl_priv *priv); |
192 | 192 | ||
193 | /* tx */ | 193 | /* tx */ |
194 | void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); | 194 | void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); |
195 | int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, | 195 | int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv, |
196 | struct iwl_tx_queue *txq, | 196 | struct iwl_tx_queue *txq, |
197 | dma_addr_t addr, u16 len, u8 reset, u8 pad); | 197 | dma_addr_t addr, u16 len, u8 reset); |
198 | int iwl_hw_tx_queue_init(struct iwl_priv *priv, | ||
199 | struct iwl_tx_queue *txq); | ||
200 | void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, | 198 | void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, |
201 | struct ieee80211_tx_info *info); | 199 | struct ieee80211_tx_info *info); |
202 | int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb); | 200 | int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb); |
@@ -345,6 +343,7 @@ extern int iwl_alive_start(struct iwl_priv *priv); | |||
345 | #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL | 343 | #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL |
346 | extern int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len); | 344 | extern int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len); |
347 | extern void iwl_testmode_init(struct iwl_priv *priv); | 345 | extern void iwl_testmode_init(struct iwl_priv *priv); |
346 | extern void iwl_testmode_cleanup(struct iwl_priv *priv); | ||
348 | #else | 347 | #else |
349 | static inline | 348 | static inline |
350 | int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) | 349 | int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) |
@@ -355,6 +354,10 @@ static inline | |||
355 | void iwl_testmode_init(struct iwl_priv *priv) | 354 | void iwl_testmode_init(struct iwl_priv *priv) |
356 | { | 355 | { |
357 | } | 356 | } |
357 | static inline | ||
358 | void iwl_testmode_cleanup(struct iwl_priv *priv) | ||
359 | { | ||
360 | } | ||
358 | #endif | 361 | #endif |
359 | 362 | ||
360 | #endif /* __iwl_agn_h__ */ | 363 | #endif /* __iwl_agn_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 5fdad6532118..6ee5f1aa555c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -205,7 +205,6 @@ enum { | |||
205 | #define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) | 205 | #define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) |
206 | #define SEQ_TO_INDEX(s) ((s) & 0xff) | 206 | #define SEQ_TO_INDEX(s) ((s) & 0xff) |
207 | #define INDEX_TO_SEQ(i) ((i) & 0xff) | 207 | #define INDEX_TO_SEQ(i) ((i) & 0xff) |
208 | #define SEQ_HUGE_FRAME cpu_to_le16(0x4000) | ||
209 | #define SEQ_RX_FRAME cpu_to_le16(0x8000) | 208 | #define SEQ_RX_FRAME cpu_to_le16(0x8000) |
210 | 209 | ||
211 | /** | 210 | /** |
@@ -234,9 +233,7 @@ struct iwl_cmd_header { | |||
234 | * | 233 | * |
235 | * 0:7 tfd index - position within TX queue | 234 | * 0:7 tfd index - position within TX queue |
236 | * 8:12 TX queue id | 235 | * 8:12 TX queue id |
237 | * 13 reserved | 236 | * 13:14 reserved |
238 | * 14 huge - driver sets this to indicate command is in the | ||
239 | * 'huge' storage at the end of the command buffers | ||
240 | * 15 unsolicited RX or uCode-originated notification | 237 | * 15 unsolicited RX or uCode-originated notification |
241 | */ | 238 | */ |
242 | __le16 sequence; | 239 | __le16 sequence; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 5b5b0cce4a54..3bb76f6ea410 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -127,16 +127,6 @@ struct iwl_temp_ops { | |||
127 | struct iwl_lib_ops { | 127 | struct iwl_lib_ops { |
128 | /* set hw dependent parameters */ | 128 | /* set hw dependent parameters */ |
129 | int (*set_hw_params)(struct iwl_priv *priv); | 129 | int (*set_hw_params)(struct iwl_priv *priv); |
130 | /* Handling TX */ | ||
131 | void (*txq_set_sched)(struct iwl_priv *priv, u32 mask); | ||
132 | int (*txq_attach_buf_to_tfd)(struct iwl_priv *priv, | ||
133 | struct iwl_tx_queue *txq, | ||
134 | dma_addr_t addr, | ||
135 | u16 len, u8 reset, u8 pad); | ||
136 | void (*txq_free_tfd)(struct iwl_priv *priv, | ||
137 | struct iwl_tx_queue *txq); | ||
138 | int (*txq_init)(struct iwl_priv *priv, | ||
139 | struct iwl_tx_queue *txq); | ||
140 | /* setup Rx handler */ | 130 | /* setup Rx handler */ |
141 | void (*rx_handler_setup)(struct iwl_priv *priv); | 131 | void (*rx_handler_setup)(struct iwl_priv *priv); |
142 | /* setup deferred work */ | 132 | /* setup deferred work */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 214e4658c495..22a6e3ec7094 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -48,8 +48,6 @@ | |||
48 | #include "iwl-agn-rs.h" | 48 | #include "iwl-agn-rs.h" |
49 | #include "iwl-agn-tt.h" | 49 | #include "iwl-agn-tt.h" |
50 | 50 | ||
51 | #define U32_PAD(n) ((4-(n))&0x3) | ||
52 | |||
53 | struct iwl_tx_queue; | 51 | struct iwl_tx_queue; |
54 | 52 | ||
55 | /* CT-KILL constants */ | 53 | /* CT-KILL constants */ |
@@ -83,7 +81,7 @@ struct iwl_tx_queue; | |||
83 | #define MAX_RTS_THRESHOLD 2347U | 81 | #define MAX_RTS_THRESHOLD 2347U |
84 | #define MAX_MSDU_SIZE 2304U | 82 | #define MAX_MSDU_SIZE 2304U |
85 | #define MAX_MPDU_SIZE 2346U | 83 | #define MAX_MPDU_SIZE 2346U |
86 | #define DEFAULT_BEACON_INTERVAL 100U | 84 | #define DEFAULT_BEACON_INTERVAL 200U |
87 | #define DEFAULT_SHORT_RETRY_LIMIT 7U | 85 | #define DEFAULT_SHORT_RETRY_LIMIT 7U |
88 | #define DEFAULT_LONG_RETRY_LIMIT 4U | 86 | #define DEFAULT_LONG_RETRY_LIMIT 4U |
89 | 87 | ||
@@ -112,8 +110,6 @@ struct iwl_cmd_meta { | |||
112 | struct iwl_device_cmd *cmd, | 110 | struct iwl_device_cmd *cmd, |
113 | struct iwl_rx_packet *pkt); | 111 | struct iwl_rx_packet *pkt); |
114 | 112 | ||
115 | /* The CMD_SIZE_HUGE flag bit indicates that the command | ||
116 | * structure is stored at the end of the shared queue memory. */ | ||
117 | u32 flags; | 113 | u32 flags; |
118 | 114 | ||
119 | DEFINE_DMA_UNMAP_ADDR(mapping); | 115 | DEFINE_DMA_UNMAP_ADDR(mapping); |
@@ -123,7 +119,23 @@ struct iwl_cmd_meta { | |||
123 | /* | 119 | /* |
124 | * Generic queue structure | 120 | * Generic queue structure |
125 | * | 121 | * |
126 | * Contains common data for Rx and Tx queues | 122 | * Contains common data for Rx and Tx queues. |
123 | * | ||
124 | * Note the difference between n_bd and n_window: the hardware | ||
125 | * always assumes 256 descriptors, so n_bd is always 256 (unless | ||
126 | * there might be HW changes in the future). For the normal TX | ||
127 | * queues, n_window, which is the size of the software queue data | ||
128 | * is also 256; however, for the command queue, n_window is only | ||
129 | * 32 since we don't need so many commands pending. Since the HW | ||
130 | * still uses 256 BDs for DMA though, n_bd stays 256. As a result, | ||
131 | * the software buffers (in the variables @meta, @txb in struct | ||
132 | * iwl_tx_queue) only have 32 entries, while the HW buffers (@tfds | ||
133 | * in the same struct) have 256. | ||
134 | * This means that we end up with the following: | ||
135 | * HW entries: | 0 | ... | N * 32 | ... | N * 32 + 31 | ... | 255 | | ||
136 | * SW entries: | 0 | ... | 31 | | ||
137 | * where N is a number between 0 and 7. This means that the SW | ||
138 | * data is a window overlayed over the HW queue. | ||
127 | */ | 139 | */ |
128 | struct iwl_queue { | 140 | struct iwl_queue { |
129 | int n_bd; /* number of BDs in this queue */ | 141 | int n_bd; /* number of BDs in this queue */ |
@@ -165,7 +177,7 @@ struct iwl_tx_info { | |||
165 | 177 | ||
166 | struct iwl_tx_queue { | 178 | struct iwl_tx_queue { |
167 | struct iwl_queue q; | 179 | struct iwl_queue q; |
168 | void *tfds; | 180 | struct iwl_tfd *tfds; |
169 | struct iwl_device_cmd **cmd; | 181 | struct iwl_device_cmd **cmd; |
170 | struct iwl_cmd_meta *meta; | 182 | struct iwl_cmd_meta *meta; |
171 | struct iwl_tx_info *txb; | 183 | struct iwl_tx_info *txb; |
@@ -247,7 +259,6 @@ enum { | |||
247 | CMD_SYNC = 0, | 259 | CMD_SYNC = 0, |
248 | CMD_SIZE_NORMAL = 0, | 260 | CMD_SIZE_NORMAL = 0, |
249 | CMD_NO_SKB = 0, | 261 | CMD_NO_SKB = 0, |
250 | CMD_SIZE_HUGE = (1 << 0), | ||
251 | CMD_ASYNC = (1 << 1), | 262 | CMD_ASYNC = (1 << 1), |
252 | CMD_WANT_SKB = (1 << 2), | 263 | CMD_WANT_SKB = (1 << 2), |
253 | CMD_MAPPED = (1 << 3), | 264 | CMD_MAPPED = (1 << 3), |
@@ -259,8 +270,8 @@ enum { | |||
259 | * struct iwl_device_cmd | 270 | * struct iwl_device_cmd |
260 | * | 271 | * |
261 | * For allocation of the command and tx queues, this establishes the overall | 272 | * For allocation of the command and tx queues, this establishes the overall |
262 | * size of the largest command we send to uCode, except for a scan command | 273 | * size of the largest command we send to uCode, except for commands that |
263 | * (which is relatively huge; space is allocated separately). | 274 | * aren't fully copied and use other TFD space. |
264 | */ | 275 | */ |
265 | struct iwl_device_cmd { | 276 | struct iwl_device_cmd { |
266 | struct iwl_cmd_header hdr; /* uCode API */ | 277 | struct iwl_cmd_header hdr; /* uCode API */ |
@@ -277,15 +288,21 @@ struct iwl_device_cmd { | |||
277 | 288 | ||
278 | #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) | 289 | #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) |
279 | 290 | ||
291 | #define IWL_MAX_CMD_TFDS 2 | ||
292 | |||
293 | enum iwl_hcmd_dataflag { | ||
294 | IWL_HCMD_DFL_NOCOPY = BIT(0), | ||
295 | }; | ||
280 | 296 | ||
281 | struct iwl_host_cmd { | 297 | struct iwl_host_cmd { |
282 | const void *data; | 298 | const void *data[IWL_MAX_CMD_TFDS]; |
283 | unsigned long reply_page; | 299 | unsigned long reply_page; |
284 | void (*callback)(struct iwl_priv *priv, | 300 | void (*callback)(struct iwl_priv *priv, |
285 | struct iwl_device_cmd *cmd, | 301 | struct iwl_device_cmd *cmd, |
286 | struct iwl_rx_packet *pkt); | 302 | struct iwl_rx_packet *pkt); |
287 | u32 flags; | 303 | u32 flags; |
288 | u16 len; | 304 | u16 len[IWL_MAX_CMD_TFDS]; |
305 | u8 dataflags[IWL_MAX_CMD_TFDS]; | ||
289 | u8 id; | 306 | u8 id; |
290 | }; | 307 | }; |
291 | 308 | ||
@@ -688,17 +705,8 @@ static inline int iwl_queue_used(const struct iwl_queue *q, int i) | |||
688 | } | 705 | } |
689 | 706 | ||
690 | 707 | ||
691 | static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge) | 708 | static inline u8 get_cmd_index(struct iwl_queue *q, u32 index) |
692 | { | 709 | { |
693 | /* | ||
694 | * This is for init calibration result and scan command which | ||
695 | * required buffer > TFD_MAX_PAYLOAD_SIZE, | ||
696 | * the big buffer at end of command array | ||
697 | */ | ||
698 | if (is_huge) | ||
699 | return q->n_window; /* must be power of 2 */ | ||
700 | |||
701 | /* Otherwise, use normal size buffers */ | ||
702 | return index & (q->n_window - 1); | 710 | return index & (q->n_window - 1); |
703 | } | 711 | } |
704 | 712 | ||
@@ -1171,6 +1179,14 @@ enum iwl_scan_type { | |||
1171 | IWL_SCAN_OFFCH_TX, | 1179 | IWL_SCAN_OFFCH_TX, |
1172 | }; | 1180 | }; |
1173 | 1181 | ||
1182 | #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL | ||
1183 | struct iwl_testmode_trace { | ||
1184 | u8 *cpu_addr; | ||
1185 | u8 *trace_addr; | ||
1186 | dma_addr_t dma_addr; | ||
1187 | bool trace_enabled; | ||
1188 | }; | ||
1189 | #endif | ||
1174 | struct iwl_priv { | 1190 | struct iwl_priv { |
1175 | 1191 | ||
1176 | /* ieee device used by generic ieee processing code */ | 1192 | /* ieee device used by generic ieee processing code */ |
@@ -1452,6 +1468,7 @@ struct iwl_priv { | |||
1452 | struct work_struct beacon_update; | 1468 | struct work_struct beacon_update; |
1453 | struct iwl_rxon_context *beacon_ctx; | 1469 | struct iwl_rxon_context *beacon_ctx; |
1454 | struct sk_buff *beacon_skb; | 1470 | struct sk_buff *beacon_skb; |
1471 | void *beacon_cmd; | ||
1455 | 1472 | ||
1456 | struct work_struct tt_work; | 1473 | struct work_struct tt_work; |
1457 | struct work_struct ct_enter; | 1474 | struct work_struct ct_enter; |
@@ -1501,6 +1518,11 @@ struct iwl_priv { | |||
1501 | struct led_classdev led; | 1518 | struct led_classdev led; |
1502 | unsigned long blink_on, blink_off; | 1519 | unsigned long blink_on, blink_off; |
1503 | bool led_registered; | 1520 | bool led_registered; |
1521 | #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL | ||
1522 | struct iwl_testmode_trace testmode_trace; | ||
1523 | #endif | ||
1524 | u32 dbg_fixed_rate; | ||
1525 | |||
1504 | }; /*iwl_priv */ | 1526 | }; /*iwl_priv */ |
1505 | 1527 | ||
1506 | static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) | 1528 | static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index f00172cb8a6d..2c84ba95afca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h | |||
@@ -137,20 +137,27 @@ TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, | |||
137 | #define TRACE_SYSTEM iwlwifi | 137 | #define TRACE_SYSTEM iwlwifi |
138 | 138 | ||
139 | TRACE_EVENT(iwlwifi_dev_hcmd, | 139 | TRACE_EVENT(iwlwifi_dev_hcmd, |
140 | TP_PROTO(struct iwl_priv *priv, void *hcmd, size_t len, u32 flags), | 140 | TP_PROTO(struct iwl_priv *priv, u32 flags, |
141 | TP_ARGS(priv, hcmd, len, flags), | 141 | const void *hcmd0, size_t len0, |
142 | const void *hcmd1, size_t len1, | ||
143 | const void *hcmd2, size_t len2), | ||
144 | TP_ARGS(priv, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2), | ||
142 | TP_STRUCT__entry( | 145 | TP_STRUCT__entry( |
143 | PRIV_ENTRY | 146 | PRIV_ENTRY |
144 | __dynamic_array(u8, hcmd, len) | 147 | __dynamic_array(u8, hcmd0, len0) |
148 | __dynamic_array(u8, hcmd1, len1) | ||
149 | __dynamic_array(u8, hcmd2, len2) | ||
145 | __field(u32, flags) | 150 | __field(u32, flags) |
146 | ), | 151 | ), |
147 | TP_fast_assign( | 152 | TP_fast_assign( |
148 | PRIV_ASSIGN; | 153 | PRIV_ASSIGN; |
149 | memcpy(__get_dynamic_array(hcmd), hcmd, len); | 154 | memcpy(__get_dynamic_array(hcmd0), hcmd0, len0); |
155 | memcpy(__get_dynamic_array(hcmd1), hcmd1, len1); | ||
156 | memcpy(__get_dynamic_array(hcmd2), hcmd2, len2); | ||
150 | __entry->flags = flags; | 157 | __entry->flags = flags; |
151 | ), | 158 | ), |
152 | TP_printk("[%p] hcmd %#.2x (%ssync)", | 159 | TP_printk("[%p] hcmd %#.2x (%ssync)", |
153 | __entry->priv, ((u8 *)__get_dynamic_array(hcmd))[0], | 160 | __entry->priv, ((u8 *)__get_dynamic_array(hcmd0))[0], |
154 | __entry->flags & CMD_ASYNC ? "a" : "") | 161 | __entry->flags & CMD_ASYNC ? "a" : "") |
155 | ); | 162 | ); |
156 | 163 | ||
@@ -202,15 +209,18 @@ TRACE_EVENT(iwlwifi_dev_tx, | |||
202 | ); | 209 | ); |
203 | 210 | ||
204 | TRACE_EVENT(iwlwifi_dev_ucode_error, | 211 | TRACE_EVENT(iwlwifi_dev_ucode_error, |
205 | TP_PROTO(struct iwl_priv *priv, u32 desc, u32 time, | 212 | TP_PROTO(struct iwl_priv *priv, u32 desc, u32 tsf_low, |
206 | u32 data1, u32 data2, u32 line, u32 blink1, | 213 | u32 data1, u32 data2, u32 line, u32 blink1, |
207 | u32 blink2, u32 ilink1, u32 ilink2), | 214 | u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, |
208 | TP_ARGS(priv, desc, time, data1, data2, line, | 215 | u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, |
209 | blink1, blink2, ilink1, ilink2), | 216 | u32 brd_ver), |
217 | TP_ARGS(priv, desc, tsf_low, data1, data2, line, | ||
218 | blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2, | ||
219 | gp3, ucode_ver, hw_ver, brd_ver), | ||
210 | TP_STRUCT__entry( | 220 | TP_STRUCT__entry( |
211 | PRIV_ENTRY | 221 | PRIV_ENTRY |
212 | __field(u32, desc) | 222 | __field(u32, desc) |
213 | __field(u32, time) | 223 | __field(u32, tsf_low) |
214 | __field(u32, data1) | 224 | __field(u32, data1) |
215 | __field(u32, data2) | 225 | __field(u32, data2) |
216 | __field(u32, line) | 226 | __field(u32, line) |
@@ -218,11 +228,18 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, | |||
218 | __field(u32, blink2) | 228 | __field(u32, blink2) |
219 | __field(u32, ilink1) | 229 | __field(u32, ilink1) |
220 | __field(u32, ilink2) | 230 | __field(u32, ilink2) |
231 | __field(u32, bcon_time) | ||
232 | __field(u32, gp1) | ||
233 | __field(u32, gp2) | ||
234 | __field(u32, gp3) | ||
235 | __field(u32, ucode_ver) | ||
236 | __field(u32, hw_ver) | ||
237 | __field(u32, brd_ver) | ||
221 | ), | 238 | ), |
222 | TP_fast_assign( | 239 | TP_fast_assign( |
223 | PRIV_ASSIGN; | 240 | PRIV_ASSIGN; |
224 | __entry->desc = desc; | 241 | __entry->desc = desc; |
225 | __entry->time = time; | 242 | __entry->tsf_low = tsf_low; |
226 | __entry->data1 = data1; | 243 | __entry->data1 = data1; |
227 | __entry->data2 = data2; | 244 | __entry->data2 = data2; |
228 | __entry->line = line; | 245 | __entry->line = line; |
@@ -230,12 +247,25 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, | |||
230 | __entry->blink2 = blink2; | 247 | __entry->blink2 = blink2; |
231 | __entry->ilink1 = ilink1; | 248 | __entry->ilink1 = ilink1; |
232 | __entry->ilink2 = ilink2; | 249 | __entry->ilink2 = ilink2; |
250 | __entry->bcon_time = bcon_time; | ||
251 | __entry->gp1 = gp1; | ||
252 | __entry->gp2 = gp2; | ||
253 | __entry->gp3 = gp3; | ||
254 | __entry->ucode_ver = ucode_ver; | ||
255 | __entry->hw_ver = hw_ver; | ||
256 | __entry->brd_ver = brd_ver; | ||
233 | ), | 257 | ), |
234 | TP_printk("[%p] #%02d %010u data 0x%08X 0x%08X line %u, " | 258 | TP_printk("[%p] #%02d %010u data 0x%08X 0x%08X line %u, " |
235 | "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X", | 259 | "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X " |
236 | __entry->priv, __entry->desc, __entry->time, __entry->data1, | 260 | "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X " |
261 | "hw 0x%08X brd 0x%08X", | ||
262 | __entry->priv, __entry->desc, __entry->tsf_low, | ||
263 | __entry->data1, | ||
237 | __entry->data2, __entry->line, __entry->blink1, | 264 | __entry->data2, __entry->line, __entry->blink1, |
238 | __entry->blink2, __entry->ilink1, __entry->ilink2) | 265 | __entry->blink2, __entry->ilink1, __entry->ilink2, |
266 | __entry->bcon_time, __entry->gp1, __entry->gp2, | ||
267 | __entry->gp3, __entry->ucode_ver, __entry->hw_ver, | ||
268 | __entry->brd_ver) | ||
239 | ); | 269 | ); |
240 | 270 | ||
241 | TRACE_EVENT(iwlwifi_dev_ucode_event, | 271 | TRACE_EVENT(iwlwifi_dev_ucode_event, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index c8397962632c..47a56bc1cd12 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -216,15 +216,14 @@ static int iwl_eeprom_verify_signature(struct iwl_priv *priv) | |||
216 | 216 | ||
217 | static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode) | 217 | static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode) |
218 | { | 218 | { |
219 | u32 otpgp; | 219 | iwl_read32(priv, CSR_OTP_GP_REG); |
220 | 220 | ||
221 | otpgp = iwl_read32(priv, CSR_OTP_GP_REG); | ||
222 | if (mode == IWL_OTP_ACCESS_ABSOLUTE) | 221 | if (mode == IWL_OTP_ACCESS_ABSOLUTE) |
223 | iwl_clear_bit(priv, CSR_OTP_GP_REG, | 222 | iwl_clear_bit(priv, CSR_OTP_GP_REG, |
224 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); | 223 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); |
225 | else | 224 | else |
226 | iwl_set_bit(priv, CSR_OTP_GP_REG, | 225 | iwl_set_bit(priv, CSR_OTP_GP_REG, |
227 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); | 226 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); |
228 | } | 227 | } |
229 | 228 | ||
230 | static int iwlcore_get_nvm_type(struct iwl_priv *priv, u32 hw_rev) | 229 | static int iwlcore_get_nvm_type(struct iwl_priv *priv, u32 hw_rev) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 8f0beb992ccf..76f996623140 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c | |||
@@ -188,6 +188,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
188 | cmd_idx = iwl_enqueue_hcmd(priv, cmd); | 188 | cmd_idx = iwl_enqueue_hcmd(priv, cmd); |
189 | if (cmd_idx < 0) { | 189 | if (cmd_idx < 0) { |
190 | ret = cmd_idx; | 190 | ret = cmd_idx; |
191 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | ||
191 | IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n", | 192 | IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n", |
192 | get_cmd_string(cmd->id), ret); | 193 | get_cmd_string(cmd->id), ret); |
193 | return ret; | 194 | return ret; |
@@ -264,8 +265,8 @@ int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data) | |||
264 | { | 265 | { |
265 | struct iwl_host_cmd cmd = { | 266 | struct iwl_host_cmd cmd = { |
266 | .id = id, | 267 | .id = id, |
267 | .len = len, | 268 | .len = { len, }, |
268 | .data = data, | 269 | .data = { data, }, |
269 | }; | 270 | }; |
270 | 271 | ||
271 | return iwl_send_cmd_sync(priv, &cmd); | 272 | return iwl_send_cmd_sync(priv, &cmd); |
@@ -279,8 +280,8 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, | |||
279 | { | 280 | { |
280 | struct iwl_host_cmd cmd = { | 281 | struct iwl_host_cmd cmd = { |
281 | .id = id, | 282 | .id = id, |
282 | .len = len, | 283 | .len = { len, }, |
283 | .data = data, | 284 | .data = { data, }, |
284 | }; | 285 | }; |
285 | 286 | ||
286 | cmd.flags |= CMD_ASYNC; | 287 | cmd.flags |= CMD_ASYNC; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 439187f903c9..7c23beb49d7c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c | |||
@@ -107,8 +107,8 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) | |||
107 | { | 107 | { |
108 | struct iwl_host_cmd cmd = { | 108 | struct iwl_host_cmd cmd = { |
109 | .id = REPLY_LEDS_CMD, | 109 | .id = REPLY_LEDS_CMD, |
110 | .len = sizeof(struct iwl_led_cmd), | 110 | .len = { sizeof(struct iwl_led_cmd), }, |
111 | .data = led_cmd, | 111 | .data = { led_cmd, }, |
112 | .flags = CMD_ASYNC, | 112 | .flags = CMD_ASYNC, |
113 | .callback = NULL, | 113 | .callback = NULL, |
114 | }; | 114 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 3c8cebde16cc..7df2814fd4f8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -141,7 +141,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
141 | struct iwl_host_cmd cmd = { | 141 | struct iwl_host_cmd cmd = { |
142 | .id = REPLY_ADD_STA, | 142 | .id = REPLY_ADD_STA, |
143 | .flags = flags, | 143 | .flags = flags, |
144 | .data = data, | 144 | .data = { data, }, |
145 | }; | 145 | }; |
146 | u8 sta_id __maybe_unused = sta->sta.sta_id; | 146 | u8 sta_id __maybe_unused = sta->sta.sta_id; |
147 | 147 | ||
@@ -155,7 +155,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
155 | might_sleep(); | 155 | might_sleep(); |
156 | } | 156 | } |
157 | 157 | ||
158 | cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); | 158 | cmd.len[0] = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); |
159 | ret = iwl_send_cmd(priv, &cmd); | 159 | ret = iwl_send_cmd(priv, &cmd); |
160 | 160 | ||
161 | if (ret || (flags & CMD_ASYNC)) | 161 | if (ret || (flags & CMD_ASYNC)) |
@@ -401,9 +401,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv, | |||
401 | 401 | ||
402 | struct iwl_host_cmd cmd = { | 402 | struct iwl_host_cmd cmd = { |
403 | .id = REPLY_REMOVE_STA, | 403 | .id = REPLY_REMOVE_STA, |
404 | .len = sizeof(struct iwl_rem_sta_cmd), | 404 | .len = { sizeof(struct iwl_rem_sta_cmd), }, |
405 | .flags = CMD_SYNC, | 405 | .flags = CMD_SYNC, |
406 | .data = &rm_sta_cmd, | 406 | .data = { &rm_sta_cmd, }, |
407 | }; | 407 | }; |
408 | 408 | ||
409 | memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); | 409 | memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); |
@@ -760,9 +760,9 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
760 | 760 | ||
761 | struct iwl_host_cmd cmd = { | 761 | struct iwl_host_cmd cmd = { |
762 | .id = REPLY_TX_LINK_QUALITY_CMD, | 762 | .id = REPLY_TX_LINK_QUALITY_CMD, |
763 | .len = sizeof(struct iwl_link_quality_cmd), | 763 | .len = { sizeof(struct iwl_link_quality_cmd), }, |
764 | .flags = flags, | 764 | .flags = flags, |
765 | .data = lq, | 765 | .data = { lq, }, |
766 | }; | 766 | }; |
767 | 767 | ||
768 | if (WARN_ON(lq->sta_id == IWL_INVALID_STATION)) | 768 | if (WARN_ON(lq->sta_id == IWL_INVALID_STATION)) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index 89b6696622c1..69b7e6bf2d6f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c | |||
@@ -97,6 +97,13 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { | |||
97 | 97 | ||
98 | [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, }, | 98 | [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, }, |
99 | [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, }, | 99 | [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, }, |
100 | |||
101 | [IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, }, | ||
102 | |||
103 | [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, }, | ||
104 | [IWL_TM_ATTR_TRACE_DATA] = { .type = NLA_UNSPEC, }, | ||
105 | |||
106 | [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, }, | ||
100 | }; | 107 | }; |
101 | 108 | ||
102 | /* | 109 | /* |
@@ -167,6 +174,31 @@ nla_put_failure: | |||
167 | void iwl_testmode_init(struct iwl_priv *priv) | 174 | void iwl_testmode_init(struct iwl_priv *priv) |
168 | { | 175 | { |
169 | priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; | 176 | priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; |
177 | priv->testmode_trace.trace_enabled = false; | ||
178 | } | ||
179 | |||
180 | static void iwl_trace_cleanup(struct iwl_priv *priv) | ||
181 | { | ||
182 | struct device *dev = &priv->pci_dev->dev; | ||
183 | |||
184 | if (priv->testmode_trace.trace_enabled) { | ||
185 | if (priv->testmode_trace.cpu_addr && | ||
186 | priv->testmode_trace.dma_addr) | ||
187 | dma_free_coherent(dev, | ||
188 | TRACE_TOTAL_SIZE, | ||
189 | priv->testmode_trace.cpu_addr, | ||
190 | priv->testmode_trace.dma_addr); | ||
191 | priv->testmode_trace.trace_enabled = false; | ||
192 | priv->testmode_trace.cpu_addr = NULL; | ||
193 | priv->testmode_trace.trace_addr = NULL; | ||
194 | priv->testmode_trace.dma_addr = 0; | ||
195 | } | ||
196 | } | ||
197 | |||
198 | |||
199 | void iwl_testmode_cleanup(struct iwl_priv *priv) | ||
200 | { | ||
201 | iwl_trace_cleanup(priv); | ||
170 | } | 202 | } |
171 | 203 | ||
172 | /* | 204 | /* |
@@ -198,10 +230,11 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) | |||
198 | } | 230 | } |
199 | 231 | ||
200 | cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]); | 232 | cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]); |
201 | cmd.data = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); | 233 | cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); |
202 | cmd.len = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); | 234 | cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); |
235 | cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; | ||
203 | IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x," | 236 | IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x," |
204 | " len %d\n", cmd.id, cmd.flags, cmd.len); | 237 | " len %d\n", cmd.id, cmd.flags, cmd.len[0]); |
205 | /* ok, let's submit the command to ucode */ | 238 | /* ok, let's submit the command to ucode */ |
206 | return iwl_send_cmd(priv, &cmd); | 239 | return iwl_send_cmd(priv, &cmd); |
207 | } | 240 | } |
@@ -388,6 +421,38 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
388 | "Error starting the device: %d\n", status); | 421 | "Error starting the device: %d\n", status); |
389 | break; | 422 | break; |
390 | 423 | ||
424 | case IWL_TM_CMD_APP2DEV_GET_EEPROM: | ||
425 | if (priv->eeprom) { | ||
426 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, | ||
427 | priv->cfg->base_params->eeprom_size + 20); | ||
428 | if (!skb) { | ||
429 | IWL_DEBUG_INFO(priv, | ||
430 | "Error allocating memory\n"); | ||
431 | return -ENOMEM; | ||
432 | } | ||
433 | NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, | ||
434 | IWL_TM_CMD_DEV2APP_EEPROM_RSP); | ||
435 | NLA_PUT(skb, IWL_TM_ATTR_EEPROM, | ||
436 | priv->cfg->base_params->eeprom_size, | ||
437 | priv->eeprom); | ||
438 | status = cfg80211_testmode_reply(skb); | ||
439 | if (status < 0) | ||
440 | IWL_DEBUG_INFO(priv, | ||
441 | "Error sending msg : %d\n", | ||
442 | status); | ||
443 | } else | ||
444 | return -EFAULT; | ||
445 | break; | ||
446 | |||
447 | case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: | ||
448 | if (!tb[IWL_TM_ATTR_FIXRATE]) { | ||
449 | IWL_DEBUG_INFO(priv, | ||
450 | "Error finding fixrate setting\n"); | ||
451 | return -ENOMSG; | ||
452 | } | ||
453 | priv->dbg_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]); | ||
454 | break; | ||
455 | |||
391 | default: | 456 | default: |
392 | IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n"); | 457 | IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n"); |
393 | return -ENOSYS; | 458 | return -ENOSYS; |
@@ -399,6 +464,102 @@ nla_put_failure: | |||
399 | return -EMSGSIZE; | 464 | return -EMSGSIZE; |
400 | } | 465 | } |
401 | 466 | ||
467 | |||
468 | /* | ||
469 | * This function handles the user application commands for uCode trace | ||
470 | * | ||
471 | * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the | ||
472 | * handlers respectively. | ||
473 | * | ||
474 | * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned | ||
475 | * value of the actual command execution is replied to the user application. | ||
476 | * | ||
477 | * @hw: ieee80211_hw object that represents the device | ||
478 | * @tb: gnl message fields from the user space | ||
479 | */ | ||
480 | static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) | ||
481 | { | ||
482 | struct iwl_priv *priv = hw->priv; | ||
483 | struct sk_buff *skb; | ||
484 | int status = 0; | ||
485 | struct device *dev = &priv->pci_dev->dev; | ||
486 | |||
487 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { | ||
488 | case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: | ||
489 | if (priv->testmode_trace.trace_enabled) | ||
490 | return -EBUSY; | ||
491 | |||
492 | priv->testmode_trace.cpu_addr = | ||
493 | dma_alloc_coherent(dev, | ||
494 | TRACE_TOTAL_SIZE, | ||
495 | &priv->testmode_trace.dma_addr, | ||
496 | GFP_KERNEL); | ||
497 | if (!priv->testmode_trace.cpu_addr) | ||
498 | return -ENOMEM; | ||
499 | priv->testmode_trace.trace_enabled = true; | ||
500 | priv->testmode_trace.trace_addr = (u8 *)PTR_ALIGN( | ||
501 | priv->testmode_trace.cpu_addr, 0x100); | ||
502 | memset(priv->testmode_trace.trace_addr, 0x03B, | ||
503 | TRACE_BUFF_SIZE); | ||
504 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, | ||
505 | sizeof(priv->testmode_trace.dma_addr) + 20); | ||
506 | if (!skb) { | ||
507 | IWL_DEBUG_INFO(priv, | ||
508 | "Error allocating memory\n"); | ||
509 | iwl_trace_cleanup(priv); | ||
510 | return -ENOMEM; | ||
511 | } | ||
512 | NLA_PUT(skb, IWL_TM_ATTR_TRACE_ADDR, | ||
513 | sizeof(priv->testmode_trace.dma_addr), | ||
514 | (u64 *)&priv->testmode_trace.dma_addr); | ||
515 | status = cfg80211_testmode_reply(skb); | ||
516 | if (status < 0) { | ||
517 | IWL_DEBUG_INFO(priv, | ||
518 | "Error sending msg : %d\n", | ||
519 | status); | ||
520 | } | ||
521 | break; | ||
522 | |||
523 | case IWL_TM_CMD_APP2DEV_END_TRACE: | ||
524 | iwl_trace_cleanup(priv); | ||
525 | break; | ||
526 | |||
527 | case IWL_TM_CMD_APP2DEV_READ_TRACE: | ||
528 | if (priv->testmode_trace.trace_enabled && | ||
529 | priv->testmode_trace.trace_addr) { | ||
530 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, | ||
531 | 20 + TRACE_BUFF_SIZE); | ||
532 | if (skb == NULL) { | ||
533 | IWL_DEBUG_INFO(priv, | ||
534 | "Error allocating memory\n"); | ||
535 | return -ENOMEM; | ||
536 | } | ||
537 | NLA_PUT(skb, IWL_TM_ATTR_TRACE_DATA, | ||
538 | TRACE_BUFF_SIZE, | ||
539 | priv->testmode_trace.trace_addr); | ||
540 | status = cfg80211_testmode_reply(skb); | ||
541 | if (status < 0) { | ||
542 | IWL_DEBUG_INFO(priv, | ||
543 | "Error sending msg : %d\n", status); | ||
544 | } | ||
545 | } else | ||
546 | return -EFAULT; | ||
547 | break; | ||
548 | |||
549 | default: | ||
550 | IWL_DEBUG_INFO(priv, "Unknown testmode mem command ID\n"); | ||
551 | return -ENOSYS; | ||
552 | } | ||
553 | return status; | ||
554 | |||
555 | nla_put_failure: | ||
556 | kfree_skb(skb); | ||
557 | if (nla_get_u32(tb[IWL_TM_ATTR_COMMAND]) == | ||
558 | IWL_TM_CMD_APP2DEV_BEGIN_TRACE) | ||
559 | iwl_trace_cleanup(priv); | ||
560 | return -EMSGSIZE; | ||
561 | } | ||
562 | |||
402 | /* The testmode gnl message handler that takes the gnl message from the | 563 | /* The testmode gnl message handler that takes the gnl message from the |
403 | * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then | 564 | * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then |
404 | * invoke the corresponding handlers. | 565 | * invoke the corresponding handlers. |
@@ -455,9 +616,19 @@ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) | |||
455 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: | 616 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: |
456 | case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: | 617 | case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: |
457 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: | 618 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: |
619 | case IWL_TM_CMD_APP2DEV_GET_EEPROM: | ||
620 | case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: | ||
458 | IWL_DEBUG_INFO(priv, "testmode cmd to driver\n"); | 621 | IWL_DEBUG_INFO(priv, "testmode cmd to driver\n"); |
459 | result = iwl_testmode_driver(hw, tb); | 622 | result = iwl_testmode_driver(hw, tb); |
460 | break; | 623 | break; |
624 | |||
625 | case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: | ||
626 | case IWL_TM_CMD_APP2DEV_END_TRACE: | ||
627 | case IWL_TM_CMD_APP2DEV_READ_TRACE: | ||
628 | IWL_DEBUG_INFO(priv, "testmode uCode trace cmd to driver\n"); | ||
629 | result = iwl_testmode_trace(hw, tb); | ||
630 | break; | ||
631 | |||
461 | default: | 632 | default: |
462 | IWL_DEBUG_INFO(priv, "Unknown testmode command\n"); | 633 | IWL_DEBUG_INFO(priv, "Unknown testmode command\n"); |
463 | result = -ENOSYS; | 634 | result = -ENOSYS; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index 31f8949f2801..a88085e9b361 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h | |||
@@ -88,9 +88,15 @@ enum iwl_tm_cmd_t { | |||
88 | IWL_TM_CMD_APP2DEV_LOAD_INIT_FW, | 88 | IWL_TM_CMD_APP2DEV_LOAD_INIT_FW, |
89 | IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB, | 89 | IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB, |
90 | IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW, | 90 | IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW, |
91 | IWL_TM_CMD_APP2DEV_GET_EEPROM, | ||
92 | IWL_TM_CMD_APP2DEV_FIXRATE_REQ, | ||
91 | /* if there is other new command for the driver layer operation, | 93 | /* if there is other new command for the driver layer operation, |
92 | * append them here */ | 94 | * append them here */ |
93 | 95 | ||
96 | /* commands fom user space for uCode trace operations */ | ||
97 | IWL_TM_CMD_APP2DEV_BEGIN_TRACE, | ||
98 | IWL_TM_CMD_APP2DEV_END_TRACE, | ||
99 | IWL_TM_CMD_APP2DEV_READ_TRACE, | ||
94 | 100 | ||
95 | /* commands from kernel space to carry the synchronous response | 101 | /* commands from kernel space to carry the synchronous response |
96 | * to user application */ | 102 | * to user application */ |
@@ -99,6 +105,11 @@ enum iwl_tm_cmd_t { | |||
99 | /* commands from kernel space to multicast the spontaneous messages | 105 | /* commands from kernel space to multicast the spontaneous messages |
100 | * to user application */ | 106 | * to user application */ |
101 | IWL_TM_CMD_DEV2APP_UCODE_RX_PKT, | 107 | IWL_TM_CMD_DEV2APP_UCODE_RX_PKT, |
108 | |||
109 | /* commands from kernel space to carry the eeprom response | ||
110 | * to user application */ | ||
111 | IWL_TM_CMD_DEV2APP_EEPROM_RSP, | ||
112 | |||
102 | IWL_TM_CMD_MAX, | 113 | IWL_TM_CMD_MAX, |
103 | }; | 114 | }; |
104 | 115 | ||
@@ -144,8 +155,31 @@ enum iwl_tm_attr_t { | |||
144 | * application */ | 155 | * application */ |
145 | IWL_TM_ATTR_UCODE_RX_PKT, | 156 | IWL_TM_ATTR_UCODE_RX_PKT, |
146 | 157 | ||
158 | /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_EEPROM, | ||
159 | * The mandatory fields are: | ||
160 | * IWL_TM_ATTR_EEPROM for the data content responging to the user | ||
161 | * application */ | ||
162 | IWL_TM_ATTR_EEPROM, | ||
163 | |||
164 | /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_XXX_TRACE, | ||
165 | * The mandatory fields are: | ||
166 | * IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address | ||
167 | */ | ||
168 | IWL_TM_ATTR_TRACE_ADDR, | ||
169 | IWL_TM_ATTR_TRACE_DATA, | ||
170 | |||
171 | /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ, | ||
172 | * The mandatory fields are: | ||
173 | * IWL_TM_ATTR_FIXRATE for the fixed rate | ||
174 | */ | ||
175 | IWL_TM_ATTR_FIXRATE, | ||
176 | |||
147 | IWL_TM_ATTR_MAX, | 177 | IWL_TM_ATTR_MAX, |
148 | }; | 178 | }; |
149 | 179 | ||
180 | /* uCode trace buffer */ | ||
181 | #define TRACE_BUFF_SIZE 0x20000 | ||
182 | #define TRACE_BUFF_PADD 0x2000 | ||
183 | #define TRACE_TOTAL_SIZE (TRACE_BUFF_SIZE + TRACE_BUFF_PADD) | ||
150 | 184 | ||
151 | #endif | 185 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index e69597ea43e2..686e176b5ebd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <net/mac80211.h> | 33 | #include <net/mac80211.h> |
34 | #include "iwl-eeprom.h" | 34 | #include "iwl-eeprom.h" |
35 | #include "iwl-agn.h" | ||
35 | #include "iwl-dev.h" | 36 | #include "iwl-dev.h" |
36 | #include "iwl-core.h" | 37 | #include "iwl-core.h" |
37 | #include "iwl-sta.h" | 38 | #include "iwl-sta.h" |
@@ -85,6 +86,158 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) | |||
85 | txq->need_update = 0; | 86 | txq->need_update = 0; |
86 | } | 87 | } |
87 | 88 | ||
89 | static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) | ||
90 | { | ||
91 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | ||
92 | |||
93 | dma_addr_t addr = get_unaligned_le32(&tb->lo); | ||
94 | if (sizeof(dma_addr_t) > sizeof(u32)) | ||
95 | addr |= | ||
96 | ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16; | ||
97 | |||
98 | return addr; | ||
99 | } | ||
100 | |||
101 | static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx) | ||
102 | { | ||
103 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | ||
104 | |||
105 | return le16_to_cpu(tb->hi_n_len) >> 4; | ||
106 | } | ||
107 | |||
108 | static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx, | ||
109 | dma_addr_t addr, u16 len) | ||
110 | { | ||
111 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | ||
112 | u16 hi_n_len = len << 4; | ||
113 | |||
114 | put_unaligned_le32(addr, &tb->lo); | ||
115 | if (sizeof(dma_addr_t) > sizeof(u32)) | ||
116 | hi_n_len |= ((addr >> 16) >> 16) & 0xF; | ||
117 | |||
118 | tb->hi_n_len = cpu_to_le16(hi_n_len); | ||
119 | |||
120 | tfd->num_tbs = idx + 1; | ||
121 | } | ||
122 | |||
123 | static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) | ||
124 | { | ||
125 | return tfd->num_tbs & 0x1f; | ||
126 | } | ||
127 | |||
128 | static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta, | ||
129 | struct iwl_tfd *tfd) | ||
130 | { | ||
131 | struct pci_dev *dev = priv->pci_dev; | ||
132 | int i; | ||
133 | int num_tbs; | ||
134 | |||
135 | /* Sanity check on number of chunks */ | ||
136 | num_tbs = iwl_tfd_get_num_tbs(tfd); | ||
137 | |||
138 | if (num_tbs >= IWL_NUM_OF_TBS) { | ||
139 | IWL_ERR(priv, "Too many chunks: %i\n", num_tbs); | ||
140 | /* @todo issue fatal error, it is quite serious situation */ | ||
141 | return; | ||
142 | } | ||
143 | |||
144 | /* Unmap tx_cmd */ | ||
145 | if (num_tbs) | ||
146 | pci_unmap_single(dev, | ||
147 | dma_unmap_addr(meta, mapping), | ||
148 | dma_unmap_len(meta, len), | ||
149 | PCI_DMA_BIDIRECTIONAL); | ||
150 | |||
151 | /* Unmap chunks, if any. */ | ||
152 | for (i = 1; i < num_tbs; i++) | ||
153 | pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i), | ||
154 | iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE); | ||
155 | } | ||
156 | |||
157 | /** | ||
158 | * iwlagn_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] | ||
159 | * @priv - driver private data | ||
160 | * @txq - tx queue | ||
161 | * | ||
162 | * Does NOT advance any TFD circular buffer read/write indexes | ||
163 | * Does NOT free the TFD itself (which is within circular buffer) | ||
164 | */ | ||
165 | void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) | ||
166 | { | ||
167 | struct iwl_tfd *tfd_tmp = txq->tfds; | ||
168 | int index = txq->q.read_ptr; | ||
169 | |||
170 | iwlagn_unmap_tfd(priv, &txq->meta[index], &tfd_tmp[index]); | ||
171 | |||
172 | /* free SKB */ | ||
173 | if (txq->txb) { | ||
174 | struct sk_buff *skb; | ||
175 | |||
176 | skb = txq->txb[txq->q.read_ptr].skb; | ||
177 | |||
178 | /* can be called from irqs-disabled context */ | ||
179 | if (skb) { | ||
180 | dev_kfree_skb_any(skb); | ||
181 | txq->txb[txq->q.read_ptr].skb = NULL; | ||
182 | } | ||
183 | } | ||
184 | } | ||
185 | |||
186 | int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv, | ||
187 | struct iwl_tx_queue *txq, | ||
188 | dma_addr_t addr, u16 len, | ||
189 | u8 reset) | ||
190 | { | ||
191 | struct iwl_queue *q; | ||
192 | struct iwl_tfd *tfd, *tfd_tmp; | ||
193 | u32 num_tbs; | ||
194 | |||
195 | q = &txq->q; | ||
196 | tfd_tmp = txq->tfds; | ||
197 | tfd = &tfd_tmp[q->write_ptr]; | ||
198 | |||
199 | if (reset) | ||
200 | memset(tfd, 0, sizeof(*tfd)); | ||
201 | |||
202 | num_tbs = iwl_tfd_get_num_tbs(tfd); | ||
203 | |||
204 | /* Each TFD can point to a maximum 20 Tx buffers */ | ||
205 | if (num_tbs >= IWL_NUM_OF_TBS) { | ||
206 | IWL_ERR(priv, "Error can not send more than %d chunks\n", | ||
207 | IWL_NUM_OF_TBS); | ||
208 | return -EINVAL; | ||
209 | } | ||
210 | |||
211 | if (WARN_ON(addr & ~DMA_BIT_MASK(36))) | ||
212 | return -EINVAL; | ||
213 | |||
214 | if (unlikely(addr & ~IWL_TX_DMA_MASK)) | ||
215 | IWL_ERR(priv, "Unaligned address = %llx\n", | ||
216 | (unsigned long long)addr); | ||
217 | |||
218 | iwl_tfd_set_tb(tfd, num_tbs, addr, len); | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * Tell nic where to find circular buffer of Tx Frame Descriptors for | ||
225 | * given Tx queue, and enable the DMA channel used for that queue. | ||
226 | * | ||
227 | * supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA | ||
228 | * channels supported in hardware. | ||
229 | */ | ||
230 | static int iwlagn_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq) | ||
231 | { | ||
232 | int txq_id = txq->q.id; | ||
233 | |||
234 | /* Circular buffer (TFD queue in DRAM) physical base address */ | ||
235 | iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), | ||
236 | txq->q.dma_addr >> 8); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
88 | /** | 241 | /** |
89 | * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's | 242 | * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's |
90 | */ | 243 | */ |
@@ -97,7 +250,7 @@ void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id) | |||
97 | return; | 250 | return; |
98 | 251 | ||
99 | while (q->write_ptr != q->read_ptr) { | 252 | while (q->write_ptr != q->read_ptr) { |
100 | priv->cfg->ops->lib->txq_free_tfd(priv, txq); | 253 | iwlagn_txq_free_tfd(priv, txq); |
101 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); | 254 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); |
102 | } | 255 | } |
103 | } | 256 | } |
@@ -154,7 +307,7 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv) | |||
154 | return; | 307 | return; |
155 | 308 | ||
156 | while (q->read_ptr != q->write_ptr) { | 309 | while (q->read_ptr != q->write_ptr) { |
157 | i = get_cmd_index(q, q->read_ptr, 0); | 310 | i = get_cmd_index(q, q->read_ptr); |
158 | 311 | ||
159 | if (txq->meta[i].flags & CMD_MAPPED) { | 312 | if (txq->meta[i].flags & CMD_MAPPED) { |
160 | pci_unmap_single(priv->pci_dev, | 313 | pci_unmap_single(priv->pci_dev, |
@@ -166,15 +319,6 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv) | |||
166 | 319 | ||
167 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); | 320 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); |
168 | } | 321 | } |
169 | |||
170 | i = q->n_window; | ||
171 | if (txq->meta[i].flags & CMD_MAPPED) { | ||
172 | pci_unmap_single(priv->pci_dev, | ||
173 | dma_unmap_addr(&txq->meta[i], mapping), | ||
174 | dma_unmap_len(&txq->meta[i], len), | ||
175 | PCI_DMA_BIDIRECTIONAL); | ||
176 | txq->meta[i].flags = 0; | ||
177 | } | ||
178 | } | 322 | } |
179 | 323 | ||
180 | /** | 324 | /** |
@@ -194,7 +338,7 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) | |||
194 | iwl_cmd_queue_unmap(priv); | 338 | iwl_cmd_queue_unmap(priv); |
195 | 339 | ||
196 | /* De-alloc array of command/tx buffers */ | 340 | /* De-alloc array of command/tx buffers */ |
197 | for (i = 0; i <= TFD_CMD_SLOTS; i++) | 341 | for (i = 0; i < TFD_CMD_SLOTS; i++) |
198 | kfree(txq->cmd[i]); | 342 | kfree(txq->cmd[i]); |
199 | 343 | ||
200 | /* De-alloc circular buffer of TFDs */ | 344 | /* De-alloc circular buffer of TFDs */ |
@@ -334,33 +478,17 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, | |||
334 | { | 478 | { |
335 | int i, len; | 479 | int i, len; |
336 | int ret; | 480 | int ret; |
337 | int actual_slots = slots_num; | ||
338 | |||
339 | /* | ||
340 | * Alloc buffer array for commands (Tx or other types of commands). | ||
341 | * For the command queue (#4/#9), allocate command space + one big | ||
342 | * command for scan, since scan command is very huge; the system will | ||
343 | * not have two scans at the same time, so only one is needed. | ||
344 | * For normal Tx queues (all other queues), no super-size command | ||
345 | * space is needed. | ||
346 | */ | ||
347 | if (txq_id == priv->cmd_queue) | ||
348 | actual_slots++; | ||
349 | 481 | ||
350 | txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * actual_slots, | 482 | txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * slots_num, |
351 | GFP_KERNEL); | 483 | GFP_KERNEL); |
352 | txq->cmd = kzalloc(sizeof(struct iwl_device_cmd *) * actual_slots, | 484 | txq->cmd = kzalloc(sizeof(struct iwl_device_cmd *) * slots_num, |
353 | GFP_KERNEL); | 485 | GFP_KERNEL); |
354 | 486 | ||
355 | if (!txq->meta || !txq->cmd) | 487 | if (!txq->meta || !txq->cmd) |
356 | goto out_free_arrays; | 488 | goto out_free_arrays; |
357 | 489 | ||
358 | len = sizeof(struct iwl_device_cmd); | 490 | len = sizeof(struct iwl_device_cmd); |
359 | for (i = 0; i < actual_slots; i++) { | 491 | for (i = 0; i < slots_num; i++) { |
360 | /* only happens for cmd queue */ | ||
361 | if (i == slots_num) | ||
362 | len = IWL_MAX_CMD_SIZE; | ||
363 | |||
364 | txq->cmd[i] = kmalloc(len, GFP_KERNEL); | 492 | txq->cmd[i] = kmalloc(len, GFP_KERNEL); |
365 | if (!txq->cmd[i]) | 493 | if (!txq->cmd[i]) |
366 | goto err; | 494 | goto err; |
@@ -391,11 +519,11 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, | |||
391 | return ret; | 519 | return ret; |
392 | 520 | ||
393 | /* Tell device where to find queue */ | 521 | /* Tell device where to find queue */ |
394 | priv->cfg->ops->lib->txq_init(priv, txq); | 522 | iwlagn_tx_queue_init(priv, txq); |
395 | 523 | ||
396 | return 0; | 524 | return 0; |
397 | err: | 525 | err: |
398 | for (i = 0; i < actual_slots; i++) | 526 | for (i = 0; i < slots_num; i++) |
399 | kfree(txq->cmd[i]); | 527 | kfree(txq->cmd[i]); |
400 | out_free_arrays: | 528 | out_free_arrays: |
401 | kfree(txq->meta); | 529 | kfree(txq->meta); |
@@ -420,7 +548,7 @@ void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, | |||
420 | iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); | 548 | iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); |
421 | 549 | ||
422 | /* Tell device where to find queue */ | 550 | /* Tell device where to find queue */ |
423 | priv->cfg->ops->lib->txq_init(priv, txq); | 551 | iwlagn_tx_queue_init(priv, txq); |
424 | } | 552 | } |
425 | 553 | ||
426 | /*************** HOST COMMAND QUEUE FUNCTIONS *****/ | 554 | /*************** HOST COMMAND QUEUE FUNCTIONS *****/ |
@@ -443,23 +571,49 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
443 | dma_addr_t phys_addr; | 571 | dma_addr_t phys_addr; |
444 | unsigned long flags; | 572 | unsigned long flags; |
445 | u32 idx; | 573 | u32 idx; |
446 | u16 fix_size; | 574 | u16 copy_size, cmd_size; |
447 | bool is_ct_kill = false; | 575 | bool is_ct_kill = false; |
576 | bool had_nocopy = false; | ||
577 | int i; | ||
578 | u8 *cmd_dest; | ||
579 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING | ||
580 | const void *trace_bufs[IWL_MAX_CMD_TFDS + 1] = {}; | ||
581 | int trace_lens[IWL_MAX_CMD_TFDS + 1] = {}; | ||
582 | int trace_idx; | ||
583 | #endif | ||
584 | |||
585 | if (test_bit(STATUS_FW_ERROR, &priv->status)) { | ||
586 | IWL_WARN(priv, "fw recovery, no hcmd send\n"); | ||
587 | return -EIO; | ||
588 | } | ||
448 | 589 | ||
449 | fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); | 590 | copy_size = sizeof(out_cmd->hdr); |
591 | cmd_size = sizeof(out_cmd->hdr); | ||
592 | |||
593 | /* need one for the header if the first is NOCOPY */ | ||
594 | BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1); | ||
595 | |||
596 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { | ||
597 | if (!cmd->len[i]) | ||
598 | continue; | ||
599 | if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { | ||
600 | had_nocopy = true; | ||
601 | } else { | ||
602 | /* NOCOPY must not be followed by normal! */ | ||
603 | if (WARN_ON(had_nocopy)) | ||
604 | return -EINVAL; | ||
605 | copy_size += cmd->len[i]; | ||
606 | } | ||
607 | cmd_size += cmd->len[i]; | ||
608 | } | ||
450 | 609 | ||
451 | /* | 610 | /* |
452 | * If any of the command structures end up being larger than | 611 | * If any of the command structures end up being larger than |
453 | * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then | 612 | * the TFD_MAX_PAYLOAD_SIZE and they aren't dynamically |
454 | * we will need to increase the size of the TFD entries | 613 | * allocated into separate TFDs, then we will need to |
455 | * Also, check to see if command buffer should not exceed the size | 614 | * increase the size of the buffers. |
456 | * of device_cmd and max_cmd_size. | ||
457 | */ | 615 | */ |
458 | if (WARN_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && | 616 | if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE)) |
459 | !(cmd->flags & CMD_SIZE_HUGE))) | ||
460 | return -EINVAL; | ||
461 | |||
462 | if (WARN_ON(fix_size > IWL_MAX_CMD_SIZE)) | ||
463 | return -EINVAL; | 617 | return -EINVAL; |
464 | 618 | ||
465 | if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) { | 619 | if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) { |
@@ -468,14 +622,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
468 | return -EIO; | 622 | return -EIO; |
469 | } | 623 | } |
470 | 624 | ||
471 | /* | ||
472 | * As we only have a single huge buffer, check that the command | ||
473 | * is synchronous (otherwise buffers could end up being reused). | ||
474 | */ | ||
475 | |||
476 | if (WARN_ON((cmd->flags & CMD_ASYNC) && (cmd->flags & CMD_SIZE_HUGE))) | ||
477 | return -EINVAL; | ||
478 | |||
479 | spin_lock_irqsave(&priv->hcmd_lock, flags); | 625 | spin_lock_irqsave(&priv->hcmd_lock, flags); |
480 | 626 | ||
481 | if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { | 627 | if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { |
@@ -490,7 +636,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
490 | return -ENOSPC; | 636 | return -ENOSPC; |
491 | } | 637 | } |
492 | 638 | ||
493 | idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); | 639 | idx = get_cmd_index(q, q->write_ptr); |
494 | out_cmd = txq->cmd[idx]; | 640 | out_cmd = txq->cmd[idx]; |
495 | out_meta = &txq->meta[idx]; | 641 | out_meta = &txq->meta[idx]; |
496 | 642 | ||
@@ -505,57 +651,84 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
505 | if (cmd->flags & CMD_ASYNC) | 651 | if (cmd->flags & CMD_ASYNC) |
506 | out_meta->callback = cmd->callback; | 652 | out_meta->callback = cmd->callback; |
507 | 653 | ||
508 | out_cmd->hdr.cmd = cmd->id; | 654 | /* set up the header */ |
509 | memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len); | ||
510 | |||
511 | /* At this point, the out_cmd now has all of the incoming cmd | ||
512 | * information */ | ||
513 | 655 | ||
656 | out_cmd->hdr.cmd = cmd->id; | ||
514 | out_cmd->hdr.flags = 0; | 657 | out_cmd->hdr.flags = 0; |
515 | out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(priv->cmd_queue) | | 658 | out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(priv->cmd_queue) | |
516 | INDEX_TO_SEQ(q->write_ptr)); | 659 | INDEX_TO_SEQ(q->write_ptr)); |
517 | if (cmd->flags & CMD_SIZE_HUGE) | 660 | |
518 | out_cmd->hdr.sequence |= SEQ_HUGE_FRAME; | 661 | /* and copy the data that needs to be copied */ |
519 | 662 | ||
520 | #ifdef CONFIG_IWLWIFI_DEBUG | 663 | cmd_dest = &out_cmd->cmd.payload[0]; |
521 | switch (out_cmd->hdr.cmd) { | 664 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { |
522 | case REPLY_TX_LINK_QUALITY_CMD: | 665 | if (!cmd->len[i]) |
523 | case SENSITIVITY_CMD: | 666 | continue; |
524 | IWL_DEBUG_HC_DUMP(priv, "Sending command %s (#%x), seq: 0x%04X, " | 667 | if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) |
525 | "%d bytes at %d[%d]:%d\n", | 668 | break; |
526 | get_cmd_string(out_cmd->hdr.cmd), | 669 | memcpy(cmd_dest, cmd->data[i], cmd->len[i]); |
527 | out_cmd->hdr.cmd, | 670 | cmd_dest += cmd->len[i]; |
528 | le16_to_cpu(out_cmd->hdr.sequence), fix_size, | ||
529 | q->write_ptr, idx, priv->cmd_queue); | ||
530 | break; | ||
531 | default: | ||
532 | IWL_DEBUG_HC(priv, "Sending command %s (#%x), seq: 0x%04X, " | ||
533 | "%d bytes at %d[%d]:%d\n", | ||
534 | get_cmd_string(out_cmd->hdr.cmd), | ||
535 | out_cmd->hdr.cmd, | ||
536 | le16_to_cpu(out_cmd->hdr.sequence), fix_size, | ||
537 | q->write_ptr, idx, priv->cmd_queue); | ||
538 | } | 671 | } |
539 | #endif | 672 | |
673 | IWL_DEBUG_HC(priv, "Sending command %s (#%x), seq: 0x%04X, " | ||
674 | "%d bytes at %d[%d]:%d\n", | ||
675 | get_cmd_string(out_cmd->hdr.cmd), | ||
676 | out_cmd->hdr.cmd, | ||
677 | le16_to_cpu(out_cmd->hdr.sequence), cmd_size, | ||
678 | q->write_ptr, idx, priv->cmd_queue); | ||
679 | |||
540 | phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr, | 680 | phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr, |
541 | fix_size, PCI_DMA_BIDIRECTIONAL); | 681 | copy_size, PCI_DMA_BIDIRECTIONAL); |
542 | if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) { | 682 | if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) { |
543 | idx = -ENOMEM; | 683 | idx = -ENOMEM; |
544 | goto out; | 684 | goto out; |
545 | } | 685 | } |
546 | 686 | ||
547 | dma_unmap_addr_set(out_meta, mapping, phys_addr); | 687 | dma_unmap_addr_set(out_meta, mapping, phys_addr); |
548 | dma_unmap_len_set(out_meta, len, fix_size); | 688 | dma_unmap_len_set(out_meta, len, copy_size); |
689 | |||
690 | iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr, copy_size, 1); | ||
691 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING | ||
692 | trace_bufs[0] = &out_cmd->hdr; | ||
693 | trace_lens[0] = copy_size; | ||
694 | trace_idx = 1; | ||
695 | #endif | ||
696 | |||
697 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { | ||
698 | if (!cmd->len[i]) | ||
699 | continue; | ||
700 | if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) | ||
701 | continue; | ||
702 | phys_addr = pci_map_single(priv->pci_dev, (void *)cmd->data[i], | ||
703 | cmd->len[i], PCI_DMA_TODEVICE); | ||
704 | if (pci_dma_mapping_error(priv->pci_dev, phys_addr)) { | ||
705 | iwlagn_unmap_tfd(priv, out_meta, | ||
706 | &txq->tfds[q->write_ptr]); | ||
707 | idx = -ENOMEM; | ||
708 | goto out; | ||
709 | } | ||
710 | |||
711 | iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr, | ||
712 | cmd->len[i], 0); | ||
713 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING | ||
714 | trace_bufs[trace_idx] = cmd->data[i]; | ||
715 | trace_lens[trace_idx] = cmd->len[i]; | ||
716 | trace_idx++; | ||
717 | #endif | ||
718 | } | ||
549 | 719 | ||
550 | out_meta->flags = cmd->flags | CMD_MAPPED; | 720 | out_meta->flags = cmd->flags | CMD_MAPPED; |
551 | 721 | ||
552 | txq->need_update = 1; | 722 | txq->need_update = 1; |
553 | 723 | ||
554 | trace_iwlwifi_dev_hcmd(priv, &out_cmd->hdr, fix_size, cmd->flags); | 724 | /* check that tracing gets all possible blocks */ |
555 | 725 | BUILD_BUG_ON(IWL_MAX_CMD_TFDS + 1 != 3); | |
556 | priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, | 726 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING |
557 | phys_addr, fix_size, 1, | 727 | trace_iwlwifi_dev_hcmd(priv, cmd->flags, |
558 | U32_PAD(cmd->len)); | 728 | trace_bufs[0], trace_lens[0], |
729 | trace_bufs[1], trace_lens[1], | ||
730 | trace_bufs[2], trace_lens[2]); | ||
731 | #endif | ||
559 | 732 | ||
560 | /* Increment and update queue's write index */ | 733 | /* Increment and update queue's write index */ |
561 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 734 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
@@ -573,8 +746,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
573 | * need to be reclaimed. As result, some free space forms. If there is | 746 | * need to be reclaimed. As result, some free space forms. If there is |
574 | * enough free space (> low mark), wake the stack that feeds us. | 747 | * enough free space (> low mark), wake the stack that feeds us. |
575 | */ | 748 | */ |
576 | static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, | 749 | static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int idx) |
577 | int idx, int cmd_idx) | ||
578 | { | 750 | { |
579 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; | 751 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; |
580 | struct iwl_queue *q = &txq->q; | 752 | struct iwl_queue *q = &txq->q; |
@@ -614,7 +786,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
614 | int txq_id = SEQ_TO_QUEUE(sequence); | 786 | int txq_id = SEQ_TO_QUEUE(sequence); |
615 | int index = SEQ_TO_INDEX(sequence); | 787 | int index = SEQ_TO_INDEX(sequence); |
616 | int cmd_index; | 788 | int cmd_index; |
617 | bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME); | ||
618 | struct iwl_device_cmd *cmd; | 789 | struct iwl_device_cmd *cmd; |
619 | struct iwl_cmd_meta *meta; | 790 | struct iwl_cmd_meta *meta; |
620 | struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; | 791 | struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; |
@@ -632,14 +803,11 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
632 | return; | 803 | return; |
633 | } | 804 | } |
634 | 805 | ||
635 | cmd_index = get_cmd_index(&txq->q, index, huge); | 806 | cmd_index = get_cmd_index(&txq->q, index); |
636 | cmd = txq->cmd[cmd_index]; | 807 | cmd = txq->cmd[cmd_index]; |
637 | meta = &txq->meta[cmd_index]; | 808 | meta = &txq->meta[cmd_index]; |
638 | 809 | ||
639 | pci_unmap_single(priv->pci_dev, | 810 | iwlagn_unmap_tfd(priv, meta, &txq->tfds[index]); |
640 | dma_unmap_addr(meta, mapping), | ||
641 | dma_unmap_len(meta, len), | ||
642 | PCI_DMA_BIDIRECTIONAL); | ||
643 | 811 | ||
644 | /* Input error checking is done when commands are added to queue. */ | 812 | /* Input error checking is done when commands are added to queue. */ |
645 | if (meta->flags & CMD_WANT_SKB) { | 813 | if (meta->flags & CMD_WANT_SKB) { |
@@ -650,7 +818,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
650 | 818 | ||
651 | spin_lock_irqsave(&priv->hcmd_lock, flags); | 819 | spin_lock_irqsave(&priv->hcmd_lock, flags); |
652 | 820 | ||
653 | iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); | 821 | iwl_hcmd_queue_reclaim(priv, txq_id, index); |
654 | 822 | ||
655 | if (!(meta->flags & CMD_ASYNC)) { | 823 | if (!(meta->flags & CMD_ASYNC)) { |
656 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | 824 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); |
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c index 5665a1a9b99e..a414768f40f1 100644 --- a/drivers/net/wireless/iwmc3200wifi/rx.c +++ b/drivers/net/wireless/iwmc3200wifi/rx.c | |||
@@ -565,7 +565,7 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf, | |||
565 | if (!test_and_clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status) | 565 | if (!test_and_clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status) |
566 | && iwm->conf.mode == UMAC_MODE_BSS) { | 566 | && iwm->conf.mode == UMAC_MODE_BSS) { |
567 | cancel_delayed_work(&iwm->disconnect); | 567 | cancel_delayed_work(&iwm->disconnect); |
568 | cfg80211_roamed(iwm_to_ndev(iwm), | 568 | cfg80211_roamed(iwm_to_ndev(iwm), NULL, |
569 | complete->bssid, | 569 | complete->bssid, |
570 | iwm->req_ie, iwm->req_ie_len, | 570 | iwm->req_ie, iwm->req_ie_len, |
571 | iwm->resp_ie, iwm->resp_ie_len, | 571 | iwm->resp_ie, iwm->resp_ie_len, |
@@ -586,7 +586,7 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf, | |||
586 | WLAN_STATUS_SUCCESS, | 586 | WLAN_STATUS_SUCCESS, |
587 | GFP_KERNEL); | 587 | GFP_KERNEL); |
588 | else | 588 | else |
589 | cfg80211_roamed(iwm_to_ndev(iwm), | 589 | cfg80211_roamed(iwm_to_ndev(iwm), NULL, |
590 | complete->bssid, | 590 | complete->bssid, |
591 | iwm->req_ie, iwm->req_ie_len, | 591 | iwm->req_ie, iwm->req_ie_len, |
592 | iwm->resp_ie, iwm->resp_ie_len, | 592 | iwm->resp_ie, iwm->resp_ie_len, |
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index d3d5e0853c45..f807447e4d99 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c | |||
@@ -196,6 +196,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
196 | if (skb_src) | 196 | if (skb_src) |
197 | pra_list->total_pkts_size -= skb_src->len; | 197 | pra_list->total_pkts_size -= skb_src->len; |
198 | 198 | ||
199 | atomic_dec(&priv->wmm.tx_pkts_queued); | ||
200 | |||
199 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, | 201 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, |
200 | ra_list_flags); | 202 | ra_list_flags); |
201 | mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad); | 203 | mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad); |
@@ -257,6 +259,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
257 | 259 | ||
258 | pra_list->total_pkts_size += skb_aggr->len; | 260 | pra_list->total_pkts_size += skb_aggr->len; |
259 | 261 | ||
262 | atomic_inc(&priv->wmm.tx_pkts_queued); | ||
263 | |||
260 | tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT; | 264 | tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT; |
261 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, | 265 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, |
262 | ra_list_flags); | 266 | ra_list_flags); |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 672701dc2721..8316b3cd92cd 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -69,7 +69,8 @@ struct mwifiex_drv_mode { | |||
69 | #define MWIFIEX_TIMER_10S 10000 | 69 | #define MWIFIEX_TIMER_10S 10000 |
70 | #define MWIFIEX_TIMER_1S 1000 | 70 | #define MWIFIEX_TIMER_1S 1000 |
71 | 71 | ||
72 | #define MAX_TX_PENDING 60 | 72 | #define MAX_TX_PENDING 100 |
73 | #define LOW_TX_PENDING 80 | ||
73 | 74 | ||
74 | #define MWIFIEX_UPLD_SIZE (2312) | 75 | #define MWIFIEX_UPLD_SIZE (2312) |
75 | 76 | ||
@@ -202,6 +203,7 @@ struct mwifiex_tid_tbl { | |||
202 | #define WMM_HIGHEST_PRIORITY 7 | 203 | #define WMM_HIGHEST_PRIORITY 7 |
203 | #define HIGH_PRIO_TID 7 | 204 | #define HIGH_PRIO_TID 7 |
204 | #define LOW_PRIO_TID 0 | 205 | #define LOW_PRIO_TID 0 |
206 | #define NO_PKT_PRIO_TID (-1) | ||
205 | 207 | ||
206 | struct mwifiex_wmm_desc { | 208 | struct mwifiex_wmm_desc { |
207 | struct mwifiex_tid_tbl tid_tbl_ptr[MAX_NUM_TID]; | 209 | struct mwifiex_tid_tbl tid_tbl_ptr[MAX_NUM_TID]; |
@@ -213,7 +215,10 @@ struct mwifiex_wmm_desc { | |||
213 | u32 drv_pkt_delay_max; | 215 | u32 drv_pkt_delay_max; |
214 | u8 queue_priority[IEEE80211_MAX_QUEUES]; | 216 | u8 queue_priority[IEEE80211_MAX_QUEUES]; |
215 | u32 user_pri_pkt_tx_ctrl[WMM_HIGHEST_PRIORITY + 1]; /* UP: 0 to 7 */ | 217 | u32 user_pri_pkt_tx_ctrl[WMM_HIGHEST_PRIORITY + 1]; /* UP: 0 to 7 */ |
216 | 218 | /* Number of transmit packets queued */ | |
219 | atomic_t tx_pkts_queued; | ||
220 | /* Tracks highest priority with a packet queued */ | ||
221 | atomic_t highest_queued_prio; | ||
217 | }; | 222 | }; |
218 | 223 | ||
219 | struct mwifiex_802_11_security { | 224 | struct mwifiex_802_11_security { |
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index 210120889dfe..aaa50c074196 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c | |||
@@ -140,7 +140,9 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, | |||
140 | } else { | 140 | } else { |
141 | priv->stats.tx_errors++; | 141 | priv->stats.tx_errors++; |
142 | } | 142 | } |
143 | atomic_dec(&adapter->tx_pending); | 143 | |
144 | if (atomic_dec_return(&adapter->tx_pending) >= LOW_TX_PENDING) | ||
145 | goto done; | ||
144 | 146 | ||
145 | for (i = 0; i < adapter->priv_num; i++) { | 147 | for (i = 0; i < adapter->priv_num; i++) { |
146 | 148 | ||
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index faa09e32902e..91634daec306 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c | |||
@@ -177,14 +177,20 @@ static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv) | |||
177 | * This function map ACs to TIDs. | 177 | * This function map ACs to TIDs. |
178 | */ | 178 | */ |
179 | static void | 179 | static void |
180 | mwifiex_wmm_queue_priorities_tid(u8 queue_priority[]) | 180 | mwifiex_wmm_queue_priorities_tid(struct mwifiex_wmm_desc *wmm) |
181 | { | 181 | { |
182 | u8 *queue_priority = wmm->queue_priority; | ||
182 | int i; | 183 | int i; |
183 | 184 | ||
184 | for (i = 0; i < 4; ++i) { | 185 | for (i = 0; i < 4; ++i) { |
185 | tos_to_tid[7 - (i * 2)] = ac_to_tid[queue_priority[i]][1]; | 186 | tos_to_tid[7 - (i * 2)] = ac_to_tid[queue_priority[i]][1]; |
186 | tos_to_tid[6 - (i * 2)] = ac_to_tid[queue_priority[i]][0]; | 187 | tos_to_tid[6 - (i * 2)] = ac_to_tid[queue_priority[i]][0]; |
187 | } | 188 | } |
189 | |||
190 | for (i = 0; i < MAX_NUM_TID; ++i) | ||
191 | tos_to_tid_inv[tos_to_tid[i]] = (u8)i; | ||
192 | |||
193 | atomic_set(&wmm->highest_queued_prio, HIGH_PRIO_TID); | ||
188 | } | 194 | } |
189 | 195 | ||
190 | /* | 196 | /* |
@@ -246,7 +252,7 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, | |||
246 | } | 252 | } |
247 | } | 253 | } |
248 | 254 | ||
249 | mwifiex_wmm_queue_priorities_tid(priv->wmm.queue_priority); | 255 | mwifiex_wmm_queue_priorities_tid(&priv->wmm); |
250 | } | 256 | } |
251 | 257 | ||
252 | /* | 258 | /* |
@@ -399,6 +405,9 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) | |||
399 | priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT; | 405 | priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT; |
400 | priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; | 406 | priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; |
401 | priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; | 407 | priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; |
408 | |||
409 | atomic_set(&priv->wmm.tx_pkts_queued, 0); | ||
410 | atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); | ||
402 | } | 411 | } |
403 | } | 412 | } |
404 | 413 | ||
@@ -408,17 +417,13 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) | |||
408 | int | 417 | int |
409 | mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter) | 418 | mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter) |
410 | { | 419 | { |
411 | int i, j; | 420 | int i; |
412 | struct mwifiex_private *priv; | 421 | struct mwifiex_private *priv; |
413 | 422 | ||
414 | for (j = 0; j < adapter->priv_num; ++j) { | 423 | for (i = 0; i < adapter->priv_num; ++i) { |
415 | priv = adapter->priv[j]; | 424 | priv = adapter->priv[i]; |
416 | if (priv) { | 425 | if (priv && atomic_read(&priv->wmm.tx_pkts_queued)) |
417 | for (i = 0; i < MAX_NUM_TID; i++) | 426 | return false; |
418 | if (!mwifiex_wmm_is_ra_list_empty( | ||
419 | &priv->wmm.tid_tbl_ptr[i].ra_list)) | ||
420 | return false; | ||
421 | } | ||
422 | } | 427 | } |
423 | 428 | ||
424 | return true; | 429 | return true; |
@@ -468,6 +473,9 @@ static void mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv) | |||
468 | for (i = 0; i < MAX_NUM_TID; i++) | 473 | for (i = 0; i < MAX_NUM_TID; i++) |
469 | mwifiex_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i]. | 474 | mwifiex_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i]. |
470 | ra_list); | 475 | ra_list); |
476 | |||
477 | atomic_set(&priv->wmm.tx_pkts_queued, 0); | ||
478 | atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); | ||
471 | } | 479 | } |
472 | 480 | ||
473 | /* | 481 | /* |
@@ -638,6 +646,13 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, | |||
638 | 646 | ||
639 | ra_list->total_pkts_size += skb->len; | 647 | ra_list->total_pkts_size += skb->len; |
640 | 648 | ||
649 | atomic_inc(&priv->wmm.tx_pkts_queued); | ||
650 | |||
651 | if (atomic_read(&priv->wmm.highest_queued_prio) < | ||
652 | tos_to_tid_inv[tid_down]) | ||
653 | atomic_set(&priv->wmm.highest_queued_prio, | ||
654 | tos_to_tid_inv[tid_down]); | ||
655 | |||
641 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); | 656 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); |
642 | } | 657 | } |
643 | 658 | ||
@@ -863,9 +878,14 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, | |||
863 | } | 878 | } |
864 | 879 | ||
865 | do { | 880 | do { |
881 | atomic_t *hqp; | ||
882 | spinlock_t *lock; | ||
883 | |||
866 | priv_tmp = bssprio_node->priv; | 884 | priv_tmp = bssprio_node->priv; |
885 | hqp = &priv_tmp->wmm.highest_queued_prio; | ||
886 | lock = &priv_tmp->wmm.ra_list_spinlock; | ||
867 | 887 | ||
868 | for (i = HIGH_PRIO_TID; i >= LOW_PRIO_TID; --i) { | 888 | for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) { |
869 | 889 | ||
870 | tid_ptr = &(priv_tmp)->wmm. | 890 | tid_ptr = &(priv_tmp)->wmm. |
871 | tid_tbl_ptr[tos_to_tid[i]]; | 891 | tid_tbl_ptr[tos_to_tid[i]]; |
@@ -903,6 +923,11 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, | |||
903 | is_list_empty = | 923 | is_list_empty = |
904 | skb_queue_empty(&ptr->skb_head); | 924 | skb_queue_empty(&ptr->skb_head); |
905 | if (!is_list_empty) { | 925 | if (!is_list_empty) { |
926 | spin_lock_irqsave(lock, flags); | ||
927 | if (atomic_read(hqp) > i) | ||
928 | atomic_set(hqp, i); | ||
929 | spin_unlock_irqrestore(lock, | ||
930 | flags); | ||
906 | *priv = priv_tmp; | 931 | *priv = priv_tmp; |
907 | *tid = tos_to_tid[i]; | 932 | *tid = tos_to_tid[i]; |
908 | return ptr; | 933 | return ptr; |
@@ -921,6 +946,12 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, | |||
921 | } while (ptr != head); | 946 | } while (ptr != head); |
922 | } | 947 | } |
923 | 948 | ||
949 | /* No packet at any TID for this priv. Mark as such | ||
950 | * to skip checking TIDs for this priv (until pkt is | ||
951 | * added). | ||
952 | */ | ||
953 | atomic_set(hqp, NO_PKT_PRIO_TID); | ||
954 | |||
924 | /* Get next bss priority node */ | 955 | /* Get next bss priority node */ |
925 | bssprio_node = list_first_entry(&bssprio_node->list, | 956 | bssprio_node = list_first_entry(&bssprio_node->list, |
926 | struct mwifiex_bss_prio_node, | 957 | struct mwifiex_bss_prio_node, |
@@ -1028,6 +1059,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, | |||
1028 | .bss_prio_cur->list, | 1059 | .bss_prio_cur->list, |
1029 | struct mwifiex_bss_prio_node, | 1060 | struct mwifiex_bss_prio_node, |
1030 | list); | 1061 | list); |
1062 | atomic_dec(&priv->wmm.tx_pkts_queued); | ||
1031 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, | 1063 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, |
1032 | ra_list_flags); | 1064 | ra_list_flags); |
1033 | } | 1065 | } |
@@ -1134,6 +1166,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv, | |||
1134 | .bss_prio_cur->list, | 1166 | .bss_prio_cur->list, |
1135 | struct mwifiex_bss_prio_node, | 1167 | struct mwifiex_bss_prio_node, |
1136 | list); | 1168 | list); |
1169 | atomic_dec(&priv->wmm.tx_pkts_queued); | ||
1137 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, | 1170 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, |
1138 | ra_list_flags); | 1171 | ra_list_flags); |
1139 | } | 1172 | } |
@@ -1227,5 +1260,5 @@ mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter) | |||
1227 | 1260 | ||
1228 | if (mwifiex_dequeue_tx_packet(adapter)) | 1261 | if (mwifiex_dequeue_tx_packet(adapter)) |
1229 | break; | 1262 | break; |
1230 | } while (true); | 1263 | } while (!mwifiex_wmm_lists_empty(adapter)); |
1231 | } | 1264 | } |
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index e18358725b69..a8f3bc740dfa 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -82,6 +82,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { | |||
82 | {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ | 82 | {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ |
83 | {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ | 83 | {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ |
84 | {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ | 84 | {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ |
85 | {USB_DEVICE(0x083a, 0xc501)}, /* Zoom Wireless-G 4410 */ | ||
85 | {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */ | 86 | {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */ |
86 | {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */ | 87 | {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */ |
87 | {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */ | 88 | {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */ |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 518542b4bf9e..29f938930667 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -2830,7 +2830,8 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) | |||
2830 | req_ie_len, resp_ie, | 2830 | req_ie_len, resp_ie, |
2831 | resp_ie_len, 0, GFP_KERNEL); | 2831 | resp_ie_len, 0, GFP_KERNEL); |
2832 | else | 2832 | else |
2833 | cfg80211_roamed(usbdev->net, bssid, req_ie, req_ie_len, | 2833 | cfg80211_roamed(usbdev->net, NULL, bssid, |
2834 | req_ie, req_ie_len, | ||
2834 | resp_ie, resp_ie_len, GFP_KERNEL); | 2835 | resp_ie, resp_ie_len, GFP_KERNEL); |
2835 | } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) | 2836 | } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) |
2836 | cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL); | 2837 | cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL); |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index 2bb71195e976..39b0297ce925 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
@@ -190,7 +190,7 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw) | |||
190 | 190 | ||
191 | ppsc->swrf_processing = true; | 191 | ppsc->swrf_processing = true; |
192 | 192 | ||
193 | if (ppsc->inactive_pwrstate == ERFOFF && | 193 | if (ppsc->inactive_pwrstate == ERFON && |
194 | rtlhal->interface == INTF_PCI) { | 194 | rtlhal->interface == INTF_PCI) { |
195 | if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && | 195 | if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && |
196 | RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) && | 196 | RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) && |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index c5424cad43cb..d2cc81586a6a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | |||
@@ -728,7 +728,7 @@ void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, | |||
728 | return; | 728 | return; |
729 | rtlphy->set_bwmode_inprogress = true; | 729 | rtlphy->set_bwmode_inprogress = true; |
730 | if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { | 730 | if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { |
731 | rtlphy->set_bwmode_inprogress = false; | 731 | rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw); |
732 | } else { | 732 | } else { |
733 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | 733 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, |
734 | ("FALSE driver sleep or unload\n")); | 734 | ("FALSE driver sleep or unload\n")); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 73ae8a431848..abe0fcc75368 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | |||
@@ -366,6 +366,75 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | |||
366 | return true; | 366 | return true; |
367 | } | 367 | } |
368 | 368 | ||
369 | void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) | ||
370 | { | ||
371 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
372 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
373 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
374 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
375 | u8 reg_bw_opmode; | ||
376 | u8 reg_prsr_rsc; | ||
377 | |||
378 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, | ||
379 | ("Switch to %s bandwidth\n", | ||
380 | rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? | ||
381 | "20MHz" : "40MHz")) | ||
382 | |||
383 | if (is_hal_stop(rtlhal)) { | ||
384 | rtlphy->set_bwmode_inprogress = false; | ||
385 | return; | ||
386 | } | ||
387 | |||
388 | reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); | ||
389 | reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); | ||
390 | |||
391 | switch (rtlphy->current_chan_bw) { | ||
392 | case HT_CHANNEL_WIDTH_20: | ||
393 | reg_bw_opmode |= BW_OPMODE_20MHZ; | ||
394 | rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); | ||
395 | break; | ||
396 | case HT_CHANNEL_WIDTH_20_40: | ||
397 | reg_bw_opmode &= ~BW_OPMODE_20MHZ; | ||
398 | rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); | ||
399 | reg_prsr_rsc = | ||
400 | (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); | ||
401 | rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); | ||
402 | break; | ||
403 | default: | ||
404 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
405 | ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); | ||
406 | break; | ||
407 | } | ||
408 | |||
409 | switch (rtlphy->current_chan_bw) { | ||
410 | case HT_CHANNEL_WIDTH_20: | ||
411 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); | ||
412 | rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); | ||
413 | rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); | ||
414 | break; | ||
415 | case HT_CHANNEL_WIDTH_20_40: | ||
416 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); | ||
417 | rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); | ||
418 | |||
419 | rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, | ||
420 | (mac->cur_40_prime_sc >> 1)); | ||
421 | rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); | ||
422 | rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0); | ||
423 | |||
424 | rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), | ||
425 | (mac->cur_40_prime_sc == | ||
426 | HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); | ||
427 | break; | ||
428 | default: | ||
429 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
430 | ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); | ||
431 | break; | ||
432 | } | ||
433 | rtl92ce_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); | ||
434 | rtlphy->set_bwmode_inprogress = false; | ||
435 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); | ||
436 | } | ||
437 | |||
369 | void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) | 438 | void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) |
370 | { | 439 | { |
371 | u8 tmpreg; | 440 | u8 tmpreg; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h index ad580852cc76..be2c92adef33 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h | |||
@@ -257,5 +257,6 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | |||
257 | u8 configtype); | 257 | u8 configtype); |
258 | bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, | 258 | bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, |
259 | u8 configtype); | 259 | u8 configtype); |
260 | void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw); | ||
260 | 261 | ||
261 | #endif | 262 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index 390bbb5ee11d..373dc78af1dc 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | |||
@@ -232,6 +232,7 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = { | |||
232 | .config_bb_with_headerfile = _rtl92ce_phy_config_bb_with_headerfile, | 232 | .config_bb_with_headerfile = _rtl92ce_phy_config_bb_with_headerfile, |
233 | .config_bb_with_pgheaderfile = _rtl92ce_phy_config_bb_with_pgheaderfile, | 233 | .config_bb_with_pgheaderfile = _rtl92ce_phy_config_bb_with_pgheaderfile, |
234 | .phy_lc_calibrate = _rtl92ce_phy_lc_calibrate, | 234 | .phy_lc_calibrate = _rtl92ce_phy_lc_calibrate, |
235 | .phy_set_bw_mode_callback = rtl92ce_phy_set_bw_mode_callback, | ||
235 | .dm_dynamic_txpower = rtl92ce_dm_dynamic_txpower, | 236 | .dm_dynamic_txpower = rtl92ce_dm_dynamic_txpower, |
236 | }; | 237 | }; |
237 | 238 | ||
diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index bcca39418f90..5bda24e26c0e 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c | |||
@@ -570,7 +570,7 @@ ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel, | |||
570 | WLAN_STATUS_SUCCESS, GFP_KERNEL); | 570 | WLAN_STATUS_SUCCESS, GFP_KERNEL); |
571 | } else { | 571 | } else { |
572 | /* inform roam event to cfg80211 */ | 572 | /* inform roam event to cfg80211 */ |
573 | cfg80211_roamed(ar->arNetDev, bssid, | 573 | cfg80211_roamed(ar->arNetDev, ibss_channel, bssid, |
574 | assocReqIe, assocReqLen, | 574 | assocReqIe, assocReqLen, |
575 | assocRespIe, assocRespLen, | 575 | assocRespIe, assocRespLen, |
576 | GFP_KERNEL); | 576 | GFP_KERNEL); |
diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 555b056b49b1..7aaf99cc3a7b 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -2630,7 +2630,7 @@ wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev, | |||
2630 | wl_get_assoc_ies(wl); | 2630 | wl_get_assoc_ies(wl); |
2631 | memcpy(&wl->bssid, &e->addr, ETH_ALEN); | 2631 | memcpy(&wl->bssid, &e->addr, ETH_ALEN); |
2632 | wl_update_bss_info(wl); | 2632 | wl_update_bss_info(wl); |
2633 | cfg80211_roamed(ndev, | 2633 | cfg80211_roamed(ndev, NULL, |
2634 | (u8 *)&wl->bssid, | 2634 | (u8 *)&wl->bssid, |
2635 | conn_info->req_ie, conn_info->req_ie_len, | 2635 | conn_info->req_ie, conn_info->req_ie_len, |
2636 | conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); | 2636 | conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); |
@@ -2663,7 +2663,7 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev, | |||
2663 | WL_DBG("Report connect result - connection %s\n", | 2663 | WL_DBG("Report connect result - connection %s\n", |
2664 | completed ? "succeeded" : "failed"); | 2664 | completed ? "succeeded" : "failed"); |
2665 | } else { | 2665 | } else { |
2666 | cfg80211_roamed(ndev, | 2666 | cfg80211_roamed(ndev, NULL, |
2667 | (u8 *)&wl->bssid, | 2667 | (u8 *)&wl->bssid, |
2668 | conn_info->req_ie, conn_info->req_ie_len, | 2668 | conn_info->req_ie, conn_info->req_ie_len, |
2669 | conn_info->resp_ie, conn_info->resp_ie_len, | 2669 | conn_info->resp_ie, conn_info->resp_ie_len, |
diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index 76378397b763..fb466f4c92e0 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c | |||
@@ -695,7 +695,7 @@ void prism2_disconnected(wlandevice_t *wlandev) | |||
695 | 695 | ||
696 | void prism2_roamed(wlandevice_t *wlandev) | 696 | void prism2_roamed(wlandevice_t *wlandev) |
697 | { | 697 | { |
698 | cfg80211_roamed(wlandev->netdev, wlandev->bssid, | 698 | cfg80211_roamed(wlandev->netdev, NULL, wlandev->bssid, |
699 | NULL, 0, NULL, 0, GFP_KERNEL); | 699 | NULL, 0, NULL, 0, GFP_KERNEL); |
700 | } | 700 | } |
701 | 701 | ||
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index f1281339b6fa..f1637f17c37c 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -674,6 +674,7 @@ struct proc_dir_entry *proc_mkdir_mode(const char *name, mode_t mode, | |||
674 | } | 674 | } |
675 | return ent; | 675 | return ent; |
676 | } | 676 | } |
677 | EXPORT_SYMBOL(proc_mkdir_mode); | ||
677 | 678 | ||
678 | struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, | 679 | struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, |
679 | struct proc_dir_entry *parent) | 680 | struct proc_dir_entry *parent) |
diff --git a/include/linux/rfkill-gpio.h b/include/linux/rfkill-gpio.h new file mode 100644 index 000000000000..a175d0598033 --- /dev/null +++ b/include/linux/rfkill-gpio.h | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011, NVIDIA Corporation. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
17 | */ | ||
18 | |||
19 | |||
20 | #ifndef __RFKILL_GPIO_H | ||
21 | #define __RFKILL_GPIO_H | ||
22 | |||
23 | #include <linux/types.h> | ||
24 | #include <linux/rfkill.h> | ||
25 | |||
26 | /** | ||
27 | * struct rfkill_gpio_platform_data - platform data for rfkill gpio device. | ||
28 | * for unused gpio's, the expected value is -1. | ||
29 | * @name: name for the gpio rf kill instance | ||
30 | * @reset_gpio: GPIO which is used for reseting rfkill switch | ||
31 | * @shutdown_gpio: GPIO which is used for shutdown of rfkill switch | ||
32 | * @power_clk_name: [optional] name of clk to turn off while blocked | ||
33 | */ | ||
34 | |||
35 | struct rfkill_gpio_platform_data { | ||
36 | char *name; | ||
37 | int reset_gpio; | ||
38 | int shutdown_gpio; | ||
39 | const char *power_clk_name; | ||
40 | enum rfkill_type type; | ||
41 | }; | ||
42 | |||
43 | #endif /* __RFKILL_GPIO_H */ | ||
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index bfd6557946be..0589f554788a 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -531,6 +531,7 @@ struct sta_bss_parameters { | |||
531 | * @tx_retries: cumulative retry counts | 531 | * @tx_retries: cumulative retry counts |
532 | * @tx_failed: number of failed transmissions (retries exceeded, no ACK) | 532 | * @tx_failed: number of failed transmissions (retries exceeded, no ACK) |
533 | * @rx_dropped_misc: Dropped for un-specified reason. | 533 | * @rx_dropped_misc: Dropped for un-specified reason. |
534 | * @bss_param: current BSS parameters | ||
534 | * @generation: generation number for nl80211 dumps. | 535 | * @generation: generation number for nl80211 dumps. |
535 | * This number should increase every time the list of stations | 536 | * This number should increase every time the list of stations |
536 | * changes, i.e. when a station is added or removed, so that | 537 | * changes, i.e. when a station is added or removed, so that |
@@ -1537,7 +1538,7 @@ struct cfg80211_ops { | |||
1537 | * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. | 1538 | * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. |
1538 | * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing | 1539 | * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing |
1539 | * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH. | 1540 | * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH. |
1540 | * @WIPHY_FLAG_SCHED_SCAN: The device supports scheduled scans. | 1541 | * @WIPHY_FLAG_SUPPORTS_SCHED_SCAN: The device supports scheduled scans. |
1541 | */ | 1542 | */ |
1542 | enum wiphy_flags { | 1543 | enum wiphy_flags { |
1543 | WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), | 1544 | WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), |
@@ -2878,6 +2879,7 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
2878 | * cfg80211_roamed - notify cfg80211 of roaming | 2879 | * cfg80211_roamed - notify cfg80211 of roaming |
2879 | * | 2880 | * |
2880 | * @dev: network device | 2881 | * @dev: network device |
2882 | * @channel: the channel of the new AP | ||
2881 | * @bssid: the BSSID of the new AP | 2883 | * @bssid: the BSSID of the new AP |
2882 | * @req_ie: association request IEs (maybe be %NULL) | 2884 | * @req_ie: association request IEs (maybe be %NULL) |
2883 | * @req_ie_len: association request IEs length | 2885 | * @req_ie_len: association request IEs length |
@@ -2888,7 +2890,9 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
2888 | * It should be called by the underlying driver whenever it roamed | 2890 | * It should be called by the underlying driver whenever it roamed |
2889 | * from one AP to another while connected. | 2891 | * from one AP to another while connected. |
2890 | */ | 2892 | */ |
2891 | void cfg80211_roamed(struct net_device *dev, const u8 *bssid, | 2893 | void cfg80211_roamed(struct net_device *dev, |
2894 | struct ieee80211_channel *channel, | ||
2895 | const u8 *bssid, | ||
2892 | const u8 *req_ie, size_t req_ie_len, | 2896 | const u8 *req_ie, size_t req_ie_len, |
2893 | const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp); | 2897 | const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp); |
2894 | 2898 | ||
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 7dfbe71dc637..49d4f869e0bc 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -384,11 +384,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
384 | int i; | 384 | int i; |
385 | enum nl80211_channel_type orig_ct; | 385 | enum nl80211_channel_type orig_ct; |
386 | 386 | ||
387 | clear_bit(SDATA_STATE_RUNNING, &sdata->state); | ||
388 | |||
387 | if (local->scan_sdata == sdata) | 389 | if (local->scan_sdata == sdata) |
388 | ieee80211_scan_cancel(local); | 390 | ieee80211_scan_cancel(local); |
389 | 391 | ||
390 | clear_bit(SDATA_STATE_RUNNING, &sdata->state); | ||
391 | |||
392 | /* | 392 | /* |
393 | * Stop TX on this interface first. | 393 | * Stop TX on this interface first. |
394 | */ | 394 | */ |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 0d7b08db8e56..866f269183cf 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -752,11 +752,25 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
752 | hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); | 752 | hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); |
753 | hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR); | 753 | hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR); |
754 | 754 | ||
755 | /* mac80211 doesn't support more than 1 channel */ | 755 | /* |
756 | for (i = 0; i < hw->wiphy->n_iface_combinations; i++) | 756 | * mac80211 doesn't support more than 1 channel, and also not more |
757 | if (hw->wiphy->iface_combinations[i].num_different_channels > 1) | 757 | * than one IBSS interface |
758 | */ | ||
759 | for (i = 0; i < hw->wiphy->n_iface_combinations; i++) { | ||
760 | const struct ieee80211_iface_combination *c; | ||
761 | int j; | ||
762 | |||
763 | c = &hw->wiphy->iface_combinations[i]; | ||
764 | |||
765 | if (c->num_different_channels > 1) | ||
758 | return -EINVAL; | 766 | return -EINVAL; |
759 | 767 | ||
768 | for (j = 0; j < c->n_limits; j++) | ||
769 | if ((c->limits[j].types & BIT(NL80211_IFTYPE_ADHOC)) && | ||
770 | c->limits[j].max > 1) | ||
771 | return -EINVAL; | ||
772 | } | ||
773 | |||
760 | #ifndef CONFIG_MAC80211_MESH | 774 | #ifndef CONFIG_MAC80211_MESH |
761 | /* mesh depends on Kconfig, but drivers should set it if they want */ | 775 | /* mesh depends on Kconfig, but drivers should set it if they want */ |
762 | local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); | 776 | local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); |
@@ -1076,6 +1090,8 @@ static void __exit ieee80211_exit(void) | |||
1076 | ieee80211s_stop(); | 1090 | ieee80211s_stop(); |
1077 | 1091 | ||
1078 | ieee80211_iface_exit(); | 1092 | ieee80211_iface_exit(); |
1093 | |||
1094 | rcu_barrier(); | ||
1079 | } | 1095 | } |
1080 | 1096 | ||
1081 | 1097 | ||
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index e7c5fddb4804..249e733362e7 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -120,6 +120,7 @@ struct mesh_path { | |||
120 | * buckets | 120 | * buckets |
121 | * @mean_chain_len: maximum average length for the hash buckets' list, if it is | 121 | * @mean_chain_len: maximum average length for the hash buckets' list, if it is |
122 | * reached, the table will grow | 122 | * reached, the table will grow |
123 | * rcu_head: RCU head to free the table | ||
123 | */ | 124 | */ |
124 | struct mesh_table { | 125 | struct mesh_table { |
125 | /* Number of buckets will be 2^N */ | 126 | /* Number of buckets will be 2^N */ |
@@ -132,6 +133,8 @@ struct mesh_table { | |||
132 | int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl); | 133 | int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl); |
133 | int size_order; | 134 | int size_order; |
134 | int mean_chain_len; | 135 | int mean_chain_len; |
136 | |||
137 | struct rcu_head rcu_head; | ||
135 | }; | 138 | }; |
136 | 139 | ||
137 | /* Recent multicast cache */ | 140 | /* Recent multicast cache */ |
@@ -286,10 +289,6 @@ static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata) | |||
286 | return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP; | 289 | return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP; |
287 | } | 290 | } |
288 | 291 | ||
289 | #define for_each_mesh_entry(x, p, node, i) \ | ||
290 | for (i = 0; i <= x->hash_mask; i++) \ | ||
291 | hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list) | ||
292 | |||
293 | void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local); | 292 | void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local); |
294 | 293 | ||
295 | void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata); | 294 | void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata); |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 83ce48e31913..0d2faacc3e87 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -36,8 +36,8 @@ struct mpath_node { | |||
36 | struct mesh_path *mpath; | 36 | struct mesh_path *mpath; |
37 | }; | 37 | }; |
38 | 38 | ||
39 | static struct mesh_table *mesh_paths; | 39 | static struct mesh_table __rcu *mesh_paths; |
40 | static struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */ | 40 | static struct mesh_table __rcu *mpp_paths; /* Store paths for MPP&MAP */ |
41 | 41 | ||
42 | int mesh_paths_generation; | 42 | int mesh_paths_generation; |
43 | 43 | ||
@@ -48,17 +48,40 @@ int mesh_paths_generation; | |||
48 | static DEFINE_RWLOCK(pathtbl_resize_lock); | 48 | static DEFINE_RWLOCK(pathtbl_resize_lock); |
49 | 49 | ||
50 | 50 | ||
51 | static inline struct mesh_table *resize_dereference_mesh_paths(void) | ||
52 | { | ||
53 | return rcu_dereference_protected(mesh_paths, | ||
54 | lockdep_is_held(&pathtbl_resize_lock)); | ||
55 | } | ||
56 | |||
57 | static inline struct mesh_table *resize_dereference_mpp_paths(void) | ||
58 | { | ||
59 | return rcu_dereference_protected(mpp_paths, | ||
60 | lockdep_is_held(&pathtbl_resize_lock)); | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * CAREFUL -- "tbl" must not be an expression, | ||
65 | * in particular not an rcu_dereference(), since | ||
66 | * it's used twice. So it is illegal to do | ||
67 | * for_each_mesh_entry(rcu_dereference(...), ...) | ||
68 | */ | ||
69 | #define for_each_mesh_entry(tbl, p, node, i) \ | ||
70 | for (i = 0; i <= tbl->hash_mask; i++) \ | ||
71 | hlist_for_each_entry_rcu(node, p, &tbl->hash_buckets[i], list) | ||
72 | |||
73 | |||
51 | static struct mesh_table *mesh_table_alloc(int size_order) | 74 | static struct mesh_table *mesh_table_alloc(int size_order) |
52 | { | 75 | { |
53 | int i; | 76 | int i; |
54 | struct mesh_table *newtbl; | 77 | struct mesh_table *newtbl; |
55 | 78 | ||
56 | newtbl = kmalloc(sizeof(struct mesh_table), GFP_KERNEL); | 79 | newtbl = kmalloc(sizeof(struct mesh_table), GFP_ATOMIC); |
57 | if (!newtbl) | 80 | if (!newtbl) |
58 | return NULL; | 81 | return NULL; |
59 | 82 | ||
60 | newtbl->hash_buckets = kzalloc(sizeof(struct hlist_head) * | 83 | newtbl->hash_buckets = kzalloc(sizeof(struct hlist_head) * |
61 | (1 << size_order), GFP_KERNEL); | 84 | (1 << size_order), GFP_ATOMIC); |
62 | 85 | ||
63 | if (!newtbl->hash_buckets) { | 86 | if (!newtbl->hash_buckets) { |
64 | kfree(newtbl); | 87 | kfree(newtbl); |
@@ -66,7 +89,7 @@ static struct mesh_table *mesh_table_alloc(int size_order) | |||
66 | } | 89 | } |
67 | 90 | ||
68 | newtbl->hashwlock = kmalloc(sizeof(spinlock_t) * | 91 | newtbl->hashwlock = kmalloc(sizeof(spinlock_t) * |
69 | (1 << size_order), GFP_KERNEL); | 92 | (1 << size_order), GFP_ATOMIC); |
70 | if (!newtbl->hashwlock) { | 93 | if (!newtbl->hashwlock) { |
71 | kfree(newtbl->hash_buckets); | 94 | kfree(newtbl->hash_buckets); |
72 | kfree(newtbl); | 95 | kfree(newtbl); |
@@ -258,12 +281,13 @@ struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) | |||
258 | */ | 281 | */ |
259 | struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data *sdata) | 282 | struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data *sdata) |
260 | { | 283 | { |
284 | struct mesh_table *tbl = rcu_dereference(mesh_paths); | ||
261 | struct mpath_node *node; | 285 | struct mpath_node *node; |
262 | struct hlist_node *p; | 286 | struct hlist_node *p; |
263 | int i; | 287 | int i; |
264 | int j = 0; | 288 | int j = 0; |
265 | 289 | ||
266 | for_each_mesh_entry(mesh_paths, p, node, i) { | 290 | for_each_mesh_entry(tbl, p, node, i) { |
267 | if (sdata && node->mpath->sdata != sdata) | 291 | if (sdata && node->mpath->sdata != sdata) |
268 | continue; | 292 | continue; |
269 | if (j++ == idx) { | 293 | if (j++ == idx) { |
@@ -293,6 +317,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) | |||
293 | { | 317 | { |
294 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 318 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
295 | struct ieee80211_local *local = sdata->local; | 319 | struct ieee80211_local *local = sdata->local; |
320 | struct mesh_table *tbl; | ||
296 | struct mesh_path *mpath, *new_mpath; | 321 | struct mesh_path *mpath, *new_mpath; |
297 | struct mpath_node *node, *new_node; | 322 | struct mpath_node *node, *new_node; |
298 | struct hlist_head *bucket; | 323 | struct hlist_head *bucket; |
@@ -332,10 +357,12 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) | |||
332 | spin_lock_init(&new_mpath->state_lock); | 357 | spin_lock_init(&new_mpath->state_lock); |
333 | init_timer(&new_mpath->timer); | 358 | init_timer(&new_mpath->timer); |
334 | 359 | ||
335 | hash_idx = mesh_table_hash(dst, sdata, mesh_paths); | 360 | tbl = resize_dereference_mesh_paths(); |
336 | bucket = &mesh_paths->hash_buckets[hash_idx]; | 361 | |
362 | hash_idx = mesh_table_hash(dst, sdata, tbl); | ||
363 | bucket = &tbl->hash_buckets[hash_idx]; | ||
337 | 364 | ||
338 | spin_lock_bh(&mesh_paths->hashwlock[hash_idx]); | 365 | spin_lock_bh(&tbl->hashwlock[hash_idx]); |
339 | 366 | ||
340 | err = -EEXIST; | 367 | err = -EEXIST; |
341 | hlist_for_each_entry(node, n, bucket, list) { | 368 | hlist_for_each_entry(node, n, bucket, list) { |
@@ -345,13 +372,13 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) | |||
345 | } | 372 | } |
346 | 373 | ||
347 | hlist_add_head_rcu(&new_node->list, bucket); | 374 | hlist_add_head_rcu(&new_node->list, bucket); |
348 | if (atomic_inc_return(&mesh_paths->entries) >= | 375 | if (atomic_inc_return(&tbl->entries) >= |
349 | mesh_paths->mean_chain_len * (mesh_paths->hash_mask + 1)) | 376 | tbl->mean_chain_len * (tbl->hash_mask + 1)) |
350 | grow = 1; | 377 | grow = 1; |
351 | 378 | ||
352 | mesh_paths_generation++; | 379 | mesh_paths_generation++; |
353 | 380 | ||
354 | spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]); | 381 | spin_unlock_bh(&tbl->hashwlock[hash_idx]); |
355 | read_unlock_bh(&pathtbl_resize_lock); | 382 | read_unlock_bh(&pathtbl_resize_lock); |
356 | if (grow) { | 383 | if (grow) { |
357 | set_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags); | 384 | set_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags); |
@@ -360,7 +387,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) | |||
360 | return 0; | 387 | return 0; |
361 | 388 | ||
362 | err_exists: | 389 | err_exists: |
363 | spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]); | 390 | spin_unlock_bh(&tbl->hashwlock[hash_idx]); |
364 | read_unlock_bh(&pathtbl_resize_lock); | 391 | read_unlock_bh(&pathtbl_resize_lock); |
365 | kfree(new_node); | 392 | kfree(new_node); |
366 | err_node_alloc: | 393 | err_node_alloc: |
@@ -370,58 +397,59 @@ err_path_alloc: | |||
370 | return err; | 397 | return err; |
371 | } | 398 | } |
372 | 399 | ||
400 | static void mesh_table_free_rcu(struct rcu_head *rcu) | ||
401 | { | ||
402 | struct mesh_table *tbl = container_of(rcu, struct mesh_table, rcu_head); | ||
403 | |||
404 | mesh_table_free(tbl, false); | ||
405 | } | ||
406 | |||
373 | void mesh_mpath_table_grow(void) | 407 | void mesh_mpath_table_grow(void) |
374 | { | 408 | { |
375 | struct mesh_table *oldtbl, *newtbl; | 409 | struct mesh_table *oldtbl, *newtbl; |
376 | 410 | ||
377 | rcu_read_lock(); | ||
378 | newtbl = mesh_table_alloc(rcu_dereference(mesh_paths)->size_order + 1); | ||
379 | if (!newtbl) | ||
380 | return; | ||
381 | write_lock_bh(&pathtbl_resize_lock); | 411 | write_lock_bh(&pathtbl_resize_lock); |
382 | oldtbl = mesh_paths; | 412 | oldtbl = resize_dereference_mesh_paths(); |
383 | if (mesh_table_grow(mesh_paths, newtbl) < 0) { | 413 | newtbl = mesh_table_alloc(oldtbl->size_order + 1); |
384 | rcu_read_unlock(); | 414 | if (!newtbl) |
415 | goto out; | ||
416 | if (mesh_table_grow(oldtbl, newtbl) < 0) { | ||
385 | __mesh_table_free(newtbl); | 417 | __mesh_table_free(newtbl); |
386 | write_unlock_bh(&pathtbl_resize_lock); | 418 | goto out; |
387 | return; | ||
388 | } | 419 | } |
389 | rcu_read_unlock(); | ||
390 | rcu_assign_pointer(mesh_paths, newtbl); | 420 | rcu_assign_pointer(mesh_paths, newtbl); |
391 | write_unlock_bh(&pathtbl_resize_lock); | ||
392 | 421 | ||
393 | synchronize_rcu(); | 422 | call_rcu(&oldtbl->rcu_head, mesh_table_free_rcu); |
394 | mesh_table_free(oldtbl, false); | 423 | |
424 | out: | ||
425 | write_unlock_bh(&pathtbl_resize_lock); | ||
395 | } | 426 | } |
396 | 427 | ||
397 | void mesh_mpp_table_grow(void) | 428 | void mesh_mpp_table_grow(void) |
398 | { | 429 | { |
399 | struct mesh_table *oldtbl, *newtbl; | 430 | struct mesh_table *oldtbl, *newtbl; |
400 | 431 | ||
401 | rcu_read_lock(); | ||
402 | newtbl = mesh_table_alloc(rcu_dereference(mpp_paths)->size_order + 1); | ||
403 | if (!newtbl) | ||
404 | return; | ||
405 | write_lock_bh(&pathtbl_resize_lock); | 432 | write_lock_bh(&pathtbl_resize_lock); |
406 | oldtbl = mpp_paths; | 433 | oldtbl = resize_dereference_mpp_paths(); |
407 | if (mesh_table_grow(mpp_paths, newtbl) < 0) { | 434 | newtbl = mesh_table_alloc(oldtbl->size_order + 1); |
408 | rcu_read_unlock(); | 435 | if (!newtbl) |
436 | goto out; | ||
437 | if (mesh_table_grow(oldtbl, newtbl) < 0) { | ||
409 | __mesh_table_free(newtbl); | 438 | __mesh_table_free(newtbl); |
410 | write_unlock_bh(&pathtbl_resize_lock); | 439 | goto out; |
411 | return; | ||
412 | } | 440 | } |
413 | rcu_read_unlock(); | ||
414 | rcu_assign_pointer(mpp_paths, newtbl); | 441 | rcu_assign_pointer(mpp_paths, newtbl); |
415 | write_unlock_bh(&pathtbl_resize_lock); | 442 | call_rcu(&oldtbl->rcu_head, mesh_table_free_rcu); |
416 | 443 | ||
417 | synchronize_rcu(); | 444 | out: |
418 | mesh_table_free(oldtbl, false); | 445 | write_unlock_bh(&pathtbl_resize_lock); |
419 | } | 446 | } |
420 | 447 | ||
421 | int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) | 448 | int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) |
422 | { | 449 | { |
423 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 450 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
424 | struct ieee80211_local *local = sdata->local; | 451 | struct ieee80211_local *local = sdata->local; |
452 | struct mesh_table *tbl; | ||
425 | struct mesh_path *mpath, *new_mpath; | 453 | struct mesh_path *mpath, *new_mpath; |
426 | struct mpath_node *node, *new_node; | 454 | struct mpath_node *node, *new_node; |
427 | struct hlist_head *bucket; | 455 | struct hlist_head *bucket; |
@@ -456,10 +484,12 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) | |||
456 | new_mpath->exp_time = jiffies; | 484 | new_mpath->exp_time = jiffies; |
457 | spin_lock_init(&new_mpath->state_lock); | 485 | spin_lock_init(&new_mpath->state_lock); |
458 | 486 | ||
459 | hash_idx = mesh_table_hash(dst, sdata, mpp_paths); | 487 | tbl = resize_dereference_mpp_paths(); |
460 | bucket = &mpp_paths->hash_buckets[hash_idx]; | ||
461 | 488 | ||
462 | spin_lock_bh(&mpp_paths->hashwlock[hash_idx]); | 489 | hash_idx = mesh_table_hash(dst, sdata, tbl); |
490 | bucket = &tbl->hash_buckets[hash_idx]; | ||
491 | |||
492 | spin_lock_bh(&tbl->hashwlock[hash_idx]); | ||
463 | 493 | ||
464 | err = -EEXIST; | 494 | err = -EEXIST; |
465 | hlist_for_each_entry(node, n, bucket, list) { | 495 | hlist_for_each_entry(node, n, bucket, list) { |
@@ -469,11 +499,11 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) | |||
469 | } | 499 | } |
470 | 500 | ||
471 | hlist_add_head_rcu(&new_node->list, bucket); | 501 | hlist_add_head_rcu(&new_node->list, bucket); |
472 | if (atomic_inc_return(&mpp_paths->entries) >= | 502 | if (atomic_inc_return(&tbl->entries) >= |
473 | mpp_paths->mean_chain_len * (mpp_paths->hash_mask + 1)) | 503 | tbl->mean_chain_len * (tbl->hash_mask + 1)) |
474 | grow = 1; | 504 | grow = 1; |
475 | 505 | ||
476 | spin_unlock_bh(&mpp_paths->hashwlock[hash_idx]); | 506 | spin_unlock_bh(&tbl->hashwlock[hash_idx]); |
477 | read_unlock_bh(&pathtbl_resize_lock); | 507 | read_unlock_bh(&pathtbl_resize_lock); |
478 | if (grow) { | 508 | if (grow) { |
479 | set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags); | 509 | set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags); |
@@ -482,7 +512,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) | |||
482 | return 0; | 512 | return 0; |
483 | 513 | ||
484 | err_exists: | 514 | err_exists: |
485 | spin_unlock_bh(&mpp_paths->hashwlock[hash_idx]); | 515 | spin_unlock_bh(&tbl->hashwlock[hash_idx]); |
486 | read_unlock_bh(&pathtbl_resize_lock); | 516 | read_unlock_bh(&pathtbl_resize_lock); |
487 | kfree(new_node); | 517 | kfree(new_node); |
488 | err_node_alloc: | 518 | err_node_alloc: |
@@ -502,6 +532,7 @@ err_path_alloc: | |||
502 | */ | 532 | */ |
503 | void mesh_plink_broken(struct sta_info *sta) | 533 | void mesh_plink_broken(struct sta_info *sta) |
504 | { | 534 | { |
535 | struct mesh_table *tbl; | ||
505 | static const u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | 536 | static const u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
506 | struct mesh_path *mpath; | 537 | struct mesh_path *mpath; |
507 | struct mpath_node *node; | 538 | struct mpath_node *node; |
@@ -510,10 +541,11 @@ void mesh_plink_broken(struct sta_info *sta) | |||
510 | int i; | 541 | int i; |
511 | 542 | ||
512 | rcu_read_lock(); | 543 | rcu_read_lock(); |
513 | for_each_mesh_entry(mesh_paths, p, node, i) { | 544 | tbl = rcu_dereference(mesh_paths); |
545 | for_each_mesh_entry(tbl, p, node, i) { | ||
514 | mpath = node->mpath; | 546 | mpath = node->mpath; |
515 | spin_lock_bh(&mpath->state_lock); | 547 | spin_lock_bh(&mpath->state_lock); |
516 | if (mpath->next_hop == sta && | 548 | if (rcu_dereference(mpath->next_hop) == sta && |
517 | mpath->flags & MESH_PATH_ACTIVE && | 549 | mpath->flags & MESH_PATH_ACTIVE && |
518 | !(mpath->flags & MESH_PATH_FIXED)) { | 550 | !(mpath->flags & MESH_PATH_FIXED)) { |
519 | mpath->flags &= ~MESH_PATH_ACTIVE; | 551 | mpath->flags &= ~MESH_PATH_ACTIVE; |
@@ -542,30 +574,38 @@ void mesh_plink_broken(struct sta_info *sta) | |||
542 | */ | 574 | */ |
543 | void mesh_path_flush_by_nexthop(struct sta_info *sta) | 575 | void mesh_path_flush_by_nexthop(struct sta_info *sta) |
544 | { | 576 | { |
577 | struct mesh_table *tbl; | ||
545 | struct mesh_path *mpath; | 578 | struct mesh_path *mpath; |
546 | struct mpath_node *node; | 579 | struct mpath_node *node; |
547 | struct hlist_node *p; | 580 | struct hlist_node *p; |
548 | int i; | 581 | int i; |
549 | 582 | ||
550 | for_each_mesh_entry(mesh_paths, p, node, i) { | 583 | rcu_read_lock(); |
584 | tbl = rcu_dereference(mesh_paths); | ||
585 | for_each_mesh_entry(tbl, p, node, i) { | ||
551 | mpath = node->mpath; | 586 | mpath = node->mpath; |
552 | if (mpath->next_hop == sta) | 587 | if (rcu_dereference(mpath->next_hop) == sta) |
553 | mesh_path_del(mpath->dst, mpath->sdata); | 588 | mesh_path_del(mpath->dst, mpath->sdata); |
554 | } | 589 | } |
590 | rcu_read_unlock(); | ||
555 | } | 591 | } |
556 | 592 | ||
557 | void mesh_path_flush(struct ieee80211_sub_if_data *sdata) | 593 | void mesh_path_flush(struct ieee80211_sub_if_data *sdata) |
558 | { | 594 | { |
595 | struct mesh_table *tbl; | ||
559 | struct mesh_path *mpath; | 596 | struct mesh_path *mpath; |
560 | struct mpath_node *node; | 597 | struct mpath_node *node; |
561 | struct hlist_node *p; | 598 | struct hlist_node *p; |
562 | int i; | 599 | int i; |
563 | 600 | ||
564 | for_each_mesh_entry(mesh_paths, p, node, i) { | 601 | rcu_read_lock(); |
602 | tbl = rcu_dereference(mesh_paths); | ||
603 | for_each_mesh_entry(tbl, p, node, i) { | ||
565 | mpath = node->mpath; | 604 | mpath = node->mpath; |
566 | if (mpath->sdata == sdata) | 605 | if (mpath->sdata == sdata) |
567 | mesh_path_del(mpath->dst, mpath->sdata); | 606 | mesh_path_del(mpath->dst, mpath->sdata); |
568 | } | 607 | } |
608 | rcu_read_unlock(); | ||
569 | } | 609 | } |
570 | 610 | ||
571 | static void mesh_path_node_reclaim(struct rcu_head *rp) | 611 | static void mesh_path_node_reclaim(struct rcu_head *rp) |
@@ -589,6 +629,7 @@ static void mesh_path_node_reclaim(struct rcu_head *rp) | |||
589 | */ | 629 | */ |
590 | int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) | 630 | int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) |
591 | { | 631 | { |
632 | struct mesh_table *tbl; | ||
592 | struct mesh_path *mpath; | 633 | struct mesh_path *mpath; |
593 | struct mpath_node *node; | 634 | struct mpath_node *node; |
594 | struct hlist_head *bucket; | 635 | struct hlist_head *bucket; |
@@ -597,19 +638,20 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) | |||
597 | int err = 0; | 638 | int err = 0; |
598 | 639 | ||
599 | read_lock_bh(&pathtbl_resize_lock); | 640 | read_lock_bh(&pathtbl_resize_lock); |
600 | hash_idx = mesh_table_hash(addr, sdata, mesh_paths); | 641 | tbl = resize_dereference_mesh_paths(); |
601 | bucket = &mesh_paths->hash_buckets[hash_idx]; | 642 | hash_idx = mesh_table_hash(addr, sdata, tbl); |
643 | bucket = &tbl->hash_buckets[hash_idx]; | ||
602 | 644 | ||
603 | spin_lock_bh(&mesh_paths->hashwlock[hash_idx]); | 645 | spin_lock_bh(&tbl->hashwlock[hash_idx]); |
604 | hlist_for_each_entry(node, n, bucket, list) { | 646 | hlist_for_each_entry(node, n, bucket, list) { |
605 | mpath = node->mpath; | 647 | mpath = node->mpath; |
606 | if (mpath->sdata == sdata && | 648 | if (mpath->sdata == sdata && |
607 | memcmp(addr, mpath->dst, ETH_ALEN) == 0) { | 649 | memcmp(addr, mpath->dst, ETH_ALEN) == 0) { |
608 | spin_lock_bh(&mpath->state_lock); | 650 | spin_lock_bh(&mpath->state_lock); |
609 | mpath->flags |= MESH_PATH_RESOLVING; | 651 | mpath->flags |= MESH_PATH_RESOLVING; |
610 | hlist_del_rcu(&node->list); | 652 | hlist_del_rcu(&node->list); |
611 | call_rcu(&node->rcu, mesh_path_node_reclaim); | 653 | call_rcu(&node->rcu, mesh_path_node_reclaim); |
612 | atomic_dec(&mesh_paths->entries); | 654 | atomic_dec(&tbl->entries); |
613 | spin_unlock_bh(&mpath->state_lock); | 655 | spin_unlock_bh(&mpath->state_lock); |
614 | goto enddel; | 656 | goto enddel; |
615 | } | 657 | } |
@@ -618,7 +660,7 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) | |||
618 | err = -ENXIO; | 660 | err = -ENXIO; |
619 | enddel: | 661 | enddel: |
620 | mesh_paths_generation++; | 662 | mesh_paths_generation++; |
621 | spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]); | 663 | spin_unlock_bh(&tbl->hashwlock[hash_idx]); |
622 | read_unlock_bh(&pathtbl_resize_lock); | 664 | read_unlock_bh(&pathtbl_resize_lock); |
623 | return err; | 665 | return err; |
624 | } | 666 | } |
@@ -719,8 +761,10 @@ static void mesh_path_node_free(struct hlist_node *p, bool free_leafs) | |||
719 | struct mpath_node *node = hlist_entry(p, struct mpath_node, list); | 761 | struct mpath_node *node = hlist_entry(p, struct mpath_node, list); |
720 | mpath = node->mpath; | 762 | mpath = node->mpath; |
721 | hlist_del_rcu(p); | 763 | hlist_del_rcu(p); |
722 | if (free_leafs) | 764 | if (free_leafs) { |
765 | del_timer_sync(&mpath->timer); | ||
723 | kfree(mpath); | 766 | kfree(mpath); |
767 | } | ||
724 | kfree(node); | 768 | kfree(node); |
725 | } | 769 | } |
726 | 770 | ||
@@ -745,52 +789,60 @@ static int mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl) | |||
745 | 789 | ||
746 | int mesh_pathtbl_init(void) | 790 | int mesh_pathtbl_init(void) |
747 | { | 791 | { |
748 | mesh_paths = mesh_table_alloc(INIT_PATHS_SIZE_ORDER); | 792 | struct mesh_table *tbl_path, *tbl_mpp; |
749 | if (!mesh_paths) | 793 | |
794 | tbl_path = mesh_table_alloc(INIT_PATHS_SIZE_ORDER); | ||
795 | if (!tbl_path) | ||
750 | return -ENOMEM; | 796 | return -ENOMEM; |
751 | mesh_paths->free_node = &mesh_path_node_free; | 797 | tbl_path->free_node = &mesh_path_node_free; |
752 | mesh_paths->copy_node = &mesh_path_node_copy; | 798 | tbl_path->copy_node = &mesh_path_node_copy; |
753 | mesh_paths->mean_chain_len = MEAN_CHAIN_LEN; | 799 | tbl_path->mean_chain_len = MEAN_CHAIN_LEN; |
754 | 800 | ||
755 | mpp_paths = mesh_table_alloc(INIT_PATHS_SIZE_ORDER); | 801 | tbl_mpp = mesh_table_alloc(INIT_PATHS_SIZE_ORDER); |
756 | if (!mpp_paths) { | 802 | if (!tbl_mpp) { |
757 | mesh_table_free(mesh_paths, true); | 803 | mesh_table_free(tbl_path, true); |
758 | return -ENOMEM; | 804 | return -ENOMEM; |
759 | } | 805 | } |
760 | mpp_paths->free_node = &mesh_path_node_free; | 806 | tbl_mpp->free_node = &mesh_path_node_free; |
761 | mpp_paths->copy_node = &mesh_path_node_copy; | 807 | tbl_mpp->copy_node = &mesh_path_node_copy; |
762 | mpp_paths->mean_chain_len = MEAN_CHAIN_LEN; | 808 | tbl_mpp->mean_chain_len = MEAN_CHAIN_LEN; |
809 | |||
810 | /* Need no locking since this is during init */ | ||
811 | RCU_INIT_POINTER(mesh_paths, tbl_path); | ||
812 | RCU_INIT_POINTER(mpp_paths, tbl_mpp); | ||
763 | 813 | ||
764 | return 0; | 814 | return 0; |
765 | } | 815 | } |
766 | 816 | ||
767 | void mesh_path_expire(struct ieee80211_sub_if_data *sdata) | 817 | void mesh_path_expire(struct ieee80211_sub_if_data *sdata) |
768 | { | 818 | { |
819 | struct mesh_table *tbl; | ||
769 | struct mesh_path *mpath; | 820 | struct mesh_path *mpath; |
770 | struct mpath_node *node; | 821 | struct mpath_node *node; |
771 | struct hlist_node *p; | 822 | struct hlist_node *p; |
772 | int i; | 823 | int i; |
773 | 824 | ||
774 | read_lock_bh(&pathtbl_resize_lock); | 825 | rcu_read_lock(); |
775 | for_each_mesh_entry(mesh_paths, p, node, i) { | 826 | tbl = rcu_dereference(mesh_paths); |
827 | for_each_mesh_entry(tbl, p, node, i) { | ||
776 | if (node->mpath->sdata != sdata) | 828 | if (node->mpath->sdata != sdata) |
777 | continue; | 829 | continue; |
778 | mpath = node->mpath; | 830 | mpath = node->mpath; |
779 | spin_lock_bh(&mpath->state_lock); | 831 | spin_lock_bh(&mpath->state_lock); |
780 | if ((!(mpath->flags & MESH_PATH_RESOLVING)) && | 832 | if ((!(mpath->flags & MESH_PATH_RESOLVING)) && |
781 | (!(mpath->flags & MESH_PATH_FIXED)) && | 833 | (!(mpath->flags & MESH_PATH_FIXED)) && |
782 | time_after(jiffies, | 834 | time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE)) { |
783 | mpath->exp_time + MESH_PATH_EXPIRE)) { | ||
784 | spin_unlock_bh(&mpath->state_lock); | 835 | spin_unlock_bh(&mpath->state_lock); |
785 | mesh_path_del(mpath->dst, mpath->sdata); | 836 | mesh_path_del(mpath->dst, mpath->sdata); |
786 | } else | 837 | } else |
787 | spin_unlock_bh(&mpath->state_lock); | 838 | spin_unlock_bh(&mpath->state_lock); |
788 | } | 839 | } |
789 | read_unlock_bh(&pathtbl_resize_lock); | 840 | rcu_read_unlock(); |
790 | } | 841 | } |
791 | 842 | ||
792 | void mesh_pathtbl_unregister(void) | 843 | void mesh_pathtbl_unregister(void) |
793 | { | 844 | { |
794 | mesh_table_free(mesh_paths, true); | 845 | /* no need for locking during exit path */ |
795 | mesh_table_free(mpp_paths, true); | 846 | mesh_table_free(rcu_dereference_raw(mesh_paths), true); |
847 | mesh_table_free(rcu_dereference_raw(mpp_paths), true); | ||
796 | } | 848 | } |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index d20046b5d8f4..27af6723cb5e 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -719,6 +719,11 @@ void ieee80211_scan_work(struct work_struct *work) | |||
719 | * without scheduling a new work | 719 | * without scheduling a new work |
720 | */ | 720 | */ |
721 | do { | 721 | do { |
722 | if (!ieee80211_sdata_running(sdata)) { | ||
723 | aborted = true; | ||
724 | goto out_complete; | ||
725 | } | ||
726 | |||
722 | switch (local->next_scan_state) { | 727 | switch (local->next_scan_state) { |
723 | case SCAN_DECISION: | 728 | case SCAN_DECISION: |
724 | /* if no more bands/channels left, complete scan */ | 729 | /* if no more bands/channels left, complete scan */ |
diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig index 48464ca13b24..78efe895b663 100644 --- a/net/rfkill/Kconfig +++ b/net/rfkill/Kconfig | |||
@@ -33,3 +33,12 @@ config RFKILL_REGULATOR | |||
33 | 33 | ||
34 | To compile this driver as a module, choose M here: the module will | 34 | To compile this driver as a module, choose M here: the module will |
35 | be called rfkill-regulator. | 35 | be called rfkill-regulator. |
36 | |||
37 | config RFKILL_GPIO | ||
38 | tristate "GPIO RFKILL driver" | ||
39 | depends on RFKILL && GPIOLIB && HAVE_CLK | ||
40 | default n | ||
41 | help | ||
42 | If you say yes here you get support of a generic gpio RFKILL | ||
43 | driver. The platform should fill in the appropriate fields in the | ||
44 | rfkill_gpio_platform_data structure and pass that to the driver. | ||
diff --git a/net/rfkill/Makefile b/net/rfkill/Makefile index d9a5a58ffd8c..311768783f4a 100644 --- a/net/rfkill/Makefile +++ b/net/rfkill/Makefile | |||
@@ -6,3 +6,4 @@ rfkill-y += core.o | |||
6 | rfkill-$(CONFIG_RFKILL_INPUT) += input.o | 6 | rfkill-$(CONFIG_RFKILL_INPUT) += input.o |
7 | obj-$(CONFIG_RFKILL) += rfkill.o | 7 | obj-$(CONFIG_RFKILL) += rfkill.o |
8 | obj-$(CONFIG_RFKILL_REGULATOR) += rfkill-regulator.o | 8 | obj-$(CONFIG_RFKILL_REGULATOR) += rfkill-regulator.o |
9 | obj-$(CONFIG_RFKILL_GPIO) += rfkill-gpio.o | ||
diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c new file mode 100644 index 000000000000..256c5ddd2d72 --- /dev/null +++ b/net/rfkill/rfkill-gpio.c | |||
@@ -0,0 +1,227 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011, NVIDIA Corporation. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
17 | */ | ||
18 | |||
19 | #include <linux/gpio.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/rfkill.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/clk.h> | ||
26 | #include <linux/slab.h> | ||
27 | |||
28 | #include <linux/rfkill-gpio.h> | ||
29 | |||
30 | enum rfkill_gpio_clk_state { | ||
31 | UNSPECIFIED = 0, | ||
32 | PWR_ENABLED, | ||
33 | PWR_DISABLED | ||
34 | }; | ||
35 | |||
36 | #define PWR_CLK_SET(_RF, _EN) \ | ||
37 | ((_RF)->pwr_clk_enabled = (!(_EN) ? PWR_ENABLED : PWR_DISABLED)) | ||
38 | #define PWR_CLK_ENABLED(_RF) ((_RF)->pwr_clk_enabled == PWR_ENABLED) | ||
39 | #define PWR_CLK_DISABLED(_RF) ((_RF)->pwr_clk_enabled != PWR_ENABLED) | ||
40 | |||
41 | struct rfkill_gpio_data { | ||
42 | struct rfkill_gpio_platform_data *pdata; | ||
43 | struct rfkill *rfkill_dev; | ||
44 | char *reset_name; | ||
45 | char *shutdown_name; | ||
46 | enum rfkill_gpio_clk_state pwr_clk_enabled; | ||
47 | struct clk *pwr_clk; | ||
48 | }; | ||
49 | |||
50 | static int rfkill_gpio_set_power(void *data, bool blocked) | ||
51 | { | ||
52 | struct rfkill_gpio_data *rfkill = data; | ||
53 | |||
54 | if (blocked) { | ||
55 | if (gpio_is_valid(rfkill->pdata->shutdown_gpio)) | ||
56 | gpio_direction_output(rfkill->pdata->shutdown_gpio, 0); | ||
57 | if (gpio_is_valid(rfkill->pdata->reset_gpio)) | ||
58 | gpio_direction_output(rfkill->pdata->reset_gpio, 0); | ||
59 | if (rfkill->pwr_clk && PWR_CLK_ENABLED(rfkill)) | ||
60 | clk_disable(rfkill->pwr_clk); | ||
61 | } else { | ||
62 | if (rfkill->pwr_clk && PWR_CLK_DISABLED(rfkill)) | ||
63 | clk_enable(rfkill->pwr_clk); | ||
64 | if (gpio_is_valid(rfkill->pdata->reset_gpio)) | ||
65 | gpio_direction_output(rfkill->pdata->reset_gpio, 1); | ||
66 | if (gpio_is_valid(rfkill->pdata->shutdown_gpio)) | ||
67 | gpio_direction_output(rfkill->pdata->shutdown_gpio, 1); | ||
68 | } | ||
69 | |||
70 | if (rfkill->pwr_clk) | ||
71 | PWR_CLK_SET(rfkill, blocked); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static const struct rfkill_ops rfkill_gpio_ops = { | ||
77 | .set_block = rfkill_gpio_set_power, | ||
78 | }; | ||
79 | |||
80 | static int rfkill_gpio_probe(struct platform_device *pdev) | ||
81 | { | ||
82 | struct rfkill_gpio_data *rfkill; | ||
83 | struct rfkill_gpio_platform_data *pdata = pdev->dev.platform_data; | ||
84 | int ret = 0; | ||
85 | int len = 0; | ||
86 | |||
87 | if (!pdata) { | ||
88 | pr_warn("%s: No platform data specified\n", __func__); | ||
89 | return -EINVAL; | ||
90 | } | ||
91 | |||
92 | /* make sure at-least one of the GPIO is defined and that | ||
93 | * a name is specified for this instance */ | ||
94 | if (!pdata->name || (!gpio_is_valid(pdata->reset_gpio) && | ||
95 | !gpio_is_valid(pdata->shutdown_gpio))) { | ||
96 | pr_warn("%s: invalid platform data\n", __func__); | ||
97 | return -EINVAL; | ||
98 | } | ||
99 | |||
100 | rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL); | ||
101 | if (!rfkill) | ||
102 | return -ENOMEM; | ||
103 | |||
104 | rfkill->pdata = pdata; | ||
105 | |||
106 | len = strlen(pdata->name); | ||
107 | rfkill->reset_name = kzalloc(len + 7, GFP_KERNEL); | ||
108 | if (!rfkill->reset_name) { | ||
109 | ret = -ENOMEM; | ||
110 | goto fail_alloc; | ||
111 | } | ||
112 | |||
113 | rfkill->shutdown_name = kzalloc(len + 10, GFP_KERNEL); | ||
114 | if (!rfkill->shutdown_name) { | ||
115 | ret = -ENOMEM; | ||
116 | goto fail_reset_name; | ||
117 | } | ||
118 | |||
119 | snprintf(rfkill->reset_name, len + 6 , "%s_reset", pdata->name); | ||
120 | snprintf(rfkill->shutdown_name, len + 9, "%s_shutdown", pdata->name); | ||
121 | |||
122 | if (pdata->power_clk_name) { | ||
123 | rfkill->pwr_clk = clk_get(&pdev->dev, pdata->power_clk_name); | ||
124 | if (IS_ERR(rfkill->pwr_clk)) { | ||
125 | pr_warn("%s: can't find pwr_clk.\n", __func__); | ||
126 | goto fail_shutdown_name; | ||
127 | } | ||
128 | } | ||
129 | |||
130 | if (gpio_is_valid(pdata->reset_gpio)) { | ||
131 | ret = gpio_request(pdata->reset_gpio, rfkill->reset_name); | ||
132 | if (ret) { | ||
133 | pr_warn("%s: failed to get reset gpio.\n", __func__); | ||
134 | goto fail_clock; | ||
135 | } | ||
136 | } | ||
137 | |||
138 | if (gpio_is_valid(pdata->shutdown_gpio)) { | ||
139 | ret = gpio_request(pdata->shutdown_gpio, rfkill->shutdown_name); | ||
140 | if (ret) { | ||
141 | pr_warn("%s: failed to get shutdown gpio.\n", __func__); | ||
142 | goto fail_reset; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | rfkill->rfkill_dev = rfkill_alloc(pdata->name, &pdev->dev, pdata->type, | ||
147 | &rfkill_gpio_ops, rfkill); | ||
148 | if (!rfkill->rfkill_dev) | ||
149 | goto fail_shutdown; | ||
150 | |||
151 | ret = rfkill_register(rfkill->rfkill_dev); | ||
152 | if (ret < 0) | ||
153 | goto fail_rfkill; | ||
154 | |||
155 | platform_set_drvdata(pdev, rfkill); | ||
156 | |||
157 | dev_info(&pdev->dev, "%s device registered.\n", pdata->name); | ||
158 | |||
159 | return 0; | ||
160 | |||
161 | fail_rfkill: | ||
162 | rfkill_destroy(rfkill->rfkill_dev); | ||
163 | fail_shutdown: | ||
164 | if (gpio_is_valid(pdata->shutdown_gpio)) | ||
165 | gpio_free(pdata->shutdown_gpio); | ||
166 | fail_reset: | ||
167 | if (gpio_is_valid(pdata->reset_gpio)) | ||
168 | gpio_free(pdata->reset_gpio); | ||
169 | fail_clock: | ||
170 | if (rfkill->pwr_clk) | ||
171 | clk_put(rfkill->pwr_clk); | ||
172 | fail_shutdown_name: | ||
173 | kfree(rfkill->shutdown_name); | ||
174 | fail_reset_name: | ||
175 | kfree(rfkill->reset_name); | ||
176 | fail_alloc: | ||
177 | kfree(rfkill); | ||
178 | |||
179 | return ret; | ||
180 | } | ||
181 | |||
182 | static int rfkill_gpio_remove(struct platform_device *pdev) | ||
183 | { | ||
184 | struct rfkill_gpio_data *rfkill = platform_get_drvdata(pdev); | ||
185 | |||
186 | rfkill_unregister(rfkill->rfkill_dev); | ||
187 | rfkill_destroy(rfkill->rfkill_dev); | ||
188 | if (gpio_is_valid(rfkill->pdata->shutdown_gpio)) | ||
189 | gpio_free(rfkill->pdata->shutdown_gpio); | ||
190 | if (gpio_is_valid(rfkill->pdata->reset_gpio)) | ||
191 | gpio_free(rfkill->pdata->reset_gpio); | ||
192 | if (rfkill->pwr_clk && PWR_CLK_ENABLED(rfkill)) | ||
193 | clk_disable(rfkill->pwr_clk); | ||
194 | if (rfkill->pwr_clk) | ||
195 | clk_put(rfkill->pwr_clk); | ||
196 | kfree(rfkill->shutdown_name); | ||
197 | kfree(rfkill->reset_name); | ||
198 | kfree(rfkill); | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static struct platform_driver rfkill_gpio_driver = { | ||
204 | .probe = rfkill_gpio_probe, | ||
205 | .remove = __devexit_p(rfkill_gpio_remove), | ||
206 | .driver = { | ||
207 | .name = "rfkill_gpio", | ||
208 | .owner = THIS_MODULE, | ||
209 | }, | ||
210 | }; | ||
211 | |||
212 | static int __init rfkill_gpio_init(void) | ||
213 | { | ||
214 | return platform_driver_register(&rfkill_gpio_driver); | ||
215 | } | ||
216 | |||
217 | static void __exit rfkill_gpio_exit(void) | ||
218 | { | ||
219 | platform_driver_unregister(&rfkill_gpio_driver); | ||
220 | } | ||
221 | |||
222 | module_init(rfkill_gpio_init); | ||
223 | module_exit(rfkill_gpio_exit); | ||
224 | |||
225 | MODULE_DESCRIPTION("gpio rfkill"); | ||
226 | MODULE_AUTHOR("NVIDIA"); | ||
227 | MODULE_LICENSE("GPL"); | ||
diff --git a/net/wireless/core.h b/net/wireless/core.h index bf0fb40e3c8b..3dce1f167eba 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -245,6 +245,7 @@ struct cfg80211_event { | |||
245 | u16 status; | 245 | u16 status; |
246 | } cr; | 246 | } cr; |
247 | struct { | 247 | struct { |
248 | struct ieee80211_channel *channel; | ||
248 | u8 bssid[ETH_ALEN]; | 249 | u8 bssid[ETH_ALEN]; |
249 | const u8 *req_ie; | 250 | const u8 *req_ie; |
250 | const u8 *resp_ie; | 251 | const u8 *resp_ie; |
@@ -392,7 +393,9 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev, | |||
392 | int cfg80211_disconnect(struct cfg80211_registered_device *rdev, | 393 | int cfg80211_disconnect(struct cfg80211_registered_device *rdev, |
393 | struct net_device *dev, u16 reason, | 394 | struct net_device *dev, u16 reason, |
394 | bool wextev); | 395 | bool wextev); |
395 | void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid, | 396 | void __cfg80211_roamed(struct wireless_dev *wdev, |
397 | struct ieee80211_channel *channel, | ||
398 | const u8 *bssid, | ||
396 | const u8 *req_ie, size_t req_ie_len, | 399 | const u8 *req_ie, size_t req_ie_len, |
397 | const u8 *resp_ie, size_t resp_ie_len); | 400 | const u8 *resp_ie, size_t resp_ie_len); |
398 | int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, | 401 | int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 2222ce08ee91..ec83f413a7ed 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -3294,8 +3294,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
3294 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 3294 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
3295 | struct net_device *dev = info->user_ptr[1]; | 3295 | struct net_device *dev = info->user_ptr[1]; |
3296 | struct cfg80211_scan_request *request; | 3296 | struct cfg80211_scan_request *request; |
3297 | struct cfg80211_ssid *ssid; | ||
3298 | struct ieee80211_channel *channel; | ||
3299 | struct nlattr *attr; | 3297 | struct nlattr *attr; |
3300 | struct wiphy *wiphy; | 3298 | struct wiphy *wiphy; |
3301 | int err, tmp, n_ssids = 0, n_channels, i; | 3299 | int err, tmp, n_ssids = 0, n_channels, i; |
@@ -3342,8 +3340,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
3342 | return -EINVAL; | 3340 | return -EINVAL; |
3343 | 3341 | ||
3344 | request = kzalloc(sizeof(*request) | 3342 | request = kzalloc(sizeof(*request) |
3345 | + sizeof(*ssid) * n_ssids | 3343 | + sizeof(*request->ssids) * n_ssids |
3346 | + sizeof(channel) * n_channels | 3344 | + sizeof(*request->channels) * n_channels |
3347 | + ie_len, GFP_KERNEL); | 3345 | + ie_len, GFP_KERNEL); |
3348 | if (!request) | 3346 | if (!request) |
3349 | return -ENOMEM; | 3347 | return -ENOMEM; |
@@ -3449,8 +3447,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
3449 | struct cfg80211_sched_scan_request *request; | 3447 | struct cfg80211_sched_scan_request *request; |
3450 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 3448 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
3451 | struct net_device *dev = info->user_ptr[1]; | 3449 | struct net_device *dev = info->user_ptr[1]; |
3452 | struct cfg80211_ssid *ssid; | ||
3453 | struct ieee80211_channel *channel; | ||
3454 | struct nlattr *attr; | 3450 | struct nlattr *attr; |
3455 | struct wiphy *wiphy; | 3451 | struct wiphy *wiphy; |
3456 | int err, tmp, n_ssids = 0, n_channels, i; | 3452 | int err, tmp, n_ssids = 0, n_channels, i; |
@@ -3507,8 +3503,8 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
3507 | return -EINVAL; | 3503 | return -EINVAL; |
3508 | 3504 | ||
3509 | request = kzalloc(sizeof(*request) | 3505 | request = kzalloc(sizeof(*request) |
3510 | + sizeof(*ssid) * n_ssids | 3506 | + sizeof(*request->ssids) * n_ssids |
3511 | + sizeof(channel) * n_channels | 3507 | + sizeof(*request->channels) * n_channels |
3512 | + ie_len, GFP_KERNEL); | 3508 | + ie_len, GFP_KERNEL); |
3513 | if (!request) | 3509 | if (!request) |
3514 | return -ENOMEM; | 3510 | return -ENOMEM; |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index e17b0bee6bdc..b7b6ff8be553 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -250,7 +250,8 @@ static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev) | |||
250 | if (wdev->conn->params.privacy) | 250 | if (wdev->conn->params.privacy) |
251 | capa |= WLAN_CAPABILITY_PRIVACY; | 251 | capa |= WLAN_CAPABILITY_PRIVACY; |
252 | 252 | ||
253 | bss = cfg80211_get_bss(wdev->wiphy, NULL, wdev->conn->params.bssid, | 253 | bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel, |
254 | wdev->conn->params.bssid, | ||
254 | wdev->conn->params.ssid, | 255 | wdev->conn->params.ssid, |
255 | wdev->conn->params.ssid_len, | 256 | wdev->conn->params.ssid_len, |
256 | WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY, | 257 | WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY, |
@@ -470,7 +471,10 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
470 | } | 471 | } |
471 | 472 | ||
472 | if (!bss) | 473 | if (!bss) |
473 | bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, | 474 | bss = cfg80211_get_bss(wdev->wiphy, |
475 | wdev->conn ? wdev->conn->params.channel : | ||
476 | NULL, | ||
477 | bssid, | ||
474 | wdev->ssid, wdev->ssid_len, | 478 | wdev->ssid, wdev->ssid_len, |
475 | WLAN_CAPABILITY_ESS, | 479 | WLAN_CAPABILITY_ESS, |
476 | WLAN_CAPABILITY_ESS); | 480 | WLAN_CAPABILITY_ESS); |
@@ -538,7 +542,9 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
538 | } | 542 | } |
539 | EXPORT_SYMBOL(cfg80211_connect_result); | 543 | EXPORT_SYMBOL(cfg80211_connect_result); |
540 | 544 | ||
541 | void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid, | 545 | void __cfg80211_roamed(struct wireless_dev *wdev, |
546 | struct ieee80211_channel *channel, | ||
547 | const u8 *bssid, | ||
542 | const u8 *req_ie, size_t req_ie_len, | 548 | const u8 *req_ie, size_t req_ie_len, |
543 | const u8 *resp_ie, size_t resp_ie_len) | 549 | const u8 *resp_ie, size_t resp_ie_len) |
544 | { | 550 | { |
@@ -565,7 +571,7 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid, | |||
565 | cfg80211_put_bss(&wdev->current_bss->pub); | 571 | cfg80211_put_bss(&wdev->current_bss->pub); |
566 | wdev->current_bss = NULL; | 572 | wdev->current_bss = NULL; |
567 | 573 | ||
568 | bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, | 574 | bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, |
569 | wdev->ssid, wdev->ssid_len, | 575 | wdev->ssid, wdev->ssid_len, |
570 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | 576 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); |
571 | 577 | ||
@@ -603,7 +609,9 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid, | |||
603 | #endif | 609 | #endif |
604 | } | 610 | } |
605 | 611 | ||
606 | void cfg80211_roamed(struct net_device *dev, const u8 *bssid, | 612 | void cfg80211_roamed(struct net_device *dev, |
613 | struct ieee80211_channel *channel, | ||
614 | const u8 *bssid, | ||
607 | const u8 *req_ie, size_t req_ie_len, | 615 | const u8 *req_ie, size_t req_ie_len, |
608 | const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp) | 616 | const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp) |
609 | { | 617 | { |
@@ -619,6 +627,7 @@ void cfg80211_roamed(struct net_device *dev, const u8 *bssid, | |||
619 | return; | 627 | return; |
620 | 628 | ||
621 | ev->type = EVENT_ROAMED; | 629 | ev->type = EVENT_ROAMED; |
630 | ev->rm.channel = channel; | ||
622 | memcpy(ev->rm.bssid, bssid, ETH_ALEN); | 631 | memcpy(ev->rm.bssid, bssid, ETH_ALEN); |
623 | ev->rm.req_ie = ((u8 *)ev) + sizeof(*ev); | 632 | ev->rm.req_ie = ((u8 *)ev) + sizeof(*ev); |
624 | ev->rm.req_ie_len = req_ie_len; | 633 | ev->rm.req_ie_len = req_ie_len; |
diff --git a/net/wireless/util.c b/net/wireless/util.c index f0536d44d43c..4d7b83fbc32f 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -746,7 +746,7 @@ static void cfg80211_process_wdev_events(struct wireless_dev *wdev) | |||
746 | NULL); | 746 | NULL); |
747 | break; | 747 | break; |
748 | case EVENT_ROAMED: | 748 | case EVENT_ROAMED: |
749 | __cfg80211_roamed(wdev, ev->rm.bssid, | 749 | __cfg80211_roamed(wdev, ev->rm.channel, ev->rm.bssid, |
750 | ev->rm.req_ie, ev->rm.req_ie_len, | 750 | ev->rm.req_ie, ev->rm.req_ie_len, |
751 | ev->rm.resp_ie, ev->rm.resp_ie_len); | 751 | ev->rm.resp_ie, ev->rm.resp_ie_len); |
752 | break; | 752 | break; |