root/drivers/net/wireless/ti/wl1251/init.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wl1251_hw_init_hwenc_config
  2. wl1251_hw_init_templates_config
  3. wl1251_hw_init_rx_config
  4. wl1251_hw_init_phy_config
  5. wl1251_hw_init_beacon_filter
  6. wl1251_hw_init_pta
  7. wl1251_hw_init_energy_detection
  8. wl1251_hw_init_beacon_broadcast
  9. wl1251_hw_init_power_auth
  10. wl1251_hw_init_mem_config
  11. wl1251_hw_init_txq_fill
  12. wl1251_hw_init_tx_queue_config
  13. wl1251_hw_init_data_path_config
  14. wl1251_hw_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * This file is part of wl1251
   4  *
   5  * Copyright (C) 2009 Nokia Corporation
   6  */
   7 
   8 #include <linux/kernel.h>
   9 #include <linux/module.h>
  10 #include <linux/slab.h>
  11 
  12 #include "init.h"
  13 #include "wl12xx_80211.h"
  14 #include "acx.h"
  15 #include "cmd.h"
  16 #include "reg.h"
  17 
  18 int wl1251_hw_init_hwenc_config(struct wl1251 *wl)
  19 {
  20         int ret;
  21 
  22         ret = wl1251_acx_feature_cfg(wl, 0);
  23         if (ret < 0) {
  24                 wl1251_warning("couldn't set feature config");
  25                 return ret;
  26         }
  27 
  28         ret = wl1251_acx_default_key(wl, wl->default_key);
  29         if (ret < 0) {
  30                 wl1251_warning("couldn't set default key");
  31                 return ret;
  32         }
  33 
  34         return 0;
  35 }
  36 
  37 int wl1251_hw_init_templates_config(struct wl1251 *wl)
  38 {
  39         int ret;
  40         u8 partial_vbm[PARTIAL_VBM_MAX];
  41 
  42         /* send empty templates for fw memory reservation */
  43         ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, NULL,
  44                                       sizeof(struct wl12xx_probe_req_template));
  45         if (ret < 0)
  46                 return ret;
  47 
  48         ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA, NULL,
  49                                       sizeof(struct wl12xx_null_data_template));
  50         if (ret < 0)
  51                 return ret;
  52 
  53         ret = wl1251_cmd_template_set(wl, CMD_PS_POLL, NULL,
  54                                       sizeof(struct wl12xx_ps_poll_template));
  55         if (ret < 0)
  56                 return ret;
  57 
  58         ret = wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, NULL,
  59                                       sizeof
  60                                       (struct wl12xx_qos_null_data_template));
  61         if (ret < 0)
  62                 return ret;
  63 
  64         ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, NULL,
  65                                       sizeof
  66                                       (struct wl12xx_probe_resp_template));
  67         if (ret < 0)
  68                 return ret;
  69 
  70         ret = wl1251_cmd_template_set(wl, CMD_BEACON, NULL,
  71                                       sizeof
  72                                       (struct wl12xx_beacon_template));
  73         if (ret < 0)
  74                 return ret;
  75 
  76         /* tim templates, first reserve space then allocate an empty one */
  77         memset(partial_vbm, 0, PARTIAL_VBM_MAX);
  78         ret = wl1251_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, PARTIAL_VBM_MAX, 0);
  79         if (ret < 0)
  80                 return ret;
  81 
  82         ret = wl1251_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, 1, 0);
  83         if (ret < 0)
  84                 return ret;
  85 
  86         return 0;
  87 }
  88 
  89 int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter)
  90 {
  91         int ret;
  92 
  93         ret = wl1251_acx_rx_msdu_life_time(wl, RX_MSDU_LIFETIME_DEF);
  94         if (ret < 0)
  95                 return ret;
  96 
  97         ret = wl1251_acx_rx_config(wl, config, filter);
  98         if (ret < 0)
  99                 return ret;
 100 
 101         return 0;
 102 }
 103 
 104 int wl1251_hw_init_phy_config(struct wl1251 *wl)
 105 {
 106         int ret;
 107 
 108         ret = wl1251_acx_pd_threshold(wl);
 109         if (ret < 0)
 110                 return ret;
 111 
 112         ret = wl1251_acx_slot(wl, DEFAULT_SLOT_TIME);
 113         if (ret < 0)
 114                 return ret;
 115 
 116         ret = wl1251_acx_group_address_tbl(wl, true, NULL, 0);
 117         if (ret < 0)
 118                 return ret;
 119 
 120         ret = wl1251_acx_service_period_timeout(wl);
 121         if (ret < 0)
 122                 return ret;
 123 
 124         ret = wl1251_acx_rts_threshold(wl, RTS_THRESHOLD_DEF);
 125         if (ret < 0)
 126                 return ret;
 127 
 128         return 0;
 129 }
 130 
 131 int wl1251_hw_init_beacon_filter(struct wl1251 *wl)
 132 {
 133         int ret;
 134 
 135         /* disable beacon filtering at this stage */
 136         ret = wl1251_acx_beacon_filter_opt(wl, false);
 137         if (ret < 0)
 138                 return ret;
 139 
 140         ret = wl1251_acx_beacon_filter_table(wl);
 141         if (ret < 0)
 142                 return ret;
 143 
 144         return 0;
 145 }
 146 
 147 int wl1251_hw_init_pta(struct wl1251 *wl)
 148 {
 149         int ret;
 150 
 151         ret = wl1251_acx_sg_enable(wl);
 152         if (ret < 0)
 153                 return ret;
 154 
 155         ret = wl1251_acx_sg_cfg(wl);
 156         if (ret < 0)
 157                 return ret;
 158 
 159         return 0;
 160 }
 161 
 162 int wl1251_hw_init_energy_detection(struct wl1251 *wl)
 163 {
 164         int ret;
 165 
 166         ret = wl1251_acx_cca_threshold(wl);
 167         if (ret < 0)
 168                 return ret;
 169 
 170         return 0;
 171 }
 172 
 173 int wl1251_hw_init_beacon_broadcast(struct wl1251 *wl)
 174 {
 175         int ret;
 176 
 177         ret = wl1251_acx_bcn_dtim_options(wl);
 178         if (ret < 0)
 179                 return ret;
 180 
 181         return 0;
 182 }
 183 
 184 int wl1251_hw_init_power_auth(struct wl1251 *wl)
 185 {
 186         return wl1251_acx_sleep_auth(wl, WL1251_PSM_CAM);
 187 }
 188 
 189 int wl1251_hw_init_mem_config(struct wl1251 *wl)
 190 {
 191         int ret;
 192 
 193         ret = wl1251_acx_mem_cfg(wl);
 194         if (ret < 0)
 195                 return ret;
 196 
 197         wl->target_mem_map = kzalloc(sizeof(struct wl1251_acx_mem_map),
 198                                           GFP_KERNEL);
 199         if (!wl->target_mem_map) {
 200                 wl1251_error("couldn't allocate target memory map");
 201                 return -ENOMEM;
 202         }
 203 
 204         /* we now ask for the firmware built memory map */
 205         ret = wl1251_acx_mem_map(wl, wl->target_mem_map,
 206                                  sizeof(struct wl1251_acx_mem_map));
 207         if (ret < 0) {
 208                 wl1251_error("couldn't retrieve firmware memory map");
 209                 kfree(wl->target_mem_map);
 210                 wl->target_mem_map = NULL;
 211                 return ret;
 212         }
 213 
 214         return 0;
 215 }
 216 
 217 static int wl1251_hw_init_txq_fill(u8 qid,
 218                                    struct acx_tx_queue_qos_config *config,
 219                                    u32 num_blocks)
 220 {
 221         config->qid = qid;
 222 
 223         switch (qid) {
 224         case QOS_AC_BE:
 225                 config->high_threshold =
 226                         (QOS_TX_HIGH_BE_DEF * num_blocks) / 100;
 227                 config->low_threshold =
 228                         (QOS_TX_LOW_BE_DEF * num_blocks) / 100;
 229                 break;
 230         case QOS_AC_BK:
 231                 config->high_threshold =
 232                         (QOS_TX_HIGH_BK_DEF * num_blocks) / 100;
 233                 config->low_threshold =
 234                         (QOS_TX_LOW_BK_DEF * num_blocks) / 100;
 235                 break;
 236         case QOS_AC_VI:
 237                 config->high_threshold =
 238                         (QOS_TX_HIGH_VI_DEF * num_blocks) / 100;
 239                 config->low_threshold =
 240                         (QOS_TX_LOW_VI_DEF * num_blocks) / 100;
 241                 break;
 242         case QOS_AC_VO:
 243                 config->high_threshold =
 244                         (QOS_TX_HIGH_VO_DEF * num_blocks) / 100;
 245                 config->low_threshold =
 246                         (QOS_TX_LOW_VO_DEF * num_blocks) / 100;
 247                 break;
 248         default:
 249                 wl1251_error("Invalid TX queue id: %d", qid);
 250                 return -EINVAL;
 251         }
 252 
 253         return 0;
 254 }
 255 
 256 static int wl1251_hw_init_tx_queue_config(struct wl1251 *wl)
 257 {
 258         struct acx_tx_queue_qos_config *config;
 259         struct wl1251_acx_mem_map *wl_mem_map = wl->target_mem_map;
 260         int ret, i;
 261 
 262         wl1251_debug(DEBUG_ACX, "acx tx queue config");
 263 
 264         config = kzalloc(sizeof(*config), GFP_KERNEL);
 265         if (!config) {
 266                 ret = -ENOMEM;
 267                 goto out;
 268         }
 269 
 270         for (i = 0; i < MAX_NUM_OF_AC; i++) {
 271                 ret = wl1251_hw_init_txq_fill(i, config,
 272                                               wl_mem_map->num_tx_mem_blocks);
 273                 if (ret < 0)
 274                         goto out;
 275 
 276                 ret = wl1251_cmd_configure(wl, ACX_TX_QUEUE_CFG,
 277                                            config, sizeof(*config));
 278                 if (ret < 0)
 279                         goto out;
 280         }
 281 
 282         wl1251_acx_ac_cfg(wl, AC_BE, CWMIN_BE, CWMAX_BE, AIFS_DIFS, TXOP_BE);
 283         wl1251_acx_ac_cfg(wl, AC_BK, CWMIN_BK, CWMAX_BK, AIFS_DIFS, TXOP_BK);
 284         wl1251_acx_ac_cfg(wl, AC_VI, CWMIN_VI, CWMAX_VI, AIFS_DIFS, TXOP_VI);
 285         wl1251_acx_ac_cfg(wl, AC_VO, CWMIN_VO, CWMAX_VO, AIFS_DIFS, TXOP_VO);
 286 
 287 out:
 288         kfree(config);
 289         return ret;
 290 }
 291 
 292 static int wl1251_hw_init_data_path_config(struct wl1251 *wl)
 293 {
 294         int ret;
 295 
 296         /* asking for the data path parameters */
 297         wl->data_path = kzalloc(sizeof(struct acx_data_path_params_resp),
 298                                 GFP_KERNEL);
 299         if (!wl->data_path)
 300                 return -ENOMEM;
 301 
 302         ret = wl1251_acx_data_path_params(wl, wl->data_path);
 303         if (ret < 0) {
 304                 kfree(wl->data_path);
 305                 wl->data_path = NULL;
 306                 return ret;
 307         }
 308 
 309         return 0;
 310 }
 311 
 312 
 313 int wl1251_hw_init(struct wl1251 *wl)
 314 {
 315         struct wl1251_acx_mem_map *wl_mem_map;
 316         int ret;
 317 
 318         ret = wl1251_hw_init_hwenc_config(wl);
 319         if (ret < 0)
 320                 return ret;
 321 
 322         /* Template settings */
 323         ret = wl1251_hw_init_templates_config(wl);
 324         if (ret < 0)
 325                 return ret;
 326 
 327         /* Default memory configuration */
 328         ret = wl1251_hw_init_mem_config(wl);
 329         if (ret < 0)
 330                 return ret;
 331 
 332         /* Default data path configuration  */
 333         ret = wl1251_hw_init_data_path_config(wl);
 334         if (ret < 0)
 335                 goto out_free_memmap;
 336 
 337         /* RX config */
 338         ret = wl1251_hw_init_rx_config(wl,
 339                                        RX_CFG_PROMISCUOUS | RX_CFG_TSF,
 340                                        RX_FILTER_OPTION_DEF);
 341         /* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
 342            RX_FILTER_OPTION_FILTER_ALL); */
 343         if (ret < 0)
 344                 goto out_free_data_path;
 345 
 346         /* TX queues config */
 347         ret = wl1251_hw_init_tx_queue_config(wl);
 348         if (ret < 0)
 349                 goto out_free_data_path;
 350 
 351         /* PHY layer config */
 352         ret = wl1251_hw_init_phy_config(wl);
 353         if (ret < 0)
 354                 goto out_free_data_path;
 355 
 356         /* Initialize connection monitoring thresholds */
 357         ret = wl1251_acx_conn_monit_params(wl);
 358         if (ret < 0)
 359                 goto out_free_data_path;
 360 
 361         /* Beacon filtering */
 362         ret = wl1251_hw_init_beacon_filter(wl);
 363         if (ret < 0)
 364                 goto out_free_data_path;
 365 
 366         /* Bluetooth WLAN coexistence */
 367         ret = wl1251_hw_init_pta(wl);
 368         if (ret < 0)
 369                 goto out_free_data_path;
 370 
 371         /* Energy detection */
 372         ret = wl1251_hw_init_energy_detection(wl);
 373         if (ret < 0)
 374                 goto out_free_data_path;
 375 
 376         /* Beacons and boradcast settings */
 377         ret = wl1251_hw_init_beacon_broadcast(wl);
 378         if (ret < 0)
 379                 goto out_free_data_path;
 380 
 381         /* Enable rx data path */
 382         ret = wl1251_cmd_data_path_rx(wl, wl->channel, 1);
 383         if (ret < 0)
 384                 goto out_free_data_path;
 385 
 386         /* Enable tx data path */
 387         ret = wl1251_cmd_data_path_tx(wl, wl->channel, 1);
 388         if (ret < 0)
 389                 goto out_free_data_path;
 390 
 391         /* Default power state */
 392         ret = wl1251_hw_init_power_auth(wl);
 393         if (ret < 0)
 394                 goto out_free_data_path;
 395 
 396         wl_mem_map = wl->target_mem_map;
 397         wl1251_info("%d tx blocks at 0x%x, %d rx blocks at 0x%x",
 398                     wl_mem_map->num_tx_mem_blocks,
 399                     wl->data_path->tx_control_addr,
 400                     wl_mem_map->num_rx_mem_blocks,
 401                     wl->data_path->rx_control_addr);
 402 
 403         return 0;
 404 
 405  out_free_data_path:
 406         kfree(wl->data_path);
 407 
 408  out_free_memmap:
 409         kfree(wl->target_mem_map);
 410 
 411         return ret;
 412 }

/* [<][>][^][v][top][bottom][index][help] */