wl12xx: implement set_bitrate_mask callback
[pandora-kernel.git] / drivers / net / wireless / wl12xx / init.c
1 /*
2  * This file is part of wl1271
3  *
4  * Copyright (C) 2009 Nokia Corporation
5  *
6  * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * version 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  *
22  */
23
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/slab.h>
27
28 #include "init.h"
29 #include "wl12xx_80211.h"
30 #include "acx.h"
31 #include "cmd.h"
32 #include "reg.h"
33 #include "tx.h"
34 #include "io.h"
35
36 int wl1271_sta_init_templates_config(struct wl1271 *wl)
37 {
38         int ret, i;
39
40         /* send empty templates for fw memory reservation */
41         ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
42                                       WL1271_CMD_TEMPL_DFLT_SIZE,
43                                       0, WL1271_RATE_AUTOMATIC);
44         if (ret < 0)
45                 return ret;
46
47         ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
48                                       NULL, WL1271_CMD_TEMPL_DFLT_SIZE, 0,
49                                       WL1271_RATE_AUTOMATIC);
50         if (ret < 0)
51                 return ret;
52
53         ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
54                                       sizeof(struct wl12xx_null_data_template),
55                                       0, WL1271_RATE_AUTOMATIC);
56         if (ret < 0)
57                 return ret;
58
59         ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL,
60                                       sizeof(struct wl12xx_ps_poll_template),
61                                       0, WL1271_RATE_AUTOMATIC);
62         if (ret < 0)
63                 return ret;
64
65         ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL,
66                                       sizeof
67                                       (struct wl12xx_qos_null_data_template),
68                                       0, WL1271_RATE_AUTOMATIC);
69         if (ret < 0)
70                 return ret;
71
72         ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL,
73                                       WL1271_CMD_TEMPL_DFLT_SIZE,
74                                       0, WL1271_RATE_AUTOMATIC);
75         if (ret < 0)
76                 return ret;
77
78         ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL,
79                                       WL1271_CMD_TEMPL_DFLT_SIZE,
80                                       0, WL1271_RATE_AUTOMATIC);
81         if (ret < 0)
82                 return ret;
83
84         ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP, NULL,
85                                       sizeof
86                                       (struct wl12xx_arp_rsp_template),
87                                       0, WL1271_RATE_AUTOMATIC);
88         if (ret < 0)
89                 return ret;
90
91         for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
92                 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL,
93                                               WL1271_CMD_TEMPL_DFLT_SIZE, i,
94                                               WL1271_RATE_AUTOMATIC);
95                 if (ret < 0)
96                         return ret;
97         }
98
99         return 0;
100 }
101
102 static int wl1271_ap_init_deauth_template(struct wl1271 *wl)
103 {
104         struct wl12xx_disconn_template *tmpl;
105         int ret;
106         u32 rate;
107
108         tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL);
109         if (!tmpl) {
110                 ret = -ENOMEM;
111                 goto out;
112         }
113
114         tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
115                                              IEEE80211_STYPE_DEAUTH);
116
117         rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
118         ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP,
119                                       tmpl, sizeof(*tmpl), 0, rate);
120
121 out:
122         kfree(tmpl);
123         return ret;
124 }
125
126 static int wl1271_ap_init_null_template(struct wl1271 *wl)
127 {
128         struct ieee80211_hdr_3addr *nullfunc;
129         int ret;
130         u32 rate;
131
132         nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL);
133         if (!nullfunc) {
134                 ret = -ENOMEM;
135                 goto out;
136         }
137
138         nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
139                                               IEEE80211_STYPE_NULLFUNC |
140                                               IEEE80211_FCTL_FROMDS);
141
142         /* nullfunc->addr1 is filled by FW */
143
144         memcpy(nullfunc->addr2, wl->mac_addr, ETH_ALEN);
145         memcpy(nullfunc->addr3, wl->mac_addr, ETH_ALEN);
146
147         rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
148         ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc,
149                                       sizeof(*nullfunc), 0, rate);
150
151 out:
152         kfree(nullfunc);
153         return ret;
154 }
155
156 static int wl1271_ap_init_qos_null_template(struct wl1271 *wl)
157 {
158         struct ieee80211_qos_hdr *qosnull;
159         int ret;
160         u32 rate;
161
162         qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL);
163         if (!qosnull) {
164                 ret = -ENOMEM;
165                 goto out;
166         }
167
168         qosnull->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
169                                              IEEE80211_STYPE_QOS_NULLFUNC |
170                                              IEEE80211_FCTL_FROMDS);
171
172         /* qosnull->addr1 is filled by FW */
173
174         memcpy(qosnull->addr2, wl->mac_addr, ETH_ALEN);
175         memcpy(qosnull->addr3, wl->mac_addr, ETH_ALEN);
176
177         rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
178         ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull,
179                                       sizeof(*qosnull), 0, rate);
180
181 out:
182         kfree(qosnull);
183         return ret;
184 }
185
186 static int wl1271_ap_init_templates_config(struct wl1271 *wl)
187 {
188         int ret;
189
190         /*
191          * Put very large empty placeholders for all templates. These
192          * reserve memory for later.
193          */
194         ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_PROBE_RESPONSE, NULL,
195                                       WL1271_CMD_TEMPL_MAX_SIZE,
196                                       0, WL1271_RATE_AUTOMATIC);
197         if (ret < 0)
198                 return ret;
199
200         ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_BEACON, NULL,
201                                       WL1271_CMD_TEMPL_MAX_SIZE,
202                                       0, WL1271_RATE_AUTOMATIC);
203         if (ret < 0)
204                 return ret;
205
206         ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, NULL,
207                                       sizeof
208                                       (struct wl12xx_disconn_template),
209                                       0, WL1271_RATE_AUTOMATIC);
210         if (ret < 0)
211                 return ret;
212
213         ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
214                                       sizeof(struct wl12xx_null_data_template),
215                                       0, WL1271_RATE_AUTOMATIC);
216         if (ret < 0)
217                 return ret;
218
219         ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL,
220                                       sizeof
221                                       (struct wl12xx_qos_null_data_template),
222                                       0, WL1271_RATE_AUTOMATIC);
223         if (ret < 0)
224                 return ret;
225
226         return 0;
227 }
228
229 static int wl12xx_init_rx_config(struct wl1271 *wl)
230 {
231         int ret;
232
233         ret = wl1271_acx_rx_msdu_life_time(wl);
234         if (ret < 0)
235                 return ret;
236
237         return 0;
238 }
239
240 int wl1271_init_phy_config(struct wl1271 *wl)
241 {
242         int ret;
243
244         ret = wl1271_acx_pd_threshold(wl);
245         if (ret < 0)
246                 return ret;
247
248         ret = wl1271_acx_slot(wl, DEFAULT_SLOT_TIME);
249         if (ret < 0)
250                 return ret;
251
252         ret = wl1271_acx_service_period_timeout(wl);
253         if (ret < 0)
254                 return ret;
255
256         ret = wl1271_acx_rts_threshold(wl, wl->hw->wiphy->rts_threshold);
257         if (ret < 0)
258                 return ret;
259
260         return 0;
261 }
262
263 static int wl1271_init_beacon_filter(struct wl1271 *wl)
264 {
265         int ret;
266
267         /* disable beacon filtering at this stage */
268         ret = wl1271_acx_beacon_filter_opt(wl, false);
269         if (ret < 0)
270                 return ret;
271
272         ret = wl1271_acx_beacon_filter_table(wl);
273         if (ret < 0)
274                 return ret;
275
276         return 0;
277 }
278
279 int wl1271_init_pta(struct wl1271 *wl)
280 {
281         int ret;
282
283         ret = wl12xx_acx_sg_cfg(wl);
284         if (ret < 0)
285                 return ret;
286
287         ret = wl1271_acx_sg_enable(wl, wl->sg_enabled);
288         if (ret < 0)
289                 return ret;
290
291         return 0;
292 }
293
294 int wl1271_init_energy_detection(struct wl1271 *wl)
295 {
296         int ret;
297
298         ret = wl1271_acx_cca_threshold(wl);
299         if (ret < 0)
300                 return ret;
301
302         return 0;
303 }
304
305 static int wl1271_init_beacon_broadcast(struct wl1271 *wl)
306 {
307         int ret;
308
309         ret = wl1271_acx_bcn_dtim_options(wl);
310         if (ret < 0)
311                 return ret;
312
313         return 0;
314 }
315
316 static int wl12xx_init_fwlog(struct wl1271 *wl)
317 {
318         int ret;
319
320         if (wl->quirks & WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED)
321                 return 0;
322
323         ret = wl12xx_cmd_config_fwlog(wl);
324         if (ret < 0)
325                 return ret;
326
327         return 0;
328 }
329
330 static int wl1271_sta_hw_init(struct wl1271 *wl)
331 {
332         int ret;
333
334         if (wl->chip.id != CHIP_ID_1283_PG20) {
335                 ret = wl1271_cmd_ext_radio_parms(wl);
336                 if (ret < 0)
337                         return ret;
338         }
339
340         /* PS config */
341         ret = wl1271_acx_config_ps(wl);
342         if (ret < 0)
343                 return ret;
344
345         ret = wl1271_sta_init_templates_config(wl);
346         if (ret < 0)
347                 return ret;
348
349         ret = wl1271_acx_group_address_tbl(wl, true, NULL, 0);
350         if (ret < 0)
351                 return ret;
352
353         /* Initialize connection monitoring thresholds */
354         ret = wl1271_acx_conn_monit_params(wl, false);
355         if (ret < 0)
356                 return ret;
357
358         /* Beacon filtering */
359         ret = wl1271_init_beacon_filter(wl);
360         if (ret < 0)
361                 return ret;
362
363         /* FM WLAN coexistence */
364         ret = wl1271_acx_fm_coex(wl);
365         if (ret < 0)
366                 return ret;
367
368         /* Beacons and broadcast settings */
369         ret = wl1271_init_beacon_broadcast(wl);
370         if (ret < 0)
371                 return ret;
372
373         /* Configure for ELP power saving */
374         ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP);
375         if (ret < 0)
376                 return ret;
377
378         /* Configure rssi/snr averaging weights */
379         ret = wl1271_acx_rssi_snr_avg_weights(wl);
380         if (ret < 0)
381                 return ret;
382
383         ret = wl1271_acx_sta_rate_policies(wl);
384         if (ret < 0)
385                 return ret;
386
387         ret = wl12xx_acx_mem_cfg(wl);
388         if (ret < 0)
389                 return ret;
390
391         /* Configure the FW logger */
392         ret = wl12xx_init_fwlog(wl);
393         if (ret < 0)
394                 return ret;
395
396         return 0;
397 }
398
399 static int wl1271_sta_hw_init_post_mem(struct wl1271 *wl)
400 {
401         int ret, i;
402
403         /* disable all keep-alive templates */
404         for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
405                 ret = wl1271_acx_keep_alive_config(wl, i,
406                                                    ACX_KEEP_ALIVE_TPL_INVALID);
407                 if (ret < 0)
408                         return ret;
409         }
410
411         /* disable the keep-alive feature */
412         ret = wl1271_acx_keep_alive_mode(wl, false);
413         if (ret < 0)
414                 return ret;
415
416         return 0;
417 }
418
419 static int wl1271_ap_hw_init(struct wl1271 *wl)
420 {
421         int ret;
422
423         ret = wl1271_ap_init_templates_config(wl);
424         if (ret < 0)
425                 return ret;
426
427         /* Configure for power always on */
428         ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
429         if (ret < 0)
430                 return ret;
431
432         ret = wl1271_init_ap_rates(wl);
433         if (ret < 0)
434                 return ret;
435
436         ret = wl1271_acx_ap_max_tx_retry(wl);
437         if (ret < 0)
438                 return ret;
439
440         ret = wl12xx_acx_mem_cfg(wl);
441         if (ret < 0)
442                 return ret;
443
444         /* initialize Tx power */
445         ret = wl1271_acx_tx_power(wl, wl->power_level);
446         if (ret < 0)
447                 return ret;
448
449         return 0;
450 }
451
452 int wl1271_ap_init_templates(struct wl1271 *wl)
453 {
454         int ret;
455
456         ret = wl1271_ap_init_deauth_template(wl);
457         if (ret < 0)
458                 return ret;
459
460         ret = wl1271_ap_init_null_template(wl);
461         if (ret < 0)
462                 return ret;
463
464         ret = wl1271_ap_init_qos_null_template(wl);
465         if (ret < 0)
466                 return ret;
467
468         /*
469          * when operating as AP we want to receive external beacons for
470          * configuring ERP protection.
471          */
472         ret = wl1271_acx_beacon_filter_opt(wl, false);
473         if (ret < 0)
474                 return ret;
475
476         return 0;
477 }
478
479 static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
480 {
481         return wl1271_ap_init_templates(wl);
482 }
483
484 int wl1271_init_ap_rates(struct wl1271 *wl)
485 {
486         int i, ret;
487         struct conf_tx_rate_class rc;
488         u32 supported_rates;
489
490         wl1271_debug(DEBUG_AP, "AP basic rate set: 0x%x", wl->basic_rate_set);
491
492         if (wl->basic_rate_set == 0)
493                 return -EINVAL;
494
495         rc.enabled_rates = wl->basic_rate_set;
496         rc.long_retry_limit = 10;
497         rc.short_retry_limit = 10;
498         rc.aflags = 0;
499         ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_MGMT_RATE);
500         if (ret < 0)
501                 return ret;
502
503         /* use the min basic rate for AP broadcast/multicast */
504         rc.enabled_rates = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
505         rc.short_retry_limit = 10;
506         rc.long_retry_limit = 10;
507         rc.aflags = 0;
508         ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_BCST_RATE);
509         if (ret < 0)
510                 return ret;
511
512         /*
513          * If the basic rates contain OFDM rates, use OFDM only
514          * rates for unicast TX as well. Else use all supported rates.
515          */
516         if ((wl->basic_rate_set & CONF_TX_OFDM_RATES))
517                 supported_rates = CONF_TX_OFDM_RATES;
518         else
519                 supported_rates = CONF_TX_AP_ENABLED_RATES;
520
521         /* unconditionally enable HT rates */
522         supported_rates |= CONF_TX_MCS_RATES;
523
524         /* configure unicast TX rate classes */
525         for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
526                 rc.enabled_rates = supported_rates;
527                 rc.short_retry_limit = 10;
528                 rc.long_retry_limit = 10;
529                 rc.aflags = 0;
530                 ret = wl1271_acx_ap_rate_policy(wl, &rc, i);
531                 if (ret < 0)
532                         return ret;
533         }
534
535         return 0;
536 }
537
538 static int wl1271_set_ba_policies(struct wl1271 *wl)
539 {
540         /* Reset the BA RX indicators */
541         wl->ba_rx_bitmap = 0;
542         wl->ba_allowed = true;
543         wl->ba_rx_session_count = 0;
544
545         /* BA is supported in STA/AP modes */
546         if (wl->bss_type != BSS_TYPE_AP_BSS &&
547             wl->bss_type != BSS_TYPE_STA_BSS) {
548                 wl->ba_support = false;
549                 return 0;
550         }
551
552         wl->ba_support = true;
553
554         /* 802.11n initiator BA session setting */
555         return wl12xx_acx_set_ba_initiator_policy(wl);
556 }
557
558 int wl1271_chip_specific_init(struct wl1271 *wl)
559 {
560         int ret = 0;
561
562         if (wl->chip.id == CHIP_ID_1283_PG20) {
563                 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
564
565                 if (wl->quirks & WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT)
566                         /* Enable SDIO padding */
567                         host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
568
569                 /* Must be before wl1271_acx_init_mem_config() */
570                 ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap);
571                 if (ret < 0)
572                         goto out;
573         }
574 out:
575         return ret;
576 }
577
578
579 int wl1271_hw_init(struct wl1271 *wl)
580 {
581         struct conf_tx_ac_category *conf_ac;
582         struct conf_tx_tid *conf_tid;
583         int ret, i;
584         bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS);
585
586         if (wl->chip.id == CHIP_ID_1283_PG20)
587                 ret = wl128x_cmd_general_parms(wl);
588         else
589                 ret = wl1271_cmd_general_parms(wl);
590         if (ret < 0)
591                 return ret;
592
593         if (wl->chip.id == CHIP_ID_1283_PG20)
594                 ret = wl128x_cmd_radio_parms(wl);
595         else
596                 ret = wl1271_cmd_radio_parms(wl);
597         if (ret < 0)
598                 return ret;
599
600         /* Chip-specific init */
601         ret = wl1271_chip_specific_init(wl);
602         if (ret < 0)
603                 return ret;
604
605         /* Mode specific init */
606         if (is_ap)
607                 ret = wl1271_ap_hw_init(wl);
608         else
609                 ret = wl1271_sta_hw_init(wl);
610
611         if (ret < 0)
612                 return ret;
613
614         /* Bluetooth WLAN coexistence */
615         ret = wl1271_init_pta(wl);
616         if (ret < 0)
617                 return ret;
618
619         /* Default memory configuration */
620         ret = wl1271_acx_init_mem_config(wl);
621         if (ret < 0)
622                 return ret;
623
624         /* RX config */
625         ret = wl12xx_init_rx_config(wl);
626         if (ret < 0)
627                 goto out_free_memmap;
628
629         /* PHY layer config */
630         ret = wl1271_init_phy_config(wl);
631         if (ret < 0)
632                 goto out_free_memmap;
633
634         ret = wl1271_acx_dco_itrim_params(wl);
635         if (ret < 0)
636                 goto out_free_memmap;
637
638         /* Configure TX patch complete interrupt behavior */
639         ret = wl1271_acx_tx_config_options(wl);
640         if (ret < 0)
641                 goto out_free_memmap;
642
643         /* RX complete interrupt pacing */
644         ret = wl1271_acx_init_rx_interrupt(wl);
645         if (ret < 0)
646                 goto out_free_memmap;
647
648         /* Energy detection */
649         ret = wl1271_init_energy_detection(wl);
650         if (ret < 0)
651                 goto out_free_memmap;
652
653         /* Default fragmentation threshold */
654         ret = wl1271_acx_frag_threshold(wl, wl->hw->wiphy->frag_threshold);
655         if (ret < 0)
656                 goto out_free_memmap;
657
658         /* Default TID/AC configuration */
659         BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count);
660         for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
661                 conf_ac = &wl->conf.tx.ac_conf[i];
662                 ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
663                                         conf_ac->cw_max, conf_ac->aifsn,
664                                         conf_ac->tx_op_limit);
665                 if (ret < 0)
666                         goto out_free_memmap;
667
668                 conf_tid = &wl->conf.tx.tid_conf[i];
669                 ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id,
670                                          conf_tid->channel_type,
671                                          conf_tid->tsid,
672                                          conf_tid->ps_scheme,
673                                          conf_tid->ack_policy,
674                                          conf_tid->apsd_conf[0],
675                                          conf_tid->apsd_conf[1]);
676                 if (ret < 0)
677                         goto out_free_memmap;
678         }
679
680         /* Enable data path */
681         ret = wl1271_cmd_data_path(wl, 1);
682         if (ret < 0)
683                 goto out_free_memmap;
684
685         /* Configure HW encryption */
686         ret = wl1271_acx_feature_cfg(wl);
687         if (ret < 0)
688                 goto out_free_memmap;
689
690         /* configure PM */
691         ret = wl1271_acx_pm_config(wl);
692         if (ret < 0)
693                 goto out_free_memmap;
694
695         /* Mode specific init - post mem init */
696         if (is_ap)
697                 ret = wl1271_ap_hw_init_post_mem(wl);
698         else
699                 ret = wl1271_sta_hw_init_post_mem(wl);
700
701         if (ret < 0)
702                 goto out_free_memmap;
703
704         ret = wl12xx_acx_set_rate_mgmt_params(wl);
705         if (ret < 0)
706                 goto out_free_memmap;
707
708         /* Configure initiator BA sessions policies */
709         ret = wl1271_set_ba_policies(wl);
710         if (ret < 0)
711                 goto out_free_memmap;
712
713         /* configure hangover */
714         ret = wl12xx_acx_config_hangover(wl);
715         if (ret < 0)
716                 goto out_free_memmap;
717
718         return 0;
719
720  out_free_memmap:
721         kfree(wl->target_mem_map);
722         wl->target_mem_map = NULL;
723
724         return ret;
725 }