Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / drivers / net / wireless / wl12xx / init.c
index 62dc983..a8f4f15 100644 (file)
@@ -31,6 +31,7 @@
 #include "cmd.h"
 #include "reg.h"
 #include "tx.h"
+#include "io.h"
 
 int wl1271_sta_init_templates_config(struct wl1271 *wl)
 {
@@ -257,7 +258,7 @@ int wl1271_init_phy_config(struct wl1271 *wl)
        if (ret < 0)
                return ret;
 
-       ret = wl1271_acx_rts_threshold(wl, wl->conf.rx.rts_threshold);
+       ret = wl1271_acx_rts_threshold(wl, wl->hw->wiphy->rts_threshold);
        if (ret < 0)
                return ret;
 
@@ -284,7 +285,10 @@ int wl1271_init_pta(struct wl1271 *wl)
 {
        int ret;
 
-       ret = wl1271_acx_sg_cfg(wl);
+       if (wl->bss_type == BSS_TYPE_AP_BSS)
+               ret = wl1271_acx_ap_sg_cfg(wl);
+       else
+               ret = wl1271_acx_sta_sg_cfg(wl);
        if (ret < 0)
                return ret;
 
@@ -321,9 +325,11 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
 {
        int ret;
 
-       ret = wl1271_cmd_ext_radio_parms(wl);
-       if (ret < 0)
-               return ret;
+       if (wl->chip.id != CHIP_ID_1283_PG20) {
+               ret = wl1271_cmd_ext_radio_parms(wl);
+               if (ret < 0)
+                       return ret;
+       }
 
        /* PS config */
        ret = wl1271_acx_config_ps(wl);
@@ -348,8 +354,8 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
        if (ret < 0)
                return ret;
 
-       /* Bluetooth WLAN coexistence */
-       ret = wl1271_init_pta(wl);
+       /* FM WLAN coexistence */
+       ret = wl1271_acx_fm_coex(wl);
        if (ret < 0)
                return ret;
 
@@ -407,7 +413,7 @@ static int wl1271_sta_hw_init_post_mem(struct wl1271 *wl)
 
 static int wl1271_ap_hw_init(struct wl1271 *wl)
 {
-       int ret, i;
+       int ret;
 
        ret = wl1271_ap_init_templates_config(wl);
        if (ret < 0)
@@ -418,23 +424,7 @@ static int wl1271_ap_hw_init(struct wl1271 *wl)
        if (ret < 0)
                return ret;
 
-       /* Configure initial TX rate classes */
-       for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
-               ret = wl1271_acx_ap_rate_policy(wl,
-                               &wl->conf.tx.ap_rc_conf[i], i);
-               if (ret < 0)
-                       return ret;
-       }
-
-       ret = wl1271_acx_ap_rate_policy(wl,
-                                       &wl->conf.tx.ap_mgmt_conf,
-                                       ACX_TX_AP_MODE_MGMT_RATE);
-       if (ret < 0)
-               return ret;
-
-       ret = wl1271_acx_ap_rate_policy(wl,
-                                       &wl->conf.tx.ap_bcst_conf,
-                                       ACX_TX_AP_MODE_BCST_RATE);
+       ret = wl1271_init_ap_rates(wl);
        if (ret < 0)
                return ret;
 
@@ -449,7 +439,7 @@ static int wl1271_ap_hw_init(struct wl1271 *wl)
        return 0;
 }
 
-static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
+int wl1271_ap_init_templates(struct wl1271 *wl)
 {
        int ret;
 
@@ -465,6 +455,70 @@ static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
        if (ret < 0)
                return ret;
 
+       /*
+        * when operating as AP we want to receive external beacons for
+        * configuring ERP protection.
+        */
+       ret = wl1271_acx_set_ap_beacon_filter(wl, false);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
+{
+       return wl1271_ap_init_templates(wl);
+}
+
+int wl1271_init_ap_rates(struct wl1271 *wl)
+{
+       int i, ret;
+       struct conf_tx_rate_class rc;
+       u32 supported_rates;
+
+       wl1271_debug(DEBUG_AP, "AP basic rate set: 0x%x", wl->basic_rate_set);
+
+       if (wl->basic_rate_set == 0)
+               return -EINVAL;
+
+       rc.enabled_rates = wl->basic_rate_set;
+       rc.long_retry_limit = 10;
+       rc.short_retry_limit = 10;
+       rc.aflags = 0;
+       ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_MGMT_RATE);
+       if (ret < 0)
+               return ret;
+
+       /* use the min basic rate for AP broadcast/multicast */
+       rc.enabled_rates = wl1271_tx_min_rate_get(wl);
+       rc.short_retry_limit = 10;
+       rc.long_retry_limit = 10;
+       rc.aflags = 0;
+       ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_BCST_RATE);
+       if (ret < 0)
+               return ret;
+
+       /*
+        * If the basic rates contain OFDM rates, use OFDM only
+        * rates for unicast TX as well. Else use all supported rates.
+        */
+       if ((wl->basic_rate_set & CONF_TX_OFDM_RATES))
+               supported_rates = CONF_TX_OFDM_RATES;
+       else
+               supported_rates = CONF_TX_AP_ENABLED_RATES;
+
+       /* configure unicast TX rate classes */
+       for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
+               rc.enabled_rates = supported_rates;
+               rc.short_retry_limit = 10;
+               rc.long_retry_limit = 10;
+               rc.aflags = 0;
+               ret = wl1271_acx_ap_rate_policy(wl, &rc, i);
+               if (ret < 0)
+                       return ret;
+       }
+
        return 0;
 }
 
@@ -483,7 +537,7 @@ static void wl1271_check_ba_support(struct wl1271 *wl)
 static int wl1271_set_ba_policies(struct wl1271 *wl)
 {
        u8 tid_index;
-       u8 ret = 0;
+       int ret = 0;
 
        /* Reset the BA RX indicators */
        wl->ba_rx_bitmap = 0;
@@ -504,6 +558,27 @@ static int wl1271_set_ba_policies(struct wl1271 *wl)
        return ret;
 }
 
+int wl1271_chip_specific_init(struct wl1271 *wl)
+{
+       int ret = 0;
+
+       if (wl->chip.id == CHIP_ID_1283_PG20) {
+               u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
+
+               if (wl->quirks & WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT)
+                       /* Enable SDIO padding */
+                       host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
+
+               /* Must be before wl1271_acx_init_mem_config() */
+               ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap);
+               if (ret < 0)
+                       goto out;
+       }
+out:
+       return ret;
+}
+
+
 int wl1271_hw_init(struct wl1271 *wl)
 {
        struct conf_tx_ac_category *conf_ac;
@@ -511,11 +586,22 @@ int wl1271_hw_init(struct wl1271 *wl)
        int ret, i;
        bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS);
 
-       ret = wl1271_cmd_general_parms(wl);
+       if (wl->chip.id == CHIP_ID_1283_PG20)
+               ret = wl128x_cmd_general_parms(wl);
+       else
+               ret = wl1271_cmd_general_parms(wl);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_radio_parms(wl);
+       if (wl->chip.id == CHIP_ID_1283_PG20)
+               ret = wl128x_cmd_radio_parms(wl);
+       else
+               ret = wl1271_cmd_radio_parms(wl);
+       if (ret < 0)
+               return ret;
+
+       /* Chip-specific init */
+       ret = wl1271_chip_specific_init(wl);
        if (ret < 0)
                return ret;
 
@@ -528,6 +614,11 @@ int wl1271_hw_init(struct wl1271 *wl)
        if (ret < 0)
                return ret;
 
+       /* Bluetooth WLAN coexistence */
+       ret = wl1271_init_pta(wl);
+       if (ret < 0)
+               return ret;
+
        /* Default memory configuration */
        ret = wl1271_acx_init_mem_config(wl);
        if (ret < 0)
@@ -567,7 +658,7 @@ int wl1271_hw_init(struct wl1271 *wl)
                goto out_free_memmap;
 
        /* Default fragmentation threshold */
-       ret = wl1271_acx_frag_threshold(wl, wl->conf.tx.frag_threshold);
+       ret = wl1271_acx_frag_threshold(wl, wl->hw->wiphy->frag_threshold);
        if (ret < 0)
                goto out_free_memmap;