]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/wireless/libertas/assoc.c
libertas: convert GET_LOG to a direct command
[linux-2.6-omap-h63xx.git] / drivers / net / wireless / libertas / assoc.c
index a4b9756ebb7f6c7a8dfd75e95b64f5f7b8fba056..95d98203eb4ebdccbf9936b7a29a745a8715161e 100644 (file)
 #include "cmd.h"
 
 
-static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
-static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const u8 bssid_any[ETH_ALEN]  __attribute__ ((aligned (2))) =
+       { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+static const u8 bssid_off[ETH_ALEN]  __attribute__ ((aligned (2))) =
+       { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
 
 static int assoc_helper_essid(struct lbs_private *priv,
@@ -36,7 +38,7 @@ static int assoc_helper_essid(struct lbs_private *priv,
                      escape_essid(assoc_req->ssid, assoc_req->ssid_len));
        if (assoc_req->mode == IW_MODE_INFRA) {
                lbs_send_specific_ssid_scan(priv, assoc_req->ssid,
-                       assoc_req->ssid_len, 0);
+                       assoc_req->ssid_len);
 
                bss = lbs_find_ssid_in_list(priv, assoc_req->ssid,
                                assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel);
@@ -51,7 +53,7 @@ static int assoc_helper_essid(struct lbs_private *priv,
                 *   scan data will cause us to join a non-existant adhoc network
                 */
                lbs_send_specific_ssid_scan(priv, assoc_req->ssid,
-                       assoc_req->ssid_len, 1);
+                       assoc_req->ssid_len);
 
                /* Search for the requested SSID in the scan table */
                bss = lbs_find_ssid_in_list(priv, assoc_req->ssid,
@@ -163,32 +165,22 @@ done:
 }
 
 
-static int update_channel(struct lbs_private *priv)
+int lbs_update_channel(struct lbs_private *priv)
 {
        int ret;
 
-       /* the channel in f/w could be out of sync, get the current channel */
+       /* the channel in f/w could be out of sync; get the current channel */
        lbs_deb_enter(LBS_DEB_ASSOC);
 
        ret = lbs_get_channel(priv);
-       if (ret > 0)
-               priv->curbssparams.channel = (u8) ret;
-
+       if (ret > 0) {
+               priv->curbssparams.channel = ret;
+               ret = 0;
+       }
        lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
        return ret;
 }
 
-void lbs_sync_channel(struct work_struct *work)
-{
-       struct lbs_private *priv = container_of(work, struct lbs_private,
-               sync_channel);
-
-       lbs_deb_enter(LBS_DEB_ASSOC);
-       if (update_channel(priv) != 0)
-               lbs_pr_info("Channel synchronization failed.");
-       lbs_deb_leave(LBS_DEB_ASSOC);
-}
-
 static int assoc_helper_channel(struct lbs_private *priv,
                                 struct assoc_request * assoc_req)
 {
@@ -196,32 +188,42 @@ static int assoc_helper_channel(struct lbs_private *priv,
 
        lbs_deb_enter(LBS_DEB_ASSOC);
 
-       ret = update_channel(priv);
-       if (ret < 0) {
-               lbs_deb_assoc("ASSOC: channel: error getting channel.");
+       ret = lbs_update_channel(priv);
+       if (ret) {
+               lbs_deb_assoc("ASSOC: channel: error getting channel.\n");
+               goto done;
        }
 
        if (assoc_req->channel == priv->curbssparams.channel)
                goto done;
 
+       if (priv->mesh_dev) {
+               /* Change mesh channel first; 21.p21 firmware won't let
+                  you change channel otherwise (even though it'll return
+                  an error to this */
+               lbs_mesh_config(priv, 0, assoc_req->channel);
+       }
+
        lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
-              priv->curbssparams.channel, assoc_req->channel);
+                     priv->curbssparams.channel, assoc_req->channel);
 
        ret = lbs_set_channel(priv, assoc_req->channel);
        if (ret < 0)
-               lbs_deb_assoc("ASSOC: channel: error setting channel.");
+               lbs_deb_assoc("ASSOC: channel: error setting channel.\n");
 
        /* FIXME: shouldn't need to grab the channel _again_ after setting
         * it since the firmware is supposed to return the new channel, but
         * whatever... */
-       ret = update_channel(priv);
-       if (ret < 0)
-               lbs_deb_assoc("ASSOC: channel: error getting channel.");
+       ret = lbs_update_channel(priv);
+       if (ret) {
+               lbs_deb_assoc("ASSOC: channel: error getting channel.\n");
+               goto done;
+       }
 
        if (assoc_req->channel != priv->curbssparams.channel) {
                lbs_deb_assoc("ASSOC: channel: failed to update channel to %d\n",
                              assoc_req->channel);
-               goto done;
+               goto restore_mesh;
        }
 
        if (   assoc_req->secinfo.wep_enabled
@@ -234,16 +236,20 @@ static int assoc_helper_channel(struct lbs_private *priv,
        }
 
        /* Must restart/rejoin adhoc networks after channel change */
-       set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
+       set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
 
-done:
+ restore_mesh:
+       if (priv->mesh_dev)
+               lbs_mesh_config(priv, 1, priv->curbssparams.channel);
+
+ done:
        lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
        return ret;
 }
 
 
 static int assoc_helper_wep_keys(struct lbs_private *priv,
-                                 struct assoc_request * assoc_req)
+                                struct assoc_request *assoc_req)
 {
        int i;
        int ret = 0;
@@ -251,41 +257,29 @@ static int assoc_helper_wep_keys(struct lbs_private *priv,
        lbs_deb_enter(LBS_DEB_ASSOC);
 
        /* Set or remove WEP keys */
-       if (   assoc_req->wep_keys[0].len
-           || assoc_req->wep_keys[1].len
-           || assoc_req->wep_keys[2].len
-           || assoc_req->wep_keys[3].len) {
-               ret = lbs_prepare_and_send_command(priv,
-                                           CMD_802_11_SET_WEP,
-                                           CMD_ACT_ADD,
-                                           CMD_OPTION_WAITFORRSP,
-                                           0, assoc_req);
-       } else {
-               ret = lbs_prepare_and_send_command(priv,
-                                           CMD_802_11_SET_WEP,
-                                           CMD_ACT_REMOVE,
-                                           CMD_OPTION_WAITFORRSP,
-                                           0, NULL);
-       }
+       if (assoc_req->wep_keys[0].len || assoc_req->wep_keys[1].len ||
+           assoc_req->wep_keys[2].len || assoc_req->wep_keys[3].len)
+               ret = lbs_cmd_802_11_set_wep(priv, CMD_ACT_ADD, assoc_req);
+       else
+               ret = lbs_cmd_802_11_set_wep(priv, CMD_ACT_REMOVE, assoc_req);
 
        if (ret)
                goto out;
 
        /* enable/disable the MAC's WEP packet filter */
        if (assoc_req->secinfo.wep_enabled)
-               priv->currentpacketfilter |= CMD_ACT_MAC_WEP_ENABLE;
+               priv->mac_control |= CMD_ACT_MAC_WEP_ENABLE;
        else
-               priv->currentpacketfilter &= ~CMD_ACT_MAC_WEP_ENABLE;
-       ret = lbs_set_mac_packet_filter(priv);
-       if (ret)
-               goto out;
+               priv->mac_control &= ~CMD_ACT_MAC_WEP_ENABLE;
+
+       lbs_set_mac_control(priv);
 
        mutex_lock(&priv->lock);
 
        /* Copy WEP keys into priv wep key fields */
        for (i = 0; i < 4; i++) {
                memcpy(&priv->wep_keys[i], &assoc_req->wep_keys[i],
-                       sizeof(struct enc_key));
+                      sizeof(struct enc_key));
        }
        priv->wep_tx_keyidx = assoc_req->wep_tx_keyidx;
 
@@ -300,17 +294,15 @@ static int assoc_helper_secinfo(struct lbs_private *priv,
                                 struct assoc_request * assoc_req)
 {
        int ret = 0;
-       u32 do_wpa;
-       u32 rsn = 0;
+       uint16_t do_wpa;
+       uint16_t rsn = 0;
 
        lbs_deb_enter(LBS_DEB_ASSOC);
 
        memcpy(&priv->secinfo, &assoc_req->secinfo,
                sizeof(struct lbs_802_11_security));
 
-       ret = lbs_set_mac_packet_filter(priv);
-       if (ret)
-               goto out;
+       lbs_set_mac_control(priv);
 
        /* If RSN is already enabled, don't try to enable it again, since
         * ENABLE_RSN resets internal state machines and will clobber the
@@ -318,28 +310,19 @@ static int assoc_helper_secinfo(struct lbs_private *priv,
         */
 
        /* Get RSN enabled/disabled */
-       ret = lbs_prepare_and_send_command(priv,
-                                   CMD_802_11_ENABLE_RSN,
-                                   CMD_ACT_GET,
-                                   CMD_OPTION_WAITFORRSP,
-                                   0, &rsn);
+       ret = lbs_cmd_802_11_enable_rsn(priv, CMD_ACT_GET, &rsn);
        if (ret) {
-               lbs_deb_assoc("Failed to get RSN status: %d", ret);
+               lbs_deb_assoc("Failed to get RSN status: %d\n", ret);
                goto out;
        }
 
        /* Don't re-enable RSN if it's already enabled */
-       do_wpa = (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled);
+       do_wpa = assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled;
        if (do_wpa == rsn)
                goto out;
 
        /* Set RSN enabled/disabled */
-       rsn = do_wpa;
-       ret = lbs_prepare_and_send_command(priv,
-                                   CMD_802_11_ENABLE_RSN,
-                                   CMD_ACT_SET,
-                                   CMD_OPTION_WAITFORRSP,
-                                   0, &rsn);
+       ret = lbs_cmd_802_11_enable_rsn(priv, CMD_ACT_SET, &do_wpa);
 
 out:
        lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
@@ -362,11 +345,7 @@ static int assoc_helper_wpa_keys(struct lbs_private *priv,
 
        if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
                clear_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
-               ret = lbs_prepare_and_send_command(priv,
-                                       CMD_802_11_KEY_MATERIAL,
-                                       CMD_ACT_SET,
-                                       CMD_OPTION_WAITFORRSP,
-                                       0, assoc_req);
+               ret = lbs_cmd_802_11_key_material(priv, CMD_ACT_SET, assoc_req);
                assoc_req->flags = flags;
        }
 
@@ -376,11 +355,7 @@ static int assoc_helper_wpa_keys(struct lbs_private *priv,
        if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
                clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
 
-               ret = lbs_prepare_and_send_command(priv,
-                                       CMD_802_11_KEY_MATERIAL,
-                                       CMD_ACT_SET,
-                                       CMD_OPTION_WAITFORRSP,
-                                       0, assoc_req);
+               ret = lbs_cmd_802_11_key_material(priv, CMD_ACT_SET, assoc_req);
                assoc_req->flags = flags;
        }
 
@@ -415,11 +390,10 @@ static int should_deauth_infrastructure(struct lbs_private *priv,
 {
        int ret = 0;
 
-       lbs_deb_enter(LBS_DEB_ASSOC);
-
        if (priv->connect_status != LBS_CONNECTED)
                return 0;
 
+       lbs_deb_enter(LBS_DEB_ASSOC);
        if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
                lbs_deb_assoc("Deauthenticating due to new SSID\n");
                ret = 1;
@@ -458,7 +432,7 @@ static int should_deauth_infrastructure(struct lbs_private *priv,
 
 out:
        lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
-       return 0;
+       return ret;
 }
 
 
@@ -645,17 +619,11 @@ void lbs_association_worker(struct work_struct *work)
                }
 
                if (success) {
-                       lbs_deb_assoc("ASSOC: associated to '%s', %s\n",
-                               escape_essid(priv->curbssparams.ssid,
-                                            priv->curbssparams.ssid_len),
+                       lbs_deb_assoc("associated to %s\n",
                                print_mac(mac, priv->curbssparams.bssid));
                        lbs_prepare_and_send_command(priv,
                                CMD_802_11_RSSI,
                                0, CMD_OPTION_WAITFORRSP, 0, NULL);
-
-                       lbs_prepare_and_send_command(priv,
-                               CMD_802_11_GET_LOG,
-                               0, CMD_OPTION_WAITFORRSP, 0, NULL);
                } else {
                        ret = -1;
                }