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