~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/net/wireless/wl12xx/cmd.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
#include "wl12xx_80211.h"
37
37
#include "cmd.h"
38
38
#include "event.h"
 
39
#include "tx.h"
39
40
 
40
41
#define WL1271_CMD_FAST_POLL_COUNT       50
41
42
 
62
63
        cmd->status = 0;
63
64
 
64
65
        WARN_ON(len % 4 != 0);
 
66
        WARN_ON(test_bit(WL1271_FLAG_IN_ELP, &wl->flags));
65
67
 
66
68
        wl1271_write(wl, wl->cmd_box_addr, buf, len, false);
67
69
 
74
76
                if (time_after(jiffies, timeout)) {
75
77
                        wl1271_error("command complete timeout");
76
78
                        ret = -ETIMEDOUT;
77
 
                        goto out;
 
79
                        goto fail;
78
80
                }
79
81
 
80
82
                poll_count++;
94
96
        status = le16_to_cpu(cmd->status);
95
97
        if (status != CMD_STATUS_SUCCESS) {
96
98
                wl1271_error("command execute failure %d", status);
97
 
                ieee80211_queue_work(wl->hw, &wl->recovery_work);
98
99
                ret = -EIO;
 
100
                goto fail;
99
101
        }
100
102
 
101
103
        wl1271_write32(wl, ACX_REG_INTERRUPT_ACK,
102
104
                       WL1271_ACX_INTR_CMD_COMPLETE);
 
105
        return 0;
103
106
 
104
 
out:
 
107
fail:
 
108
        WARN_ON(1);
 
109
        ieee80211_queue_work(wl->hw, &wl->recovery_work);
105
110
        return ret;
106
111
}
107
112
 
108
113
int wl1271_cmd_general_parms(struct wl1271 *wl)
109
114
{
110
115
        struct wl1271_general_parms_cmd *gen_parms;
111
 
        struct wl1271_ini_general_params *gp = &wl->nvs->general_params;
112
 
        bool answer = false;
113
 
        int ret;
114
 
 
115
 
        if (!wl->nvs)
116
 
                return -ENODEV;
117
 
 
118
 
        gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
119
 
        if (!gen_parms)
120
 
                return -ENOMEM;
121
 
 
122
 
        gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
123
 
 
124
 
        memcpy(&gen_parms->general_params, gp, sizeof(*gp));
125
 
 
126
 
        if (gp->tx_bip_fem_auto_detect)
127
 
                answer = true;
 
116
        struct wl1271_ini_general_params *gp =
 
117
                &((struct wl1271_nvs_file *)wl->nvs)->general_params;
 
118
        bool answer = false;
 
119
        int ret;
 
120
 
 
121
        if (!wl->nvs)
 
122
                return -ENODEV;
 
123
 
 
124
        gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
 
125
        if (!gen_parms)
 
126
                return -ENOMEM;
 
127
 
 
128
        gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
 
129
 
 
130
        memcpy(&gen_parms->general_params, gp, sizeof(*gp));
 
131
 
 
132
        if (gp->tx_bip_fem_auto_detect)
 
133
                answer = true;
 
134
 
 
135
        /* Override the REF CLK from the NVS with the one from platform data */
 
136
        gen_parms->general_params.ref_clock = wl->ref_clock;
 
137
 
 
138
        ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
 
139
        if (ret < 0) {
 
140
                wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
 
141
                goto out;
 
142
        }
 
143
 
 
144
        gp->tx_bip_fem_manufacturer =
 
145
                gen_parms->general_params.tx_bip_fem_manufacturer;
 
146
 
 
147
        wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
 
148
                     answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
 
149
 
 
150
out:
 
151
        kfree(gen_parms);
 
152
        return ret;
 
153
}
 
154
 
 
155
int wl128x_cmd_general_parms(struct wl1271 *wl)
 
156
{
 
157
        struct wl128x_general_parms_cmd *gen_parms;
 
158
        struct wl128x_ini_general_params *gp =
 
159
                &((struct wl128x_nvs_file *)wl->nvs)->general_params;
 
160
        bool answer = false;
 
161
        int ret;
 
162
 
 
163
        if (!wl->nvs)
 
164
                return -ENODEV;
 
165
 
 
166
        gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
 
167
        if (!gen_parms)
 
168
                return -ENOMEM;
 
169
 
 
170
        gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
 
171
 
 
172
        memcpy(&gen_parms->general_params, gp, sizeof(*gp));
 
173
 
 
174
        if (gp->tx_bip_fem_auto_detect)
 
175
                answer = true;
 
176
 
 
177
        /* Replace REF and TCXO CLKs with the ones from platform data */
 
178
        gen_parms->general_params.ref_clock = wl->ref_clock;
 
179
        gen_parms->general_params.tcxo_ref_clock = wl->tcxo_clock;
128
180
 
129
181
        ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
130
182
        if (ret < 0) {
145
197
 
146
198
int wl1271_cmd_radio_parms(struct wl1271 *wl)
147
199
{
 
200
        struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs;
148
201
        struct wl1271_radio_parms_cmd *radio_parms;
149
 
        struct wl1271_ini_general_params *gp = &wl->nvs->general_params;
 
202
        struct wl1271_ini_general_params *gp = &nvs->general_params;
150
203
        int ret;
151
204
 
152
205
        if (!wl->nvs)
159
212
        radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
160
213
 
161
214
        /* 2.4GHz parameters */
162
 
        memcpy(&radio_parms->static_params_2, &wl->nvs->stat_radio_params_2,
 
215
        memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
163
216
               sizeof(struct wl1271_ini_band_params_2));
164
217
        memcpy(&radio_parms->dyn_params_2,
165
 
               &wl->nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
 
218
               &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
166
219
               sizeof(struct wl1271_ini_fem_params_2));
167
220
 
168
221
        /* 5GHz parameters */
169
222
        memcpy(&radio_parms->static_params_5,
170
 
               &wl->nvs->stat_radio_params_5,
 
223
               &nvs->stat_radio_params_5,
171
224
               sizeof(struct wl1271_ini_band_params_5));
172
225
        memcpy(&radio_parms->dyn_params_5,
173
 
               &wl->nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
 
226
               &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
174
227
               sizeof(struct wl1271_ini_fem_params_5));
175
228
 
176
229
        wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
184
237
        return ret;
185
238
}
186
239
 
 
240
int wl128x_cmd_radio_parms(struct wl1271 *wl)
 
241
{
 
242
        struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
 
243
        struct wl128x_radio_parms_cmd *radio_parms;
 
244
        struct wl128x_ini_general_params *gp = &nvs->general_params;
 
245
        int ret;
 
246
 
 
247
        if (!wl->nvs)
 
248
                return -ENODEV;
 
249
 
 
250
        radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
 
251
        if (!radio_parms)
 
252
                return -ENOMEM;
 
253
 
 
254
        radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
 
255
 
 
256
        /* 2.4GHz parameters */
 
257
        memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
 
258
               sizeof(struct wl128x_ini_band_params_2));
 
259
        memcpy(&radio_parms->dyn_params_2,
 
260
               &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
 
261
               sizeof(struct wl128x_ini_fem_params_2));
 
262
 
 
263
        /* 5GHz parameters */
 
264
        memcpy(&radio_parms->static_params_5,
 
265
               &nvs->stat_radio_params_5,
 
266
               sizeof(struct wl128x_ini_band_params_5));
 
267
        memcpy(&radio_parms->dyn_params_5,
 
268
               &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
 
269
               sizeof(struct wl128x_ini_fem_params_5));
 
270
 
 
271
        radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options;
 
272
 
 
273
        wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
 
274
                    radio_parms, sizeof(*radio_parms));
 
275
 
 
276
        ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
 
277
        if (ret < 0)
 
278
                wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
 
279
 
 
280
        kfree(radio_parms);
 
281
        return ret;
 
282
}
 
283
 
187
284
int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
188
285
{
189
286
        struct wl1271_ext_radio_parms_cmd *ext_radio_parms;
221
318
 * Poll the mailbox event field until any of the bits in the mask is set or a
222
319
 * timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
223
320
 */
224
 
static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
 
321
static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask)
225
322
{
226
323
        u32 events_vector, event;
227
324
        unsigned long timeout;
230
327
 
231
328
        do {
232
329
                if (time_after(jiffies, timeout)) {
233
 
                        ieee80211_queue_work(wl->hw, &wl->recovery_work);
 
330
                        wl1271_debug(DEBUG_CMD, "timeout waiting for event %d",
 
331
                                     (int)mask);
234
332
                        return -ETIMEDOUT;
235
333
                }
236
334
 
248
346
        return 0;
249
347
}
250
348
 
 
349
static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
 
350
{
 
351
        int ret;
 
352
 
 
353
        ret = wl1271_cmd_wait_for_event_or_timeout(wl, mask);
 
354
        if (ret != 0) {
 
355
                ieee80211_queue_work(wl->hw, &wl->recovery_work);
 
356
                return ret;
 
357
        }
 
358
 
 
359
        return 0;
 
360
}
 
361
 
251
362
int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
252
363
{
253
364
        struct wl1271_cmd_join *join;
271
382
        join->rx_filter_options = cpu_to_le32(wl->rx_filter);
272
383
        join->bss_type = bss_type;
273
384
        join->basic_rate_set = cpu_to_le32(wl->basic_rate_set);
 
385
        join->supported_rate_set = cpu_to_le32(wl->rate_set);
274
386
 
275
387
        if (wl->band == IEEE80211_BAND_5GHZ)
276
388
                join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ;
288
400
        wl->tx_security_last_seq = 0;
289
401
        wl->tx_security_seq = 0;
290
402
 
 
403
        wl1271_debug(DEBUG_CMD, "cmd join: basic_rate_set=0x%x, rate_set=0x%x",
 
404
                join->basic_rate_set, join->supported_rate_set);
 
405
 
291
406
        ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0);
292
407
        if (ret < 0) {
293
408
                wl1271_error("failed to initiate cmd join");
339
454
 * @wl: wl struct
340
455
 * @id: acx id
341
456
 * @buf: buffer for the response, including all headers, must work with dma
342
 
 * @len: lenght of buf
 
457
 * @len: length of buf
343
458
 */
344
459
int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len)
345
460
{
439
554
        return ret;
440
555
}
441
556
 
442
 
int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send)
 
557
int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode)
443
558
{
444
559
        struct wl1271_cmd_ps_params *ps_params = NULL;
445
560
        int ret = 0;
453
568
        }
454
569
 
455
570
        ps_params->ps_mode = ps_mode;
456
 
        ps_params->send_null_data = send;
457
 
        ps_params->retries = wl->conf.conn.psm_entry_nullfunc_retries;
458
 
        ps_params->hang_over_period = wl->conf.conn.psm_entry_hangover_period;
459
 
        ps_params->null_data_rate = cpu_to_le32(rates);
460
571
 
461
572
        ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
462
573
                              sizeof(*ps_params), 0);
490
601
        cmd->len = cpu_to_le16(buf_len);
491
602
        cmd->template_type = template_id;
492
603
        cmd->enabled_rates = cpu_to_le32(rates);
493
 
        cmd->short_retry_limit = wl->conf.tx.rc_conf.short_retry_limit;
494
 
        cmd->long_retry_limit = wl->conf.tx.rc_conf.long_retry_limit;
 
604
        cmd->short_retry_limit = wl->conf.tx.tmpl_short_retry_limit;
 
605
        cmd->long_retry_limit = wl->conf.tx.tmpl_long_retry_limit;
495
606
        cmd->index = index;
496
607
 
497
608
        if (buf)
659
770
 
660
771
        /* llc layer */
661
772
        memcpy(tmpl.llc_hdr, rfc1042_header, sizeof(rfc1042_header));
662
 
        tmpl.llc_type = htons(ETH_P_ARP);
 
773
        tmpl.llc_type = cpu_to_be16(ETH_P_ARP);
663
774
 
664
775
        /* arp header */
665
776
        arp_hdr = &tmpl.arp_hdr;
666
 
        arp_hdr->ar_hrd = htons(ARPHRD_ETHER);
667
 
        arp_hdr->ar_pro = htons(ETH_P_IP);
 
777
        arp_hdr->ar_hrd = cpu_to_be16(ARPHRD_ETHER);
 
778
        arp_hdr->ar_pro = cpu_to_be16(ETH_P_IP);
668
779
        arp_hdr->ar_hln = ETH_ALEN;
669
780
        arp_hdr->ar_pln = 4;
670
 
        arp_hdr->ar_op = htons(ARPOP_REPLY);
 
781
        arp_hdr->ar_op = cpu_to_be16(ARPOP_REPLY);
671
782
 
672
783
        /* arp payload */
673
784
        memcpy(tmpl.sender_hw, wl->vif->addr, ETH_ALEN);
702
813
                                       wl->basic_rate);
703
814
}
704
815
 
705
 
int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
 
816
int wl1271_cmd_set_sta_default_wep_key(struct wl1271 *wl, u8 id)
706
817
{
707
 
        struct wl1271_cmd_set_keys *cmd;
 
818
        struct wl1271_cmd_set_sta_keys *cmd;
708
819
        int ret = 0;
709
820
 
710
821
        wl1271_debug(DEBUG_CMD, "cmd set_default_wep_key %d", id);
731
842
        return ret;
732
843
}
733
844
 
734
 
int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
 
845
int wl1271_cmd_set_ap_default_wep_key(struct wl1271 *wl, u8 id)
 
846
{
 
847
        struct wl1271_cmd_set_ap_keys *cmd;
 
848
        int ret = 0;
 
849
 
 
850
        wl1271_debug(DEBUG_CMD, "cmd set_ap_default_wep_key %d", id);
 
851
 
 
852
        cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
 
853
        if (!cmd) {
 
854
                ret = -ENOMEM;
 
855
                goto out;
 
856
        }
 
857
 
 
858
        cmd->hlid = WL1271_AP_BROADCAST_HLID;
 
859
        cmd->key_id = id;
 
860
        cmd->lid_key_type = WEP_DEFAULT_LID_TYPE;
 
861
        cmd->key_action = cpu_to_le16(KEY_SET_ID);
 
862
        cmd->key_type = KEY_WEP;
 
863
 
 
864
        ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
 
865
        if (ret < 0) {
 
866
                wl1271_warning("cmd set_ap_default_wep_key failed: %d", ret);
 
867
                goto out;
 
868
        }
 
869
 
 
870
out:
 
871
        kfree(cmd);
 
872
 
 
873
        return ret;
 
874
}
 
875
 
 
876
int wl1271_cmd_set_sta_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
735
877
                       u8 key_size, const u8 *key, const u8 *addr,
736
878
                       u32 tx_seq_32, u16 tx_seq_16)
737
879
{
738
 
        struct wl1271_cmd_set_keys *cmd;
 
880
        struct wl1271_cmd_set_sta_keys *cmd;
739
881
        int ret = 0;
740
882
 
741
883
        cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
788
930
        return ret;
789
931
}
790
932
 
 
933
int wl1271_cmd_set_ap_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
 
934
                        u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32,
 
935
                        u16 tx_seq_16)
 
936
{
 
937
        struct wl1271_cmd_set_ap_keys *cmd;
 
938
        int ret = 0;
 
939
        u8 lid_type;
 
940
 
 
941
        cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
 
942
        if (!cmd)
 
943
                return -ENOMEM;
 
944
 
 
945
        if (hlid == WL1271_AP_BROADCAST_HLID) {
 
946
                if (key_type == KEY_WEP)
 
947
                        lid_type = WEP_DEFAULT_LID_TYPE;
 
948
                else
 
949
                        lid_type = BROADCAST_LID_TYPE;
 
950
        } else {
 
951
                lid_type = UNICAST_LID_TYPE;
 
952
        }
 
953
 
 
954
        wl1271_debug(DEBUG_CRYPT, "ap key action: %d id: %d lid: %d type: %d"
 
955
                     " hlid: %d", (int)action, (int)id, (int)lid_type,
 
956
                     (int)key_type, (int)hlid);
 
957
 
 
958
        cmd->lid_key_type = lid_type;
 
959
        cmd->hlid = hlid;
 
960
        cmd->key_action = cpu_to_le16(action);
 
961
        cmd->key_size = key_size;
 
962
        cmd->key_type = key_type;
 
963
        cmd->key_id = id;
 
964
        cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16);
 
965
        cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32);
 
966
 
 
967
        if (key_type == KEY_TKIP) {
 
968
                /*
 
969
                 * We get the key in the following form:
 
970
                 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
 
971
                 * but the target is expecting:
 
972
                 * TKIP - RX MIC - TX MIC
 
973
                 */
 
974
                memcpy(cmd->key, key, 16);
 
975
                memcpy(cmd->key + 16, key + 24, 8);
 
976
                memcpy(cmd->key + 24, key + 16, 8);
 
977
        } else {
 
978
                memcpy(cmd->key, key, key_size);
 
979
        }
 
980
 
 
981
        wl1271_dump(DEBUG_CRYPT, "TARGET AP KEY: ", cmd, sizeof(*cmd));
 
982
 
 
983
        ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
 
984
        if (ret < 0) {
 
985
                wl1271_warning("could not set ap keys");
 
986
                goto out;
 
987
        }
 
988
 
 
989
out:
 
990
        kfree(cmd);
 
991
        return ret;
 
992
}
 
993
 
791
994
int wl1271_cmd_disconnect(struct wl1271 *wl)
792
995
{
793
996
        struct wl1271_cmd_disconnect *cmd;
850
1053
out:
851
1054
        return ret;
852
1055
}
 
1056
 
 
1057
int wl1271_cmd_start_bss(struct wl1271 *wl)
 
1058
{
 
1059
        struct wl1271_cmd_bss_start *cmd;
 
1060
        struct ieee80211_bss_conf *bss_conf = &wl->vif->bss_conf;
 
1061
        int ret;
 
1062
 
 
1063
        wl1271_debug(DEBUG_CMD, "cmd start bss");
 
1064
 
 
1065
        /*
 
1066
         * FIXME: We currently do not support hidden SSID. The real SSID
 
1067
         * should be fetched from mac80211 first.
 
1068
         */
 
1069
        if (wl->ssid_len == 0) {
 
1070
                wl1271_warning("Hidden SSID currently not supported for AP");
 
1071
                ret = -EINVAL;
 
1072
                goto out;
 
1073
        }
 
1074
 
 
1075
        cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
 
1076
        if (!cmd) {
 
1077
                ret = -ENOMEM;
 
1078
                goto out;
 
1079
        }
 
1080
 
 
1081
        memcpy(cmd->bssid, bss_conf->bssid, ETH_ALEN);
 
1082
 
 
1083
        cmd->aging_period = cpu_to_le16(WL1271_AP_DEF_INACTIV_SEC);
 
1084
        cmd->bss_index = WL1271_AP_BSS_INDEX;
 
1085
        cmd->global_hlid = WL1271_AP_GLOBAL_HLID;
 
1086
        cmd->broadcast_hlid = WL1271_AP_BROADCAST_HLID;
 
1087
        cmd->basic_rate_set = cpu_to_le32(wl->basic_rate_set);
 
1088
        cmd->beacon_interval = cpu_to_le16(wl->beacon_int);
 
1089
        cmd->dtim_interval = bss_conf->dtim_period;
 
1090
        cmd->beacon_expiry = WL1271_AP_DEF_BEACON_EXP;
 
1091
        cmd->channel = wl->channel;
 
1092
        cmd->ssid_len = wl->ssid_len;
 
1093
        cmd->ssid_type = SSID_TYPE_PUBLIC;
 
1094
        memcpy(cmd->ssid, wl->ssid, wl->ssid_len);
 
1095
 
 
1096
        switch (wl->band) {
 
1097
        case IEEE80211_BAND_2GHZ:
 
1098
                cmd->band = RADIO_BAND_2_4GHZ;
 
1099
                break;
 
1100
        case IEEE80211_BAND_5GHZ:
 
1101
                cmd->band = RADIO_BAND_5GHZ;
 
1102
                break;
 
1103
        default:
 
1104
                wl1271_warning("bss start - unknown band: %d", (int)wl->band);
 
1105
                cmd->band = RADIO_BAND_2_4GHZ;
 
1106
                break;
 
1107
        }
 
1108
 
 
1109
        ret = wl1271_cmd_send(wl, CMD_BSS_START, cmd, sizeof(*cmd), 0);
 
1110
        if (ret < 0) {
 
1111
                wl1271_error("failed to initiate cmd start bss");
 
1112
                goto out_free;
 
1113
        }
 
1114
 
 
1115
out_free:
 
1116
        kfree(cmd);
 
1117
 
 
1118
out:
 
1119
        return ret;
 
1120
}
 
1121
 
 
1122
int wl1271_cmd_stop_bss(struct wl1271 *wl)
 
1123
{
 
1124
        struct wl1271_cmd_bss_start *cmd;
 
1125
        int ret;
 
1126
 
 
1127
        wl1271_debug(DEBUG_CMD, "cmd stop bss");
 
1128
 
 
1129
        cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
 
1130
        if (!cmd) {
 
1131
                ret = -ENOMEM;
 
1132
                goto out;
 
1133
        }
 
1134
 
 
1135
        cmd->bss_index = WL1271_AP_BSS_INDEX;
 
1136
 
 
1137
        ret = wl1271_cmd_send(wl, CMD_BSS_STOP, cmd, sizeof(*cmd), 0);
 
1138
        if (ret < 0) {
 
1139
                wl1271_error("failed to initiate cmd stop bss");
 
1140
                goto out_free;
 
1141
        }
 
1142
 
 
1143
out_free:
 
1144
        kfree(cmd);
 
1145
 
 
1146
out:
 
1147
        return ret;
 
1148
}
 
1149
 
 
1150
int wl1271_cmd_add_sta(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid)
 
1151
{
 
1152
        struct wl1271_cmd_add_sta *cmd;
 
1153
        int ret;
 
1154
 
 
1155
        wl1271_debug(DEBUG_CMD, "cmd add sta %d", (int)hlid);
 
1156
 
 
1157
        cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
 
1158
        if (!cmd) {
 
1159
                ret = -ENOMEM;
 
1160
                goto out;
 
1161
        }
 
1162
 
 
1163
        /* currently we don't support UAPSD */
 
1164
        cmd->sp_len = 0;
 
1165
 
 
1166
        memcpy(cmd->addr, sta->addr, ETH_ALEN);
 
1167
        cmd->bss_index = WL1271_AP_BSS_INDEX;
 
1168
        cmd->aid = sta->aid;
 
1169
        cmd->hlid = hlid;
 
1170
 
 
1171
        /*
 
1172
         * FIXME: Does STA support QOS? We need to propagate this info from
 
1173
         * hostapd. Currently not that important since this is only used for
 
1174
         * sending the correct flavor of null-data packet in response to a
 
1175
         * trigger.
 
1176
         */
 
1177
        cmd->wmm = 0;
 
1178
 
 
1179
        cmd->supported_rates = cpu_to_le32(wl1271_tx_enabled_rates_get(wl,
 
1180
                                                sta->supp_rates[wl->band]));
 
1181
 
 
1182
        wl1271_debug(DEBUG_CMD, "new sta rates: 0x%x", cmd->supported_rates);
 
1183
 
 
1184
        ret = wl1271_cmd_send(wl, CMD_ADD_STA, cmd, sizeof(*cmd), 0);
 
1185
        if (ret < 0) {
 
1186
                wl1271_error("failed to initiate cmd add sta");
 
1187
                goto out_free;
 
1188
        }
 
1189
 
 
1190
out_free:
 
1191
        kfree(cmd);
 
1192
 
 
1193
out:
 
1194
        return ret;
 
1195
}
 
1196
 
 
1197
int wl1271_cmd_remove_sta(struct wl1271 *wl, u8 hlid)
 
1198
{
 
1199
        struct wl1271_cmd_remove_sta *cmd;
 
1200
        int ret;
 
1201
 
 
1202
        wl1271_debug(DEBUG_CMD, "cmd remove sta %d", (int)hlid);
 
1203
 
 
1204
        cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
 
1205
        if (!cmd) {
 
1206
                ret = -ENOMEM;
 
1207
                goto out;
 
1208
        }
 
1209
 
 
1210
        cmd->hlid = hlid;
 
1211
        /* We never send a deauth, mac80211 is in charge of this */
 
1212
        cmd->reason_opcode = 0;
 
1213
        cmd->send_deauth_flag = 0;
 
1214
 
 
1215
        ret = wl1271_cmd_send(wl, CMD_REMOVE_STA, cmd, sizeof(*cmd), 0);
 
1216
        if (ret < 0) {
 
1217
                wl1271_error("failed to initiate cmd remove sta");
 
1218
                goto out_free;
 
1219
        }
 
1220
 
 
1221
        /*
 
1222
         * We are ok with a timeout here. The event is sometimes not sent
 
1223
         * due to a firmware bug.
 
1224
         */
 
1225
        wl1271_cmd_wait_for_event_or_timeout(wl, STA_REMOVE_COMPLETE_EVENT_ID);
 
1226
 
 
1227
out_free:
 
1228
        kfree(cmd);
 
1229
 
 
1230
out:
 
1231
        return ret;
 
1232
}