]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/net/wireless/wl12xx/wl1271_event.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke...
[mv-sheeva.git] / drivers / net / wireless / wl12xx / wl1271_event.c
index d13fdd99c85c515eea99dd128f8e8b8ecd606a31..7468ef10194bef9a1974f84b09036e3954a831ed 100644 (file)
@@ -24,6 +24,7 @@
 #include "wl1271.h"
 #include "wl1271_reg.h"
 #include "wl1271_spi.h"
+#include "wl1271_io.h"
 #include "wl1271_event.h"
 #include "wl1271_ps.h"
 #include "wl12xx_80211.h"
@@ -35,7 +36,7 @@ static int wl1271_event_scan_complete(struct wl1271 *wl,
        wl1271_debug(DEBUG_EVENT, "status: 0x%x",
                     mbox->scheduled_scan_status);
 
-       if (wl->scanning) {
+       if (test_bit(WL1271_FLAG_SCANNING, &wl->flags)) {
                if (wl->scan.state == WL1271_SCAN_BAND_DUAL) {
                        wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
                                                NULL, size);
@@ -43,7 +44,7 @@ static int wl1271_event_scan_complete(struct wl1271 *wl,
                         * to the wl1271_cmd_scan function that we are not
                         * scanning as it checks that.
                         */
-                       wl->scanning = false;
+                       clear_bit(WL1271_FLAG_SCANNING, &wl->flags);
                        wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len,
                                                wl->scan.active,
                                                wl->scan.high_prio,
@@ -62,7 +63,7 @@ static int wl1271_event_scan_complete(struct wl1271 *wl,
                        mutex_unlock(&wl->mutex);
                        ieee80211_scan_completed(wl->hw, false);
                        mutex_lock(&wl->mutex);
-                       wl->scanning = false;
+                       clear_bit(WL1271_FLAG_SCANNING, &wl->flags);
                }
        }
        return 0;
@@ -78,25 +79,61 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
 
        switch (mbox->ps_status) {
        case EVENT_ENTER_POWER_SAVE_FAIL:
-               if (!wl->psm) {
+               wl1271_debug(DEBUG_PSM, "PSM entry failed");
+
+               if (!test_bit(WL1271_FLAG_PSM, &wl->flags)) {
+                       /* remain in active mode */
                        wl->psm_entry_retry = 0;
                        break;
                }
 
                if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) {
                        wl->psm_entry_retry++;
-                       ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
+                       ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
+                                                true);
                } else {
                        wl1271_error("PSM entry failed, giving up.\n");
+                       /* FIXME: this may need to be reconsidered. for now it
+                          is not possible to indicate to the mac80211
+                          afterwards that PSM entry failed. To maximize
+                          functionality (receiving data and remaining
+                          associated) make sure that we are in sync with the
+                          AP in regard of PSM mode. */
+                       ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
+                                                false);
                        wl->psm_entry_retry = 0;
-                       *beacon_loss = true;
                }
                break;
        case EVENT_ENTER_POWER_SAVE_SUCCESS:
                wl->psm_entry_retry = 0;
+
+               /* enable beacon filtering */
+               ret = wl1271_acx_beacon_filter_opt(wl, true);
+               if (ret < 0)
+                       break;
+
+               /* enable beacon early termination */
+               ret = wl1271_acx_bet_enable(wl, true);
+               if (ret < 0)
+                       break;
+
+               /* go to extremely low power mode */
+               wl1271_ps_elp_sleep(wl);
+               if (ret < 0)
+                       break;
                break;
        case EVENT_EXIT_POWER_SAVE_FAIL:
-               wl1271_info("PSM exit failed");
+               wl1271_debug(DEBUG_PSM, "PSM exit failed");
+
+               if (test_bit(WL1271_FLAG_PSM, &wl->flags)) {
+                       wl->psm_entry_retry = 0;
+                       break;
+               }
+
+               /* make sure the firmware goes to active mode - the frame to
+                  be sent next will indicate to the AP, that we are active. */
+               ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
+                                        false);
                break;
        case EVENT_EXIT_POWER_SAVE_SUCCESS:
        default:
@@ -136,7 +173,8 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
         * filtering) is enabled. Without PSM, the stack will receive all
         * beacons and can detect beacon loss by itself.
         */
-       if (vector & BSS_LOSE_EVENT_ID && wl->psm) {
+       if (vector & BSS_LOSE_EVENT_ID &&
+           test_bit(WL1271_FLAG_PSM, &wl->flags)) {
                wl1271_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
 
                /* indicate to the stack, that beacons have been lost */
@@ -150,7 +188,7 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
                        return ret;
        }
 
-       if (beacon_loss) {
+       if (wl->vif && beacon_loss) {
                /* Obviously, it's dangerous to release the mutex while
                   we are holding many of the variables in the wl struct.
                   That's why it's done last in the function, and care must
@@ -177,14 +215,14 @@ int wl1271_event_unmask(struct wl1271 *wl)
 
 void wl1271_event_mbox_config(struct wl1271 *wl)
 {
-       wl->mbox_ptr[0] = wl1271_spi_read32(wl, REG_EVENT_MAILBOX_PTR);
+       wl->mbox_ptr[0] = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR);
        wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
 
        wl1271_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
                     wl->mbox_ptr[0], wl->mbox_ptr[1]);
 }
 
-int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num, bool do_ack)
+int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num)
 {
        struct event_mailbox mbox;
        int ret;
@@ -195,8 +233,8 @@ int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num, bool do_ack)
                return -EINVAL;
 
        /* first we read the mbox descriptor */
-       wl1271_spi_read(wl, wl->mbox_ptr[mbox_num], &mbox,
-                       sizeof(struct event_mailbox), false);
+       wl1271_read(wl, wl->mbox_ptr[mbox_num], &mbox,
+                   sizeof(struct event_mailbox), false);
 
        /* process the descriptor */
        ret = wl1271_event_process(wl, &mbox);
@@ -204,9 +242,7 @@ int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num, bool do_ack)
                return ret;
 
        /* then we let the firmware know it can go on...*/
-       if (do_ack)
-               wl1271_spi_write32(wl, ACX_REG_INTERRUPT_TRIG,
-                                  INTR_TRIG_EVENT_ACK);
+       wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
 
        return 0;
 }