~ubuntu-branches/ubuntu/natty/linux-backports-modules-2.6.38/natty-security

« back to all changes in this revision

Viewing changes to updates/cw-3.0.0/drivers/net/wireless/wl1251/event.c

  • Committer: Package Import Robot
  • Author(s): Herton Ronaldo Krzesinski, Herton Ronaldo Krzesinski, Tim Gardner
  • Date: 2011-09-27 18:53:53 UTC
  • Revision ID: package-import@ubuntu.com-20110927185353-kv2b0it2l42t74bh
Tags: 2.6.38-12.8
[ Herton Ronaldo Krzesinski ]

* Bump ABI - Natty ABI 12

[ Tim Gardner ]

* Added compat wireless 3.0.0
  - LP: #819484

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of wl1251
 
3
 *
 
4
 * Copyright (c) 1998-2007 Texas Instruments Incorporated
 
5
 * Copyright (C) 2008 Nokia Corporation
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU General Public License
 
9
 * version 2 as published by the Free Software Foundation.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful, but
 
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 
19
 * 02110-1301 USA
 
20
 *
 
21
 */
 
22
 
 
23
#include "wl1251.h"
 
24
#include "reg.h"
 
25
#include "io.h"
 
26
#include "event.h"
 
27
#include "ps.h"
 
28
 
 
29
static int wl1251_event_scan_complete(struct wl1251 *wl,
 
30
                                      struct event_mailbox *mbox)
 
31
{
 
32
        wl1251_debug(DEBUG_EVENT, "status: 0x%x, channels: %d",
 
33
                     mbox->scheduled_scan_status,
 
34
                     mbox->scheduled_scan_channels);
 
35
 
 
36
        if (wl->scanning) {
 
37
                ieee80211_scan_completed(wl->hw, false);
 
38
                wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan completed");
 
39
                wl->scanning = false;
 
40
        }
 
41
 
 
42
        return 0;
 
43
}
 
44
 
 
45
static void wl1251_event_mbox_dump(struct event_mailbox *mbox)
 
46
{
 
47
        wl1251_debug(DEBUG_EVENT, "MBOX DUMP:");
 
48
        wl1251_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector);
 
49
        wl1251_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask);
 
50
}
 
51
 
 
52
static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox)
 
53
{
 
54
        int ret;
 
55
        u32 vector;
 
56
 
 
57
        wl1251_event_mbox_dump(mbox);
 
58
 
 
59
        vector = mbox->events_vector & ~(mbox->events_mask);
 
60
        wl1251_debug(DEBUG_EVENT, "vector: 0x%x", vector);
 
61
 
 
62
        if (vector & SCAN_COMPLETE_EVENT_ID) {
 
63
                ret = wl1251_event_scan_complete(wl, mbox);
 
64
                if (ret < 0)
 
65
                        return ret;
 
66
        }
 
67
 
 
68
        if (vector & BSS_LOSE_EVENT_ID) {
 
69
                wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
 
70
 
 
71
                if (wl->psm_requested &&
 
72
                    wl->station_mode != STATION_ACTIVE_MODE) {
 
73
                        ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
 
74
                        if (ret < 0)
 
75
                                return ret;
 
76
                }
 
77
        }
 
78
 
 
79
        if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID &&
 
80
            wl->station_mode != STATION_ACTIVE_MODE) {
 
81
                wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT");
 
82
 
 
83
                /* indicate to the stack, that beacons have been lost */
 
84
                ieee80211_beacon_loss(wl->vif);
 
85
        }
 
86
 
 
87
        if (vector & REGAINED_BSS_EVENT_ID) {
 
88
                if (wl->psm_requested) {
 
89
                        ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
 
90
                        if (ret < 0)
 
91
                                return ret;
 
92
                }
 
93
        }
 
94
 
 
95
        if (wl->vif && wl->rssi_thold) {
 
96
                if (vector & ROAMING_TRIGGER_LOW_RSSI_EVENT_ID) {
 
97
                        wl1251_debug(DEBUG_EVENT,
 
98
                                     "ROAMING_TRIGGER_LOW_RSSI_EVENT");
 
99
                        ieee80211_cqm_rssi_notify(wl->vif,
 
100
                                NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
 
101
                                GFP_KERNEL);
 
102
                }
 
103
 
 
104
                if (vector & ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID) {
 
105
                        wl1251_debug(DEBUG_EVENT,
 
106
                                     "ROAMING_TRIGGER_REGAINED_RSSI_EVENT");
 
107
                        ieee80211_cqm_rssi_notify(wl->vif,
 
108
                                NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
 
109
                                GFP_KERNEL);
 
110
                }
 
111
        }
 
112
 
 
113
        return 0;
 
114
}
 
115
 
 
116
/*
 
117
 * Poll the mailbox event field until any of the bits in the mask is set or a
 
118
 * timeout occurs (WL1251_EVENT_TIMEOUT in msecs)
 
119
 */
 
120
int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms)
 
121
{
 
122
        u32 events_vector, event;
 
123
        unsigned long timeout;
 
124
 
 
125
        timeout = jiffies + msecs_to_jiffies(timeout_ms);
 
126
 
 
127
        do {
 
128
                if (time_after(jiffies, timeout))
 
129
                        return -ETIMEDOUT;
 
130
 
 
131
                msleep(1);
 
132
 
 
133
                /* read from both event fields */
 
134
                wl1251_mem_read(wl, wl->mbox_ptr[0], &events_vector,
 
135
                                sizeof(events_vector));
 
136
                event = events_vector & mask;
 
137
                wl1251_mem_read(wl, wl->mbox_ptr[1], &events_vector,
 
138
                                sizeof(events_vector));
 
139
                event |= events_vector & mask;
 
140
        } while (!event);
 
141
 
 
142
        return 0;
 
143
}
 
144
 
 
145
int wl1251_event_unmask(struct wl1251 *wl)
 
146
{
 
147
        int ret;
 
148
 
 
149
        ret = wl1251_acx_event_mbox_mask(wl, ~(wl->event_mask));
 
150
        if (ret < 0)
 
151
                return ret;
 
152
 
 
153
        return 0;
 
154
}
 
155
 
 
156
void wl1251_event_mbox_config(struct wl1251 *wl)
 
157
{
 
158
        wl->mbox_ptr[0] = wl1251_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
 
159
        wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
 
160
 
 
161
        wl1251_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
 
162
                     wl->mbox_ptr[0], wl->mbox_ptr[1]);
 
163
}
 
164
 
 
165
int wl1251_event_handle(struct wl1251 *wl, u8 mbox_num)
 
166
{
 
167
        struct event_mailbox mbox;
 
168
        int ret;
 
169
 
 
170
        wl1251_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num);
 
171
 
 
172
        if (mbox_num > 1)
 
173
                return -EINVAL;
 
174
 
 
175
        /* first we read the mbox descriptor */
 
176
        wl1251_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox,
 
177
                            sizeof(struct event_mailbox));
 
178
 
 
179
        /* process the descriptor */
 
180
        ret = wl1251_event_process(wl, &mbox);
 
181
        if (ret < 0)
 
182
                return ret;
 
183
 
 
184
        /* then we let the firmware know it can go on...*/
 
185
        wl1251_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
 
186
 
 
187
        return 0;
 
188
}