1 /* 2 * Copyright (c) 2012 Qualcomm Atheros, 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 17 #include <linux/moduleparam.h> 18 #include <linux/if_arp.h> 19 20 #include "wil6210.h" 21 22 /* 23 * Due to a hardware issue, 24 * one has to read/write to/from NIC in 32-bit chunks; 25 * regular memcpy_fromio and siblings will 26 * not work on 64-bit platform - it uses 64-bit transactions 27 * 28 * Force 32-bit transactions to enable NIC on 64-bit platforms 29 * 30 * To avoid byte swap on big endian host, __raw_{read|write}l 31 * should be used - {read|write}l would swap bytes to provide 32 * little endian on PCI value in host endianness. 33 */ 34 void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src, 35 size_t count) 36 { 37 u32 *d = dst; 38 const volatile u32 __iomem *s = src; 39 40 /* size_t is unsigned, if (count%4 != 0) it will wrap */ 41 for (count += 4; count > 4; count -= 4) 42 *d++ = __raw_readl(s++); 43 } 44 45 void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, 46 size_t count) 47 { 48 volatile u32 __iomem *d = dst; 49 const u32 *s = src; 50 51 for (count += 4; count > 4; count -= 4) 52 __raw_writel(*s++, d++); 53 } 54 55 static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid) 56 { 57 uint i; 58 struct net_device *ndev = wil_to_ndev(wil); 59 struct wireless_dev *wdev = wil->wdev; 60 61 wil_dbg_misc(wil, "%s()\n", __func__); 62 63 wil_link_off(wil); 64 clear_bit(wil_status_fwconnected, &wil->status); 65 66 switch (wdev->sme_state) { 67 case CFG80211_SME_CONNECTED: 68 cfg80211_disconnected(ndev, WLAN_STATUS_UNSPECIFIED_FAILURE, 69 NULL, 0, GFP_KERNEL); 70 break; 71 case CFG80211_SME_CONNECTING: 72 cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0, 73 WLAN_STATUS_UNSPECIFIED_FAILURE, 74 GFP_KERNEL); 75 break; 76 default: 77 break; 78 } 79 80 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) 81 wil_vring_fini_tx(wil, i); 82 83 clear_bit(wil_status_dontscan, &wil->status); 84 } 85 86 static void wil_disconnect_worker(struct work_struct *work) 87 { 88 struct wil6210_priv *wil = container_of(work, 89 struct wil6210_priv, disconnect_worker); 90 91 _wil6210_disconnect(wil, NULL); 92 } 93 94 static void wil_connect_timer_fn(ulong x) 95 { 96 struct wil6210_priv *wil = (void *)x; 97 98 wil_dbg_misc(wil, "Connect timeout\n"); 99 100 /* reschedule to thread context - disconnect won't 101 * run from atomic context 102 */ 103 schedule_work(&wil->disconnect_worker); 104 } 105 106 static void wil_connect_worker(struct work_struct *work) 107 { 108 int rc; 109 struct wil6210_priv *wil = container_of(work, struct wil6210_priv, 110 connect_worker); 111 int cid = wil->pending_connect_cid; 112 113 if (cid < 0) { 114 wil_err(wil, "No connection pending\n"); 115 return; 116 } 117 118 wil_dbg_wmi(wil, "Configure for connection CID %d\n", cid); 119 120 rc = wil_vring_init_tx(wil, 0, WIL6210_TX_RING_SIZE, cid, 0); 121 wil->pending_connect_cid = -1; 122 if (rc == 0) 123 wil_link_on(wil); 124 } 125 126 int wil_priv_init(struct wil6210_priv *wil) 127 { 128 wil_dbg_misc(wil, "%s()\n", __func__); 129 130 mutex_init(&wil->mutex); 131 mutex_init(&wil->wmi_mutex); 132 133 init_completion(&wil->wmi_ready); 134 135 wil->pending_connect_cid = -1; 136 setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil); 137 138 INIT_WORK(&wil->connect_worker, wil_connect_worker); 139 INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker); 140 INIT_WORK(&wil->wmi_event_worker, wmi_event_worker); 141 142 INIT_LIST_HEAD(&wil->pending_wmi_ev); 143 spin_lock_init(&wil->wmi_ev_lock); 144 145 wil->wmi_wq = create_singlethread_workqueue(WIL_NAME"_wmi"); 146 if (!wil->wmi_wq) 147 return -EAGAIN; 148 149 wil->wmi_wq_conn = create_singlethread_workqueue(WIL_NAME"_connect"); 150 if (!wil->wmi_wq_conn) { 151 destroy_workqueue(wil->wmi_wq); 152 return -EAGAIN; 153 } 154 155 return 0; 156 } 157 158 void wil6210_disconnect(struct wil6210_priv *wil, void *bssid) 159 { 160 del_timer_sync(&wil->connect_timer); 161 _wil6210_disconnect(wil, bssid); 162 } 163 164 void wil_priv_deinit(struct wil6210_priv *wil) 165 { 166 cancel_work_sync(&wil->disconnect_worker); 167 wil6210_disconnect(wil, NULL); 168 wmi_event_flush(wil); 169 destroy_workqueue(wil->wmi_wq_conn); 170 destroy_workqueue(wil->wmi_wq); 171 } 172 173 static void wil_target_reset(struct wil6210_priv *wil) 174 { 175 wil_dbg_misc(wil, "Resetting...\n"); 176 177 /* register write */ 178 #define W(a, v) iowrite32(v, wil->csr + HOSTADDR(a)) 179 /* register set = read, OR, write */ 180 #define S(a, v) iowrite32(ioread32(wil->csr + HOSTADDR(a)) | v, \ 181 wil->csr + HOSTADDR(a)) 182 183 /* hpal_perst_from_pad_src_n_mask */ 184 S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(6)); 185 /* car_perst_rst_src_n_mask */ 186 S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(7)); 187 188 W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */ 189 W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */ 190 191 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); 192 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F); 193 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000170); 194 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00); 195 196 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0); 197 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0); 198 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0); 199 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 200 201 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001); 202 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080); 203 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 204 205 wil_dbg_misc(wil, "Reset completed\n"); 206 207 #undef W 208 #undef S 209 } 210 211 void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r) 212 { 213 le32_to_cpus(&r->base); 214 le16_to_cpus(&r->entry_size); 215 le16_to_cpus(&r->size); 216 le32_to_cpus(&r->tail); 217 le32_to_cpus(&r->head); 218 } 219 220 static int wil_wait_for_fw_ready(struct wil6210_priv *wil) 221 { 222 ulong to = msecs_to_jiffies(1000); 223 ulong left = wait_for_completion_timeout(&wil->wmi_ready, to); 224 if (0 == left) { 225 wil_err(wil, "Firmware not ready\n"); 226 return -ETIME; 227 } else { 228 wil_dbg_misc(wil, "FW ready after %d ms\n", 229 jiffies_to_msecs(to-left)); 230 } 231 return 0; 232 } 233 234 /* 235 * We reset all the structures, and we reset the UMAC. 236 * After calling this routine, you're expected to reload 237 * the firmware. 238 */ 239 int wil_reset(struct wil6210_priv *wil) 240 { 241 int rc; 242 243 cancel_work_sync(&wil->disconnect_worker); 244 wil6210_disconnect(wil, NULL); 245 246 wil6210_disable_irq(wil); 247 wil->status = 0; 248 249 wmi_event_flush(wil); 250 251 flush_workqueue(wil->wmi_wq_conn); 252 flush_workqueue(wil->wmi_wq); 253 254 /* TODO: put MAC in reset */ 255 wil_target_reset(wil); 256 257 /* init after reset */ 258 wil->pending_connect_cid = -1; 259 INIT_COMPLETION(wil->wmi_ready); 260 261 /* TODO: release MAC reset */ 262 wil6210_enable_irq(wil); 263 264 /* we just started MAC, wait for FW ready */ 265 rc = wil_wait_for_fw_ready(wil); 266 267 return rc; 268 } 269 270 271 void wil_link_on(struct wil6210_priv *wil) 272 { 273 struct net_device *ndev = wil_to_ndev(wil); 274 275 wil_dbg_misc(wil, "%s()\n", __func__); 276 277 netif_carrier_on(ndev); 278 netif_tx_wake_all_queues(ndev); 279 } 280 281 void wil_link_off(struct wil6210_priv *wil) 282 { 283 struct net_device *ndev = wil_to_ndev(wil); 284 285 wil_dbg_misc(wil, "%s()\n", __func__); 286 287 netif_tx_stop_all_queues(ndev); 288 netif_carrier_off(ndev); 289 } 290 291 static int __wil_up(struct wil6210_priv *wil) 292 { 293 struct net_device *ndev = wil_to_ndev(wil); 294 struct wireless_dev *wdev = wil->wdev; 295 struct ieee80211_channel *channel = wdev->preset_chandef.chan; 296 int rc; 297 int bi; 298 u16 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype); 299 300 rc = wil_reset(wil); 301 if (rc) 302 return rc; 303 304 /* FIXME Firmware works now in PBSS mode(ToDS=0, FromDS=0) */ 305 wmi_nettype = wil_iftype_nl2wmi(NL80211_IFTYPE_ADHOC); 306 switch (wdev->iftype) { 307 case NL80211_IFTYPE_STATION: 308 wil_dbg_misc(wil, "type: STATION\n"); 309 bi = 0; 310 ndev->type = ARPHRD_ETHER; 311 break; 312 case NL80211_IFTYPE_AP: 313 wil_dbg_misc(wil, "type: AP\n"); 314 bi = 100; 315 ndev->type = ARPHRD_ETHER; 316 break; 317 case NL80211_IFTYPE_P2P_CLIENT: 318 wil_dbg_misc(wil, "type: P2P_CLIENT\n"); 319 bi = 0; 320 ndev->type = ARPHRD_ETHER; 321 break; 322 case NL80211_IFTYPE_P2P_GO: 323 wil_dbg_misc(wil, "type: P2P_GO\n"); 324 bi = 100; 325 ndev->type = ARPHRD_ETHER; 326 break; 327 case NL80211_IFTYPE_MONITOR: 328 wil_dbg_misc(wil, "type: Monitor\n"); 329 bi = 0; 330 ndev->type = ARPHRD_IEEE80211_RADIOTAP; 331 /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_RADIOTAP ? */ 332 break; 333 default: 334 return -EOPNOTSUPP; 335 } 336 337 /* Apply profile in the following order: */ 338 /* SSID and channel for the AP */ 339 switch (wdev->iftype) { 340 case NL80211_IFTYPE_AP: 341 case NL80211_IFTYPE_P2P_GO: 342 if (wdev->ssid_len == 0) { 343 wil_err(wil, "SSID not set\n"); 344 return -EINVAL; 345 } 346 rc = wmi_set_ssid(wil, wdev->ssid_len, wdev->ssid); 347 if (rc) 348 return rc; 349 break; 350 default: 351 break; 352 } 353 354 /* MAC address - pre-requisite for other commands */ 355 wmi_set_mac_address(wil, ndev->dev_addr); 356 357 /* Set up beaconing if required. */ 358 if (bi > 0) { 359 rc = wmi_pcp_start(wil, bi, wmi_nettype, 360 (channel ? channel->hw_value : 0)); 361 if (rc) 362 return rc; 363 } 364 365 /* Rx VRING. After MAC and beacon */ 366 wil_rx_init(wil); 367 368 return 0; 369 } 370 371 int wil_up(struct wil6210_priv *wil) 372 { 373 int rc; 374 375 mutex_lock(&wil->mutex); 376 rc = __wil_up(wil); 377 mutex_unlock(&wil->mutex); 378 379 return rc; 380 } 381 382 static int __wil_down(struct wil6210_priv *wil) 383 { 384 if (wil->scan_request) { 385 cfg80211_scan_done(wil->scan_request, true); 386 wil->scan_request = NULL; 387 } 388 389 wil6210_disconnect(wil, NULL); 390 wil_rx_fini(wil); 391 392 return 0; 393 } 394 395 int wil_down(struct wil6210_priv *wil) 396 { 397 int rc; 398 399 mutex_lock(&wil->mutex); 400 rc = __wil_down(wil); 401 mutex_unlock(&wil->mutex); 402 403 return rc; 404 } 405