aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-03-06 15:46:08 -0500
committerDavid S. Miller <davem@davemloft.net>2015-03-06 15:46:08 -0500
commit28c0f02ffe8a614bc7e1aa57319a62e7ce700d04 (patch)
tree078ee8553662a5f6d82d31859c160ceab866c2d6 /drivers/net/wireless/brcm80211/brcmfmac
parent89650ad0047f039b3c3bc0f6a5823bb9c9738152 (diff)
parent1ca2760fb2c13959fcba794695cd5b306cbfa6a4 (diff)
Merge tag 'wireless-drivers-next-for-davem-2015-03-06' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Major changes: brcmfmac: * sdio improvements * add a debugfs file so users can provide us all the revinfo we could ask for iwlwifi: * add triggers for firmware dump collection * remove support for -9.ucode * new statitics API * rate control improvements ath9k: * add per-vif TX power capability * BT coexistance fixes ath10k: * qca6174: enable STA transmit beamforming (TxBF) support * disable multi-vif power save by default bcma: * enable support for PCIe Gen 2 host devices Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c166
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c13
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/core.c30
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.c115
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.h47
5 files changed, 274 insertions, 97 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 7944224e3fc9..c438ccdb6ed8 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -58,6 +58,14 @@
58#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */ 58#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
59#define BRCMF_DEFAULT_RXGLOM_SIZE 32 /* max rx frames in glom chain */ 59#define BRCMF_DEFAULT_RXGLOM_SIZE 32 /* max rx frames in glom chain */
60 60
61struct brcmf_sdiod_freezer {
62 atomic_t freezing;
63 atomic_t thread_count;
64 u32 frozen_count;
65 wait_queue_head_t thread_freeze;
66 struct completion resumed;
67};
68
61static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE; 69static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
62module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0); 70module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0);
63MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]"); 71MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
@@ -197,6 +205,30 @@ int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
197 return 0; 205 return 0;
198} 206}
199 207
208void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
209 enum brcmf_sdiod_state state)
210{
211 if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM ||
212 state == sdiodev->state)
213 return;
214
215 brcmf_dbg(TRACE, "%d -> %d\n", sdiodev->state, state);
216 switch (sdiodev->state) {
217 case BRCMF_SDIOD_DATA:
218 /* any other state means bus interface is down */
219 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN);
220 break;
221 case BRCMF_SDIOD_DOWN:
222 /* transition from DOWN to DATA means bus interface is up */
223 if (state == BRCMF_SDIOD_DATA)
224 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_UP);
225 break;
226 default:
227 break;
228 }
229 sdiodev->state = state;
230}
231
200static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, 232static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func,
201 uint regaddr, u8 byte) 233 uint regaddr, u8 byte)
202{ 234{
@@ -269,12 +301,6 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn,
269 return ret; 301 return ret;
270} 302}
271 303
272static void brcmf_sdiod_nomedium_state(struct brcmf_sdio_dev *sdiodev)
273{
274 sdiodev->state = BRCMF_STATE_NOMEDIUM;
275 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN);
276}
277
278static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, 304static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
279 u8 regsz, void *data, bool write) 305 u8 regsz, void *data, bool write)
280{ 306{
@@ -282,7 +308,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
282 s32 retry = 0; 308 s32 retry = 0;
283 int ret; 309 int ret;
284 310
285 if (sdiodev->state == BRCMF_STATE_NOMEDIUM) 311 if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
286 return -ENOMEDIUM; 312 return -ENOMEDIUM;
287 313
288 /* 314 /*
@@ -308,7 +334,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
308 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); 334 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
309 335
310 if (ret == -ENOMEDIUM) 336 if (ret == -ENOMEDIUM)
311 brcmf_sdiod_nomedium_state(sdiodev); 337 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
312 else if (ret != 0) { 338 else if (ret != 0) {
313 /* 339 /*
314 * SleepCSR register access can fail when 340 * SleepCSR register access can fail when
@@ -331,7 +357,7 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
331 int err = 0, i; 357 int err = 0, i;
332 u8 addr[3]; 358 u8 addr[3];
333 359
334 if (sdiodev->state == BRCMF_STATE_NOMEDIUM) 360 if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
335 return -ENOMEDIUM; 361 return -ENOMEDIUM;
336 362
337 addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; 363 addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
@@ -460,7 +486,7 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
460 err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr, 486 err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr,
461 req_sz); 487 req_sz);
462 if (err == -ENOMEDIUM) 488 if (err == -ENOMEDIUM)
463 brcmf_sdiod_nomedium_state(sdiodev); 489 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
464 return err; 490 return err;
465} 491}
466 492
@@ -595,7 +621,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
595 621
596 ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; 622 ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error;
597 if (ret == -ENOMEDIUM) { 623 if (ret == -ENOMEDIUM) {
598 brcmf_sdiod_nomedium_state(sdiodev); 624 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
599 break; 625 break;
600 } else if (ret != 0) { 626 } else if (ret != 0) {
601 brcmf_err("CMD53 sg block %s failed %d\n", 627 brcmf_err("CMD53 sg block %s failed %d\n",
@@ -877,6 +903,87 @@ static void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
877 sdiodev->txglomsz = brcmf_sdiod_txglomsz; 903 sdiodev->txglomsz = brcmf_sdiod_txglomsz;
878} 904}
879 905
906#ifdef CONFIG_PM_SLEEP
907static int brcmf_sdiod_freezer_attach(struct brcmf_sdio_dev *sdiodev)
908{
909 sdiodev->freezer = kzalloc(sizeof(*sdiodev->freezer), GFP_KERNEL);
910 if (!sdiodev->freezer)
911 return -ENOMEM;
912 atomic_set(&sdiodev->freezer->thread_count, 0);
913 atomic_set(&sdiodev->freezer->freezing, 0);
914 init_waitqueue_head(&sdiodev->freezer->thread_freeze);
915 init_completion(&sdiodev->freezer->resumed);
916 return 0;
917}
918
919static void brcmf_sdiod_freezer_detach(struct brcmf_sdio_dev *sdiodev)
920{
921 if (sdiodev->freezer) {
922 WARN_ON(atomic_read(&sdiodev->freezer->freezing));
923 kfree(sdiodev->freezer);
924 }
925}
926
927static int brcmf_sdiod_freezer_on(struct brcmf_sdio_dev *sdiodev)
928{
929 atomic_t *expect = &sdiodev->freezer->thread_count;
930 int res = 0;
931
932 sdiodev->freezer->frozen_count = 0;
933 reinit_completion(&sdiodev->freezer->resumed);
934 atomic_set(&sdiodev->freezer->freezing, 1);
935 brcmf_sdio_trigger_dpc(sdiodev->bus);
936 wait_event(sdiodev->freezer->thread_freeze,
937 atomic_read(expect) == sdiodev->freezer->frozen_count);
938 sdio_claim_host(sdiodev->func[1]);
939 res = brcmf_sdio_sleep(sdiodev->bus, true);
940 sdio_release_host(sdiodev->func[1]);
941 return res;
942}
943
944static void brcmf_sdiod_freezer_off(struct brcmf_sdio_dev *sdiodev)
945{
946 sdio_claim_host(sdiodev->func[1]);
947 brcmf_sdio_sleep(sdiodev->bus, false);
948 sdio_release_host(sdiodev->func[1]);
949 atomic_set(&sdiodev->freezer->freezing, 0);
950 complete_all(&sdiodev->freezer->resumed);
951}
952
953bool brcmf_sdiod_freezing(struct brcmf_sdio_dev *sdiodev)
954{
955 return atomic_read(&sdiodev->freezer->freezing);
956}
957
958void brcmf_sdiod_try_freeze(struct brcmf_sdio_dev *sdiodev)
959{
960 if (!brcmf_sdiod_freezing(sdiodev))
961 return;
962 sdiodev->freezer->frozen_count++;
963 wake_up(&sdiodev->freezer->thread_freeze);
964 wait_for_completion(&sdiodev->freezer->resumed);
965}
966
967void brcmf_sdiod_freezer_count(struct brcmf_sdio_dev *sdiodev)
968{
969 atomic_inc(&sdiodev->freezer->thread_count);
970}
971
972void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev)
973{
974 atomic_dec(&sdiodev->freezer->thread_count);
975}
976#else
977static int brcmf_sdiod_freezer_attach(struct brcmf_sdio_dev *sdiodev)
978{
979 return 0;
980}
981
982static void brcmf_sdiod_freezer_detach(struct brcmf_sdio_dev *sdiodev)
983{
984}
985#endif /* CONFIG_PM_SLEEP */
986
880static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) 987static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
881{ 988{
882 if (sdiodev->bus) { 989 if (sdiodev->bus) {
@@ -884,6 +991,8 @@ static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
884 sdiodev->bus = NULL; 991 sdiodev->bus = NULL;
885 } 992 }
886 993
994 brcmf_sdiod_freezer_detach(sdiodev);
995
887 /* Disable Function 2 */ 996 /* Disable Function 2 */
888 sdio_claim_host(sdiodev->func[2]); 997 sdio_claim_host(sdiodev->func[2]);
889 sdio_disable_func(sdiodev->func[2]); 998 sdio_disable_func(sdiodev->func[2]);
@@ -955,6 +1064,10 @@ static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
955 */ 1064 */
956 brcmf_sdiod_sgtable_alloc(sdiodev); 1065 brcmf_sdiod_sgtable_alloc(sdiodev);
957 1066
1067 ret = brcmf_sdiod_freezer_attach(sdiodev);
1068 if (ret)
1069 goto out;
1070
958 /* try to attach to the target device */ 1071 /* try to attach to the target device */
959 sdiodev->bus = brcmf_sdio_probe(sdiodev); 1072 sdiodev->bus = brcmf_sdio_probe(sdiodev);
960 if (!sdiodev->bus) { 1073 if (!sdiodev->bus) {
@@ -1050,9 +1163,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
1050 bus_if->wowl_supported = true; 1163 bus_if->wowl_supported = true;
1051#endif 1164#endif
1052 1165
1053 sdiodev->sleeping = false; 1166 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN);
1054 atomic_set(&sdiodev->suspend, false);
1055 init_waitqueue_head(&sdiodev->idle_wait);
1056 1167
1057 brcmf_dbg(SDIO, "F2 found, calling brcmf_sdiod_probe...\n"); 1168 brcmf_dbg(SDIO, "F2 found, calling brcmf_sdiod_probe...\n");
1058 err = brcmf_sdiod_probe(sdiodev); 1169 err = brcmf_sdiod_probe(sdiodev);
@@ -1114,24 +1225,22 @@ void brcmf_sdio_wowl_config(struct device *dev, bool enabled)
1114#ifdef CONFIG_PM_SLEEP 1225#ifdef CONFIG_PM_SLEEP
1115static int brcmf_ops_sdio_suspend(struct device *dev) 1226static int brcmf_ops_sdio_suspend(struct device *dev)
1116{ 1227{
1228 struct sdio_func *func;
1117 struct brcmf_bus *bus_if; 1229 struct brcmf_bus *bus_if;
1118 struct brcmf_sdio_dev *sdiodev; 1230 struct brcmf_sdio_dev *sdiodev;
1119 mmc_pm_flag_t sdio_flags; 1231 mmc_pm_flag_t sdio_flags;
1120 1232
1121 brcmf_dbg(SDIO, "Enter\n"); 1233 func = container_of(dev, struct sdio_func, dev);
1234 brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
1235 if (func->num != SDIO_FUNC_1)
1236 return 0;
1237
1122 1238
1123 bus_if = dev_get_drvdata(dev); 1239 bus_if = dev_get_drvdata(dev);
1124 sdiodev = bus_if->bus_priv.sdio; 1240 sdiodev = bus_if->bus_priv.sdio;
1125 1241
1126 /* wait for watchdog to go idle */ 1242 brcmf_sdiod_freezer_on(sdiodev);
1127 if (wait_event_timeout(sdiodev->idle_wait, sdiodev->sleeping,
1128 msecs_to_jiffies(3 * BRCMF_WD_POLL_MS)) == 0) {
1129 brcmf_err("bus still active\n");
1130 return -EBUSY;
1131 }
1132 /* disable watchdog */
1133 brcmf_sdio_wd_timer(sdiodev->bus, 0); 1243 brcmf_sdio_wd_timer(sdiodev->bus, 0);
1134 atomic_set(&sdiodev->suspend, true);
1135 1244
1136 if (sdiodev->wowl_enabled) { 1245 if (sdiodev->wowl_enabled) {
1137 sdio_flags = MMC_PM_KEEP_POWER; 1246 sdio_flags = MMC_PM_KEEP_POWER;
@@ -1149,12 +1258,13 @@ static int brcmf_ops_sdio_resume(struct device *dev)
1149{ 1258{
1150 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 1259 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1151 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 1260 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
1261 struct sdio_func *func = container_of(dev, struct sdio_func, dev);
1152 1262
1153 brcmf_dbg(SDIO, "Enter\n"); 1263 brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
1154 if (sdiodev->pdata && sdiodev->pdata->oob_irq_supported) 1264 if (func->num != SDIO_FUNC_2)
1155 disable_irq_wake(sdiodev->pdata->oob_irq_nr); 1265 return 0;
1156 brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); 1266
1157 atomic_set(&sdiodev->suspend, false); 1267 brcmf_sdiod_freezer_off(sdiodev);
1158 return 0; 1268 return 0;
1159} 1269}
1160 1270
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
index 06727a61b438..9b805c9fd51e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
@@ -1050,10 +1050,6 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1050 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) 1050 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
1051 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; 1051 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1052 1052
1053 /* Arm scan timeout timer */
1054 mod_timer(&cfg->escan_timeout, jiffies +
1055 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1056
1057 escan_req = false; 1053 escan_req = false;
1058 if (request) { 1054 if (request) {
1059 /* scan bss */ 1055 /* scan bss */
@@ -1112,12 +1108,14 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1112 } 1108 }
1113 } 1109 }
1114 1110
1111 /* Arm scan timeout timer */
1112 mod_timer(&cfg->escan_timeout, jiffies +
1113 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1114
1115 return 0; 1115 return 0;
1116 1116
1117scan_out: 1117scan_out:
1118 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); 1118 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1119 if (timer_pending(&cfg->escan_timeout))
1120 del_timer_sync(&cfg->escan_timeout);
1121 cfg->scan_request = NULL; 1119 cfg->scan_request = NULL;
1122 return err; 1120 return err;
1123} 1121}
@@ -2252,7 +2250,6 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2252 2250
2253 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) { 2251 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2254 /* we ignore this key index in this case */ 2252 /* we ignore this key index in this case */
2255 brcmf_err("invalid key index (%d)\n", key_idx);
2256 return -EINVAL; 2253 return -EINVAL;
2257 } 2254 }
2258 2255
@@ -4272,7 +4269,7 @@ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4272 return -EIO; 4269 return -EIO;
4273 4270
4274 memcpy(&scbval.ea, params->mac, ETH_ALEN); 4271 memcpy(&scbval.ea, params->mac, ETH_ALEN);
4275 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING); 4272 scbval.val = cpu_to_le32(params->reason_code);
4276 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON, 4273 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4277 &scbval, sizeof(scbval)); 4274 &scbval, sizeof(scbval));
4278 if (err) 4275 if (err)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/core.c b/drivers/net/wireless/brcm80211/brcmfmac/core.c
index 2d6e2cc1b12c..f8f47dcfa886 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
@@ -944,6 +944,34 @@ fail:
944 return ret; 944 return ret;
945} 945}
946 946
947static int brcmf_revinfo_read(struct seq_file *s, void *data)
948{
949 struct brcmf_bus *bus_if = dev_get_drvdata(s->private);
950 struct brcmf_rev_info *ri = &bus_if->drvr->revinfo;
951 char drev[BRCMU_DOTREV_LEN];
952 char brev[BRCMU_BOARDREV_LEN];
953
954 seq_printf(s, "vendorid: 0x%04x\n", ri->vendorid);
955 seq_printf(s, "deviceid: 0x%04x\n", ri->deviceid);
956 seq_printf(s, "radiorev: %s\n", brcmu_dotrev_str(ri->radiorev, drev));
957 seq_printf(s, "chipnum: %u (%x)\n", ri->chipnum, ri->chipnum);
958 seq_printf(s, "chiprev: %u\n", ri->chiprev);
959 seq_printf(s, "chippkg: %u\n", ri->chippkg);
960 seq_printf(s, "corerev: %u\n", ri->corerev);
961 seq_printf(s, "boardid: 0x%04x\n", ri->boardid);
962 seq_printf(s, "boardvendor: 0x%04x\n", ri->boardvendor);
963 seq_printf(s, "boardrev: %s\n", brcmu_boardrev_str(ri->boardrev, brev));
964 seq_printf(s, "driverrev: %s\n", brcmu_dotrev_str(ri->driverrev, drev));
965 seq_printf(s, "ucoderev: %u\n", ri->ucoderev);
966 seq_printf(s, "bus: %u\n", ri->bus);
967 seq_printf(s, "phytype: %u\n", ri->phytype);
968 seq_printf(s, "phyrev: %u\n", ri->phyrev);
969 seq_printf(s, "anarev: %u\n", ri->anarev);
970 seq_printf(s, "nvramrev: %08x\n", ri->nvramrev);
971
972 return 0;
973}
974
947int brcmf_bus_start(struct device *dev) 975int brcmf_bus_start(struct device *dev)
948{ 976{
949 int ret = -1; 977 int ret = -1;
@@ -974,6 +1002,8 @@ int brcmf_bus_start(struct device *dev)
974 if (ret < 0) 1002 if (ret < 0)
975 goto fail; 1003 goto fail;
976 1004
1005 brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read);
1006
977 /* assure we have chipid before feature attach */ 1007 /* assure we have chipid before feature attach */
978 if (!bus_if->chip) { 1008 if (!bus_if->chip) {
979 bus_if->chip = drvr->revinfo.chipnum; 1009 bus_if->chip = drvr->revinfo.chipnum;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
index faec35c899ec..257ee70feb5b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
@@ -515,6 +515,7 @@ struct brcmf_sdio {
515 bool txoff; /* Transmit flow-controlled */ 515 bool txoff; /* Transmit flow-controlled */
516 struct brcmf_sdio_count sdcnt; 516 struct brcmf_sdio_count sdcnt;
517 bool sr_enabled; /* SaveRestore enabled */ 517 bool sr_enabled; /* SaveRestore enabled */
518 bool sleeping;
518 519
519 u8 tx_hdrlen; /* sdio bus header length for tx packet */ 520 u8 tx_hdrlen; /* sdio bus header length for tx packet */
520 bool txglom; /* host tx glomming enable flag */ 521 bool txglom; /* host tx glomming enable flag */
@@ -1013,12 +1014,12 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
1013 1014
1014 brcmf_dbg(SDIO, "Enter: request %s currently %s\n", 1015 brcmf_dbg(SDIO, "Enter: request %s currently %s\n",
1015 (sleep ? "SLEEP" : "WAKE"), 1016 (sleep ? "SLEEP" : "WAKE"),
1016 (bus->sdiodev->sleeping ? "SLEEP" : "WAKE")); 1017 (bus->sleeping ? "SLEEP" : "WAKE"));
1017 1018
1018 /* If SR is enabled control bus state with KSO */ 1019 /* If SR is enabled control bus state with KSO */
1019 if (bus->sr_enabled) { 1020 if (bus->sr_enabled) {
1020 /* Done if we're already in the requested state */ 1021 /* Done if we're already in the requested state */
1021 if (sleep == bus->sdiodev->sleeping) 1022 if (sleep == bus->sleeping)
1022 goto end; 1023 goto end;
1023 1024
1024 /* Going to sleep */ 1025 /* Going to sleep */
@@ -1026,6 +1027,7 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
1026 /* Don't sleep if something is pending */ 1027 /* Don't sleep if something is pending */
1027 if (atomic_read(&bus->intstatus) || 1028 if (atomic_read(&bus->intstatus) ||
1028 atomic_read(&bus->ipend) > 0 || 1029 atomic_read(&bus->ipend) > 0 ||
1030 bus->ctrl_frame_stat ||
1029 (!atomic_read(&bus->fcstate) && 1031 (!atomic_read(&bus->fcstate) &&
1030 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && 1032 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
1031 data_ok(bus))) { 1033 data_ok(bus))) {
@@ -1065,9 +1067,7 @@ end:
1065 } else { 1067 } else {
1066 brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok); 1068 brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok);
1067 } 1069 }
1068 bus->sdiodev->sleeping = sleep; 1070 bus->sleeping = sleep;
1069 if (sleep)
1070 wake_up(&bus->sdiodev->idle_wait);
1071 brcmf_dbg(SDIO, "new state %s\n", 1071 brcmf_dbg(SDIO, "new state %s\n",
1072 (sleep ? "SLEEP" : "WAKE")); 1072 (sleep ? "SLEEP" : "WAKE"));
1073done: 1073done:
@@ -1909,7 +1909,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1909 bus->rxpending = true; 1909 bus->rxpending = true;
1910 1910
1911 for (rd->seq_num = bus->rx_seq, rxleft = maxframes; 1911 for (rd->seq_num = bus->rx_seq, rxleft = maxframes;
1912 !bus->rxskip && rxleft && bus->sdiodev->state == BRCMF_STATE_DATA; 1912 !bus->rxskip && rxleft && bus->sdiodev->state == BRCMF_SDIOD_DATA;
1913 rd->seq_num++, rxleft--) { 1913 rd->seq_num++, rxleft--) {
1914 1914
1915 /* Handle glomming separately */ 1915 /* Handle glomming separately */
@@ -2415,7 +2415,7 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2415 } 2415 }
2416 2416
2417 /* Deflow-control stack if needed */ 2417 /* Deflow-control stack if needed */
2418 if ((bus->sdiodev->state == BRCMF_STATE_DATA) && 2418 if ((bus->sdiodev->state == BRCMF_SDIOD_DATA) &&
2419 bus->txoff && (pktq_len(&bus->txq) < TXLOW)) { 2419 bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
2420 bus->txoff = false; 2420 bus->txoff = false;
2421 brcmf_txflowblock(bus->sdiodev->dev, false); 2421 brcmf_txflowblock(bus->sdiodev->dev, false);
@@ -2503,7 +2503,7 @@ static void brcmf_sdio_bus_stop(struct device *dev)
2503 bus->watchdog_tsk = NULL; 2503 bus->watchdog_tsk = NULL;
2504 } 2504 }
2505 2505
2506 if (sdiodev->state != BRCMF_STATE_NOMEDIUM) { 2506 if (sdiodev->state != BRCMF_SDIOD_NOMEDIUM) {
2507 sdio_claim_host(sdiodev->func[1]); 2507 sdio_claim_host(sdiodev->func[1]);
2508 2508
2509 /* Enable clock for device interrupts */ 2509 /* Enable clock for device interrupts */
@@ -2603,21 +2603,6 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
2603 return ret; 2603 return ret;
2604} 2604}
2605 2605
2606static int brcmf_sdio_pm_resume_wait(struct brcmf_sdio_dev *sdiodev)
2607{
2608#ifdef CONFIG_PM_SLEEP
2609 int retry;
2610
2611 /* Wait for possible resume to complete */
2612 retry = 0;
2613 while ((atomic_read(&sdiodev->suspend)) && (retry++ != 50))
2614 msleep(20);
2615 if (atomic_read(&sdiodev->suspend))
2616 return -EIO;
2617#endif
2618 return 0;
2619}
2620
2621static void brcmf_sdio_dpc(struct brcmf_sdio *bus) 2606static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2622{ 2607{
2623 u32 newstatus = 0; 2608 u32 newstatus = 0;
@@ -2628,9 +2613,6 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2628 2613
2629 brcmf_dbg(TRACE, "Enter\n"); 2614 brcmf_dbg(TRACE, "Enter\n");
2630 2615
2631 if (brcmf_sdio_pm_resume_wait(bus->sdiodev))
2632 return;
2633
2634 sdio_claim_host(bus->sdiodev->func[1]); 2616 sdio_claim_host(bus->sdiodev->func[1]);
2635 2617
2636 /* If waiting for HTAVAIL, check status */ 2618 /* If waiting for HTAVAIL, check status */
@@ -2755,7 +2737,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2755 brcmf_sdio_sendfromq(bus, framecnt); 2737 brcmf_sdio_sendfromq(bus, framecnt);
2756 } 2738 }
2757 2739
2758 if ((bus->sdiodev->state != BRCMF_STATE_DATA) || (err != 0)) { 2740 if ((bus->sdiodev->state != BRCMF_SDIOD_DATA) || (err != 0)) {
2759 brcmf_err("failed backplane access over SDIO, halting operation\n"); 2741 brcmf_err("failed backplane access over SDIO, halting operation\n");
2760 atomic_set(&bus->intstatus, 0); 2742 atomic_set(&bus->intstatus, 0);
2761 } else if (atomic_read(&bus->intstatus) || 2743 } else if (atomic_read(&bus->intstatus) ||
@@ -2862,11 +2844,7 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
2862 qcount[prec] = pktq_plen(&bus->txq, prec); 2844 qcount[prec] = pktq_plen(&bus->txq, prec);
2863#endif 2845#endif
2864 2846
2865 if (atomic_read(&bus->dpc_tskcnt) == 0) { 2847 brcmf_sdio_trigger_dpc(bus);
2866 atomic_inc(&bus->dpc_tskcnt);
2867 queue_work(bus->brcmf_wq, &bus->datawork);
2868 }
2869
2870 return ret; 2848 return ret;
2871} 2849}
2872 2850
@@ -2964,11 +2942,8 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2964 bus->ctrl_frame_buf = msg; 2942 bus->ctrl_frame_buf = msg;
2965 bus->ctrl_frame_len = msglen; 2943 bus->ctrl_frame_len = msglen;
2966 bus->ctrl_frame_stat = true; 2944 bus->ctrl_frame_stat = true;
2967 if (atomic_read(&bus->dpc_tskcnt) == 0) {
2968 atomic_inc(&bus->dpc_tskcnt);
2969 queue_work(bus->brcmf_wq, &bus->datawork);
2970 }
2971 2945
2946 brcmf_sdio_trigger_dpc(bus);
2972 wait_event_interruptible_timeout(bus->ctrl_wait, !bus->ctrl_frame_stat, 2947 wait_event_interruptible_timeout(bus->ctrl_wait, !bus->ctrl_frame_stat,
2973 msecs_to_jiffies(CTL_DONE_TIMEOUT)); 2948 msecs_to_jiffies(CTL_DONE_TIMEOUT));
2974 2949
@@ -3411,7 +3386,7 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
3411 } 3386 }
3412 3387
3413 /* Allow full data communication using DPC from now on. */ 3388 /* Allow full data communication using DPC from now on. */
3414 bus->sdiodev->state = BRCMF_STATE_DATA; 3389 brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA);
3415 bcmerror = 0; 3390 bcmerror = 0;
3416 3391
3417err: 3392err:
@@ -3548,6 +3523,14 @@ done:
3548 return err; 3523 return err;
3549} 3524}
3550 3525
3526void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus)
3527{
3528 if (atomic_read(&bus->dpc_tskcnt) == 0) {
3529 atomic_inc(&bus->dpc_tskcnt);
3530 queue_work(bus->brcmf_wq, &bus->datawork);
3531 }
3532}
3533
3551void brcmf_sdio_isr(struct brcmf_sdio *bus) 3534void brcmf_sdio_isr(struct brcmf_sdio *bus)
3552{ 3535{
3553 brcmf_dbg(TRACE, "Enter\n"); 3536 brcmf_dbg(TRACE, "Enter\n");
@@ -3557,7 +3540,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus)
3557 return; 3540 return;
3558 } 3541 }
3559 3542
3560 if (bus->sdiodev->state != BRCMF_STATE_DATA) { 3543 if (bus->sdiodev->state != BRCMF_SDIOD_DATA) {
3561 brcmf_err("bus is down. we have nothing to do\n"); 3544 brcmf_err("bus is down. we have nothing to do\n");
3562 return; 3545 return;
3563 } 3546 }
@@ -3602,9 +3585,8 @@ static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
3602 SDIO_CCCR_INTx, 3585 SDIO_CCCR_INTx,
3603 NULL); 3586 NULL);
3604 sdio_release_host(bus->sdiodev->func[1]); 3587 sdio_release_host(bus->sdiodev->func[1]);
3605 intstatus = 3588 intstatus = devpend & (INTR_STATUS_FUNC1 |
3606 devpend & (INTR_STATUS_FUNC1 | 3589 INTR_STATUS_FUNC2);
3607 INTR_STATUS_FUNC2);
3608 } 3590 }
3609 3591
3610 /* If there is something, make like the ISR and 3592 /* If there is something, make like the ISR and
@@ -3623,7 +3605,7 @@ static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
3623 } 3605 }
3624#ifdef DEBUG 3606#ifdef DEBUG
3625 /* Poll for console output periodically */ 3607 /* Poll for console output periodically */
3626 if (bus->sdiodev->state == BRCMF_STATE_DATA && 3608 if (bus->sdiodev->state == BRCMF_SDIOD_DATA &&
3627 bus->console_interval != 0) { 3609 bus->console_interval != 0) {
3628 bus->console.count += BRCMF_WD_POLL_MS; 3610 bus->console.count += BRCMF_WD_POLL_MS;
3629 if (bus->console.count >= bus->console_interval) { 3611 if (bus->console.count >= bus->console_interval) {
@@ -3667,6 +3649,11 @@ static void brcmf_sdio_dataworker(struct work_struct *work)
3667 atomic_set(&bus->dpc_tskcnt, 0); 3649 atomic_set(&bus->dpc_tskcnt, 0);
3668 brcmf_sdio_dpc(bus); 3650 brcmf_sdio_dpc(bus);
3669 } 3651 }
3652 if (brcmf_sdiod_freezing(bus->sdiodev)) {
3653 brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DOWN);
3654 brcmf_sdiod_try_freeze(bus->sdiodev);
3655 brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA);
3656 }
3670} 3657}
3671 3658
3672static void 3659static void
@@ -3944,13 +3931,19 @@ static int
3944brcmf_sdio_watchdog_thread(void *data) 3931brcmf_sdio_watchdog_thread(void *data)
3945{ 3932{
3946 struct brcmf_sdio *bus = (struct brcmf_sdio *)data; 3933 struct brcmf_sdio *bus = (struct brcmf_sdio *)data;
3934 int wait;
3947 3935
3948 allow_signal(SIGTERM); 3936 allow_signal(SIGTERM);
3949 /* Run until signal received */ 3937 /* Run until signal received */
3938 brcmf_sdiod_freezer_count(bus->sdiodev);
3950 while (1) { 3939 while (1) {
3951 if (kthread_should_stop()) 3940 if (kthread_should_stop())
3952 break; 3941 break;
3953 if (!wait_for_completion_interruptible(&bus->watchdog_wait)) { 3942 brcmf_sdiod_freezer_uncount(bus->sdiodev);
3943 wait = wait_for_completion_interruptible(&bus->watchdog_wait);
3944 brcmf_sdiod_freezer_count(bus->sdiodev);
3945 brcmf_sdiod_try_freeze(bus->sdiodev);
3946 if (!wait) {
3954 brcmf_sdio_bus_watchdog(bus); 3947 brcmf_sdio_bus_watchdog(bus);
3955 /* Count the tick for reference */ 3948 /* Count the tick for reference */
3956 bus->sdcnt.tickcnt++; 3949 bus->sdcnt.tickcnt++;
@@ -3971,7 +3964,7 @@ brcmf_sdio_watchdog(unsigned long data)
3971 /* Reschedule the watchdog */ 3964 /* Reschedule the watchdog */
3972 if (bus->wd_timer_valid) 3965 if (bus->wd_timer_valid)
3973 mod_timer(&bus->timer, 3966 mod_timer(&bus->timer,
3974 jiffies + BRCMF_WD_POLL_MS * HZ / 1000); 3967 jiffies + msecs_to_jiffies(BRCMF_WD_POLL_MS));
3975 } 3968 }
3976} 3969}
3977 3970
@@ -4089,6 +4082,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4089{ 4082{
4090 int ret; 4083 int ret;
4091 struct brcmf_sdio *bus; 4084 struct brcmf_sdio *bus;
4085 struct workqueue_struct *wq;
4092 4086
4093 brcmf_dbg(TRACE, "Enter\n"); 4087 brcmf_dbg(TRACE, "Enter\n");
4094 4088
@@ -4117,12 +4111,16 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4117 bus->sgentry_align = sdiodev->pdata->sd_sgentry_align; 4111 bus->sgentry_align = sdiodev->pdata->sd_sgentry_align;
4118 } 4112 }
4119 4113
4120 INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); 4114 /* single-threaded workqueue */
4121 bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); 4115 wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM,
4122 if (bus->brcmf_wq == NULL) { 4116 dev_name(&sdiodev->func[1]->dev));
4117 if (!wq) {
4123 brcmf_err("insufficient memory to create txworkqueue\n"); 4118 brcmf_err("insufficient memory to create txworkqueue\n");
4124 goto fail; 4119 goto fail;
4125 } 4120 }
4121 brcmf_sdiod_freezer_count(sdiodev);
4122 INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
4123 bus->brcmf_wq = wq;
4126 4124
4127 /* attempt to attach to the dongle */ 4125 /* attempt to attach to the dongle */
4128 if (!(brcmf_sdio_probe_attach(bus))) { 4126 if (!(brcmf_sdio_probe_attach(bus))) {
@@ -4143,7 +4141,8 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4143 /* Initialize watchdog thread */ 4141 /* Initialize watchdog thread */
4144 init_completion(&bus->watchdog_wait); 4142 init_completion(&bus->watchdog_wait);
4145 bus->watchdog_tsk = kthread_run(brcmf_sdio_watchdog_thread, 4143 bus->watchdog_tsk = kthread_run(brcmf_sdio_watchdog_thread,
4146 bus, "brcmf_watchdog"); 4144 bus, "brcmf_wdog/%s",
4145 dev_name(&sdiodev->func[1]->dev));
4147 if (IS_ERR(bus->watchdog_tsk)) { 4146 if (IS_ERR(bus->watchdog_tsk)) {
4148 pr_warn("brcmf_watchdog thread failed to start\n"); 4147 pr_warn("brcmf_watchdog thread failed to start\n");
4149 bus->watchdog_tsk = NULL; 4148 bus->watchdog_tsk = NULL;
@@ -4242,7 +4241,7 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
4242 destroy_workqueue(bus->brcmf_wq); 4241 destroy_workqueue(bus->brcmf_wq);
4243 4242
4244 if (bus->ci) { 4243 if (bus->ci) {
4245 if (bus->sdiodev->state != BRCMF_STATE_NOMEDIUM) { 4244 if (bus->sdiodev->state != BRCMF_SDIOD_NOMEDIUM) {
4246 sdio_claim_host(bus->sdiodev->func[1]); 4245 sdio_claim_host(bus->sdiodev->func[1]);
4247 brcmf_sdio_clkctl(bus, CLK_AVAIL, false); 4246 brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
4248 /* Leave the device in state where it is 4247 /* Leave the device in state where it is
@@ -4277,7 +4276,7 @@ void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick)
4277 } 4276 }
4278 4277
4279 /* don't start the wd until fw is loaded */ 4278 /* don't start the wd until fw is loaded */
4280 if (bus->sdiodev->state != BRCMF_STATE_DATA) 4279 if (bus->sdiodev->state != BRCMF_SDIOD_DATA)
4281 return; 4280 return;
4282 4281
4283 if (wdtick) { 4282 if (wdtick) {
@@ -4290,16 +4289,28 @@ void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick)
4290 dynamically changed or in the first instance 4289 dynamically changed or in the first instance
4291 */ 4290 */
4292 bus->timer.expires = 4291 bus->timer.expires =
4293 jiffies + BRCMF_WD_POLL_MS * HZ / 1000; 4292 jiffies + msecs_to_jiffies(BRCMF_WD_POLL_MS);
4294 add_timer(&bus->timer); 4293 add_timer(&bus->timer);
4295 4294
4296 } else { 4295 } else {
4297 /* Re arm the timer, at last watchdog period */ 4296 /* Re arm the timer, at last watchdog period */
4298 mod_timer(&bus->timer, 4297 mod_timer(&bus->timer,
4299 jiffies + BRCMF_WD_POLL_MS * HZ / 1000); 4298 jiffies + msecs_to_jiffies(BRCMF_WD_POLL_MS));
4300 } 4299 }
4301 4300
4302 bus->wd_timer_valid = true; 4301 bus->wd_timer_valid = true;
4303 bus->save_ms = wdtick; 4302 bus->save_ms = wdtick;
4304 } 4303 }
4305} 4304}
4305
4306int brcmf_sdio_sleep(struct brcmf_sdio *bus, bool sleep)
4307{
4308 int ret;
4309
4310 sdio_claim_host(bus->sdiodev->func[1]);
4311 ret = brcmf_sdio_bus_sleep(bus, sleep, false);
4312 sdio_release_host(bus->sdiodev->func[1]);
4313
4314 return ret;
4315}
4316
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h
index ec2586a8425c..7328478b2d7b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h
@@ -155,11 +155,17 @@
155/* watchdog polling interval in ms */ 155/* watchdog polling interval in ms */
156#define BRCMF_WD_POLL_MS 10 156#define BRCMF_WD_POLL_MS 10
157 157
158/* The state of the bus */ 158/**
159enum brcmf_sdio_state { 159 * enum brcmf_sdiod_state - the state of the bus.
160 BRCMF_STATE_DOWN, /* Device available, still initialising */ 160 *
161 BRCMF_STATE_DATA, /* Ready for data transfers, DPC enabled */ 161 * @BRCMF_SDIOD_DOWN: Device can be accessed, no DPC.
162 BRCMF_STATE_NOMEDIUM /* No medium access to dongle possible */ 162 * @BRCMF_SDIOD_DATA: Ready for data transfers, DPC enabled.
163 * @BRCMF_SDIOD_NOMEDIUM: No medium access to dongle possible.
164 */
165enum brcmf_sdiod_state {
166 BRCMF_SDIOD_DOWN,
167 BRCMF_SDIOD_DATA,
168 BRCMF_SDIOD_NOMEDIUM
163}; 169};
164 170
165struct brcmf_sdreg { 171struct brcmf_sdreg {
@@ -169,15 +175,13 @@ struct brcmf_sdreg {
169}; 175};
170 176
171struct brcmf_sdio; 177struct brcmf_sdio;
178struct brcmf_sdiod_freezer;
172 179
173struct brcmf_sdio_dev { 180struct brcmf_sdio_dev {
174 struct sdio_func *func[SDIO_MAX_FUNCS]; 181 struct sdio_func *func[SDIO_MAX_FUNCS];
175 u8 num_funcs; /* Supported funcs on client */ 182 u8 num_funcs; /* Supported funcs on client */
176 u32 sbwad; /* Save backplane window address */ 183 u32 sbwad; /* Save backplane window address */
177 struct brcmf_sdio *bus; 184 struct brcmf_sdio *bus;
178 atomic_t suspend; /* suspend flag */
179 bool sleeping;
180 wait_queue_head_t idle_wait;
181 struct device *dev; 185 struct device *dev;
182 struct brcmf_bus *bus_if; 186 struct brcmf_bus *bus_if;
183 struct brcmfmac_sdio_platform_data *pdata; 187 struct brcmfmac_sdio_platform_data *pdata;
@@ -194,7 +198,8 @@ struct brcmf_sdio_dev {
194 char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; 198 char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
195 char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; 199 char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
196 bool wowl_enabled; 200 bool wowl_enabled;
197 enum brcmf_sdio_state state; 201 enum brcmf_sdiod_state state;
202 struct brcmf_sdiod_freezer *freezer;
198}; 203};
199 204
200/* sdio core registers */ 205/* sdio core registers */
@@ -337,6 +342,28 @@ int brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
337 342
338/* Issue an abort to the specified function */ 343/* Issue an abort to the specified function */
339int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn); 344int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn);
345void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
346 enum brcmf_sdiod_state state);
347#ifdef CONFIG_PM_SLEEP
348bool brcmf_sdiod_freezing(struct brcmf_sdio_dev *sdiodev);
349void brcmf_sdiod_try_freeze(struct brcmf_sdio_dev *sdiodev);
350void brcmf_sdiod_freezer_count(struct brcmf_sdio_dev *sdiodev);
351void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev);
352#else
353static inline bool brcmf_sdiod_freezing(struct brcmf_sdio_dev *sdiodev)
354{
355 return false;
356}
357static inline void brcmf_sdiod_try_freeze(struct brcmf_sdio_dev *sdiodev)
358{
359}
360static inline void brcmf_sdiod_freezer_count(struct brcmf_sdio_dev *sdiodev)
361{
362}
363static inline void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev)
364{
365}
366#endif /* CONFIG_PM_SLEEP */
340 367
341struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); 368struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
342void brcmf_sdio_remove(struct brcmf_sdio *bus); 369void brcmf_sdio_remove(struct brcmf_sdio *bus);
@@ -344,5 +371,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus);
344 371
345void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick); 372void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick);
346void brcmf_sdio_wowl_config(struct device *dev, bool enabled); 373void brcmf_sdio_wowl_config(struct device *dev, bool enabled);
374int brcmf_sdio_sleep(struct brcmf_sdio *bus, bool sleep);
375void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus);
347 376
348#endif /* BRCMFMAC_SDIO_H */ 377#endif /* BRCMFMAC_SDIO_H */