Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / ath / wil6210 / main.c
index 95fcd361322b06149ff0f7b95aa70ba08f6da181..a0478e2f68688ebdcc71f2351e7593efa4f3c12a 100644 (file)
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/sched.h>
-#include <linux/ieee80211.h>
-#include <linux/wireless.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/if_arp.h>
 
@@ -64,7 +58,7 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid)
        struct net_device *ndev = wil_to_ndev(wil);
        struct wireless_dev *wdev = wil->wdev;
 
-       wil_dbg(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "%s()\n", __func__);
 
        wil_link_off(wil);
        clear_bit(wil_status_fwconnected, &wil->status);
@@ -80,11 +74,13 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid)
                                        GFP_KERNEL);
                break;
        default:
-               ;
+               break;
        }
 
        for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++)
                wil_vring_fini_tx(wil, i);
+
+       clear_bit(wil_status_dontscan, &wil->status);
 }
 
 static void wil_disconnect_worker(struct work_struct *work)
@@ -99,7 +95,7 @@ static void wil_connect_timer_fn(ulong x)
 {
        struct wil6210_priv *wil = (void *)x;
 
-       wil_dbg(wil, "Connect timeout\n");
+       wil_dbg_misc(wil, "Connect timeout\n");
 
        /* reschedule to thread context - disconnect won't
         * run from atomic context
@@ -107,9 +103,29 @@ static void wil_connect_timer_fn(ulong x)
        schedule_work(&wil->disconnect_worker);
 }
 
+static void wil_connect_worker(struct work_struct *work)
+{
+       int rc;
+       struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
+                                               connect_worker);
+       int cid = wil->pending_connect_cid;
+
+       if (cid < 0) {
+               wil_err(wil, "No connection pending\n");
+               return;
+       }
+
+       wil_dbg_wmi(wil, "Configure for connection CID %d\n", cid);
+
+       rc = wil_vring_init_tx(wil, 0, WIL6210_TX_RING_SIZE, cid, 0);
+       wil->pending_connect_cid = -1;
+       if (rc == 0)
+               wil_link_on(wil);
+}
+
 int wil_priv_init(struct wil6210_priv *wil)
 {
-       wil_dbg(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "%s()\n", __func__);
 
        mutex_init(&wil->mutex);
        mutex_init(&wil->wmi_mutex);
@@ -119,7 +135,7 @@ int wil_priv_init(struct wil6210_priv *wil)
        wil->pending_connect_cid = -1;
        setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil);
 
-       INIT_WORK(&wil->wmi_connect_worker, wmi_connect_worker);
+       INIT_WORK(&wil->connect_worker, wil_connect_worker);
        INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker);
        INIT_WORK(&wil->wmi_event_worker, wmi_event_worker);
 
@@ -136,12 +152,6 @@ int wil_priv_init(struct wil6210_priv *wil)
                return -EAGAIN;
        }
 
-       /* make shadow copy of registers that should not change on run time */
-       wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
-                            sizeof(struct wil6210_mbox_ctl));
-       wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx);
-       wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
-
        return 0;
 }
 
@@ -162,7 +172,7 @@ void wil_priv_deinit(struct wil6210_priv *wil)
 
 static void wil_target_reset(struct wil6210_priv *wil)
 {
-       wil_dbg(wil, "Resetting...\n");
+       wil_dbg_misc(wil, "Resetting...\n");
 
        /* register write */
 #define W(a, v) iowrite32(v, wil->csr + HOSTADDR(a))
@@ -178,15 +188,11 @@ static void wil_target_reset(struct wil6210_priv *wil)
        W(RGF_USER_MAC_CPU_0,  BIT(1)); /* mac_cpu_man_rst */
        W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */
 
-       msleep(100);
-
        W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000);
        W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F);
        W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000170);
        W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00);
 
-       msleep(100);
-
        W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0);
        W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0);
        W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0);
@@ -196,13 +202,7 @@ static void wil_target_reset(struct wil6210_priv *wil)
        W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080);
        W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
 
-       msleep(2000);
-
-       W(RGF_USER_USER_CPU_0, BIT(0)); /* user_cpu_man_de_rst */
-
-       msleep(2000);
-
-       wil_dbg(wil, "Reset completed\n");
+       wil_dbg_misc(wil, "Reset completed\n");
 
 #undef W
 #undef S
@@ -225,8 +225,8 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil)
                wil_err(wil, "Firmware not ready\n");
                return -ETIME;
        } else {
-               wil_dbg(wil, "FW ready after %d ms\n",
-                       jiffies_to_msecs(to-left));
+               wil_dbg_misc(wil, "FW ready after %d ms\n",
+                            jiffies_to_msecs(to-left));
        }
        return 0;
 }
@@ -243,13 +243,13 @@ int wil_reset(struct wil6210_priv *wil)
        cancel_work_sync(&wil->disconnect_worker);
        wil6210_disconnect(wil, NULL);
 
+       wil6210_disable_irq(wil);
+       wil->status = 0;
+
        wmi_event_flush(wil);
 
-       flush_workqueue(wil->wmi_wq);
        flush_workqueue(wil->wmi_wq_conn);
-
-       wil6210_disable_irq(wil);
-       wil->status = 0;
+       flush_workqueue(wil->wmi_wq);
 
        /* TODO: put MAC in reset */
        wil_target_reset(wil);
@@ -258,12 +258,6 @@ int wil_reset(struct wil6210_priv *wil)
        wil->pending_connect_cid = -1;
        INIT_COMPLETION(wil->wmi_ready);
 
-       /* make shadow copy of registers that should not change on run time */
-       wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
-                            sizeof(struct wil6210_mbox_ctl));
-       wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx);
-       wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
-
        /* TODO: release MAC reset */
        wil6210_enable_irq(wil);
 
@@ -278,7 +272,7 @@ void wil_link_on(struct wil6210_priv *wil)
 {
        struct net_device *ndev = wil_to_ndev(wil);
 
-       wil_dbg(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "%s()\n", __func__);
 
        netif_carrier_on(ndev);
        netif_tx_wake_all_queues(ndev);
@@ -288,7 +282,7 @@ void wil_link_off(struct wil6210_priv *wil)
 {
        struct net_device *ndev = wil_to_ndev(wil);
 
-       wil_dbg(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "%s()\n", __func__);
 
        netif_tx_stop_all_queues(ndev);
        netif_carrier_off(ndev);
@@ -311,27 +305,27 @@ static int __wil_up(struct wil6210_priv *wil)
        wmi_nettype = wil_iftype_nl2wmi(NL80211_IFTYPE_ADHOC);
        switch (wdev->iftype) {
        case NL80211_IFTYPE_STATION:
-               wil_dbg(wil, "type: STATION\n");
+               wil_dbg_misc(wil, "type: STATION\n");
                bi = 0;
                ndev->type = ARPHRD_ETHER;
                break;
        case NL80211_IFTYPE_AP:
-               wil_dbg(wil, "type: AP\n");
+               wil_dbg_misc(wil, "type: AP\n");
                bi = 100;
                ndev->type = ARPHRD_ETHER;
                break;
        case NL80211_IFTYPE_P2P_CLIENT:
-               wil_dbg(wil, "type: P2P_CLIENT\n");
+               wil_dbg_misc(wil, "type: P2P_CLIENT\n");
                bi = 0;
                ndev->type = ARPHRD_ETHER;
                break;
        case NL80211_IFTYPE_P2P_GO:
-               wil_dbg(wil, "type: P2P_GO\n");
+               wil_dbg_misc(wil, "type: P2P_GO\n");
                bi = 100;
                ndev->type = ARPHRD_ETHER;
                break;
        case NL80211_IFTYPE_MONITOR:
-               wil_dbg(wil, "type: Monitor\n");
+               wil_dbg_misc(wil, "type: Monitor\n");
                bi = 0;
                ndev->type = ARPHRD_IEEE80211_RADIOTAP;
                /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_RADIOTAP ? */
@@ -349,21 +343,24 @@ static int __wil_up(struct wil6210_priv *wil)
                        wil_err(wil, "SSID not set\n");
                        return -EINVAL;
                }
-               wmi_set_ssid(wil, wdev->ssid_len, wdev->ssid);
-               if (channel)
-                       wmi_set_channel(wil, channel->hw_value);
+               rc = wmi_set_ssid(wil, wdev->ssid_len, wdev->ssid);
+               if (rc)
+                       return rc;
                break;
        default:
-               ;
+               break;
        }
 
        /* MAC address - pre-requisite for other commands */
        wmi_set_mac_address(wil, ndev->dev_addr);
 
        /* Set up beaconing if required. */
-       rc = wmi_set_bcon(wil, bi, wmi_nettype);
-       if (rc)
-               return rc;
+       if (bi > 0) {
+               rc = wmi_pcp_start(wil, bi, wmi_nettype,
+                                  (channel ? channel->hw_value : 0));
+               if (rc)
+                       return rc;
+       }
 
        /* Rx VRING. After MAC and beacon */
        wil_rx_init(wil);