Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2010 Broadcom Corporation |
| 3 | * |
| 4 | * Permission to use, copy, modify, and/or distribute this software for any |
| 5 | * purpose with or without fee is hereby granted, provided that the above |
| 6 | * copyright notice and this permission notice appear in all copies. |
| 7 | * |
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
| 11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
| 13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
| 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 15 | */ |
| 16 | |
| 17 | #include <wlc_cfg.h> |
| 18 | |
| 19 | #ifdef WLANTSEL |
| 20 | |
Brett Rudley | 3327989 | 2010-10-01 18:03:27 -0700 | [diff] [blame] | 21 | #include <linux/kernel.h> |
| 22 | #include <linuxver.h> |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 23 | #include <bcmdefs.h> |
| 24 | #include <osl.h> |
| 25 | #include <bcmutils.h> |
| 26 | #include <siutils.h> |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 27 | #include <wlioctl.h> |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 28 | |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 29 | #include <d11.h> |
| 30 | #include <wlc_rate.h> |
| 31 | #include <wlc_key.h> |
| 32 | #include <wlc_pub.h> |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 33 | #include <wl_dbg.h> |
| 34 | #include <wlc_mac80211.h> |
| 35 | #include <wlc_bmac.h> |
| 36 | #include <wlc_phy_hal.h> |
| 37 | #include <wl_export.h> |
| 38 | #include <wlc_antsel.h> |
| 39 | #include <wlc_phy_shim.h> |
| 40 | |
| 41 | /* useful macros */ |
| 42 | #define WLC_ANTSEL_11N_0(ant) ((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf) |
| 43 | #define WLC_ANTSEL_11N_1(ant) (((ant) & ANT_SELCFG_MASK) & 0xf) |
| 44 | #define WLC_ANTIDX_11N(ant) (((WLC_ANTSEL_11N_0(ant)) << 2) + (WLC_ANTSEL_11N_1(ant))) |
| 45 | #define WLC_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) |
| 46 | #define WLC_ANTSEL_11N(ant) ((ant) & ANT_SELCFG_MASK) |
| 47 | |
| 48 | /* antenna switch */ |
| 49 | /* defines for no boardlevel antenna diversity */ |
| 50 | #define ANT_SELCFG_DEF_2x2 0x01 /* default antenna configuration */ |
| 51 | |
| 52 | /* 2x3 antdiv defines and tables for GPIO communication */ |
| 53 | #define ANT_SELCFG_NUM_2x3 3 |
| 54 | #define ANT_SELCFG_DEF_2x3 0x01 /* default antenna configuration */ |
| 55 | |
| 56 | /* 2x4 antdiv rev4 defines and tables for GPIO communication */ |
| 57 | #define ANT_SELCFG_NUM_2x4 4 |
| 58 | #define ANT_SELCFG_DEF_2x4 0x02 /* default antenna configuration */ |
| 59 | |
| 60 | /* static functions */ |
Jason Cooper | 7cc4a4c | 2010-09-14 09:45:30 -0400 | [diff] [blame] | 61 | static int wlc_antsel_cfgupd(antsel_info_t *asi, wlc_antselcfg_t *antsel); |
Greg Kroah-Hartman | 41feb5e | 2010-10-05 10:09:00 -0700 | [diff] [blame] | 62 | static u8 wlc_antsel_id2antcfg(antsel_info_t *asi, u8 id); |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 63 | static u16 wlc_antsel_antcfg2antsel(antsel_info_t *asi, u8 ant_cfg); |
Jason Cooper | 7cc4a4c | 2010-09-14 09:45:30 -0400 | [diff] [blame] | 64 | static void wlc_antsel_init_cfg(antsel_info_t *asi, wlc_antselcfg_t *antsel, |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 65 | bool auto_sel); |
| 66 | |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 67 | const u16 mimo_2x4_div_antselpat_tbl[] = { |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 68 | 0, 0, 0x9, 0xa, /* ant0: 0 ant1: 2,3 */ |
| 69 | 0, 0, 0x5, 0x6, /* ant0: 1 ant1: 2,3 */ |
| 70 | 0, 0, 0, 0, /* n.a. */ |
| 71 | 0, 0, 0, 0 /* n.a. */ |
| 72 | }; |
| 73 | |
Greg Kroah-Hartman | 41feb5e | 2010-10-05 10:09:00 -0700 | [diff] [blame] | 74 | const u8 mimo_2x4_div_antselid_tbl[16] = { |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 75 | 0, 0, 0, 0, 0, 2, 3, 0, |
| 76 | 0, 0, 1, 0, 0, 0, 0, 0 /* pat to antselid */ |
| 77 | }; |
| 78 | |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 79 | const u16 mimo_2x3_div_antselpat_tbl[] = { |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 80 | 16, 0, 1, 16, /* ant0: 0 ant1: 1,2 */ |
| 81 | 16, 16, 16, 16, /* n.a. */ |
| 82 | 16, 2, 16, 16, /* ant0: 2 ant1: 1 */ |
| 83 | 16, 16, 16, 16 /* n.a. */ |
| 84 | }; |
| 85 | |
Greg Kroah-Hartman | 41feb5e | 2010-10-05 10:09:00 -0700 | [diff] [blame] | 86 | const u8 mimo_2x3_div_antselid_tbl[16] = { |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 87 | 0, 1, 2, 0, 0, 0, 0, 0, |
| 88 | 0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */ |
| 89 | }; |
| 90 | |
Jason Cooper | a9d0fff | 2010-10-11 10:03:00 -0400 | [diff] [blame] | 91 | antsel_info_t *wlc_antsel_attach(wlc_info_t *wlc, osl_t *osh, |
Jason Cooper | 7cc4a4c | 2010-09-14 09:45:30 -0400 | [diff] [blame] | 92 | wlc_pub_t *pub, |
| 93 | wlc_hw_info_t *wlc_hw) { |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 94 | antsel_info_t *asi; |
| 95 | |
mike.rapoport@gmail.com | 5fcc1fc | 2010-10-13 00:09:10 +0200 | [diff] [blame] | 96 | asi = kzalloc(sizeof(antsel_info_t), GFP_ATOMIC); |
Jason Cooper | ca8c1e5 | 2010-09-14 09:45:33 -0400 | [diff] [blame] | 97 | if (!asi) { |
mike.rapoport@gmail.com | 97e17d0 | 2010-10-13 00:09:09 +0200 | [diff] [blame] | 98 | WL_ERROR(("wl%d: wlc_antsel_attach: out of mem\n", pub->unit)); |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 99 | return NULL; |
| 100 | } |
| 101 | |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 102 | asi->wlc = wlc; |
| 103 | asi->pub = pub; |
| 104 | asi->antsel_type = ANTSEL_NA; |
Greg Kroah-Hartman | 0965ae8 | 2010-10-12 12:50:15 -0700 | [diff] [blame] | 105 | asi->antsel_avail = false; |
Greg Kroah-Hartman | 41feb5e | 2010-10-05 10:09:00 -0700 | [diff] [blame] | 106 | asi->antsel_antswitch = (u8) getintvar(asi->pub->vars, "antswitch"); |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 107 | |
| 108 | if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) { |
| 109 | switch (asi->antsel_antswitch) { |
| 110 | case ANTSWITCH_TYPE_1: |
| 111 | case ANTSWITCH_TYPE_2: |
| 112 | case ANTSWITCH_TYPE_3: |
| 113 | /* 4321/2 board with 2x3 switch logic */ |
| 114 | asi->antsel_type = ANTSEL_2x3; |
| 115 | /* Antenna selection availability */ |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 116 | if (((u16) getintvar(asi->pub->vars, "aa2g") == 7) || |
| 117 | ((u16) getintvar(asi->pub->vars, "aa5g") == 7)) { |
Greg Kroah-Hartman | 0f0881b | 2010-10-12 12:15:18 -0700 | [diff] [blame] | 118 | asi->antsel_avail = true; |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 119 | } else |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 120 | if (((u16) getintvar(asi->pub->vars, "aa2g") == |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 121 | 3) |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 122 | || ((u16) getintvar(asi->pub->vars, "aa5g") |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 123 | == 3)) { |
Greg Kroah-Hartman | 0965ae8 | 2010-10-12 12:50:15 -0700 | [diff] [blame] | 124 | asi->antsel_avail = false; |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 125 | } else { |
Greg Kroah-Hartman | 0965ae8 | 2010-10-12 12:50:15 -0700 | [diff] [blame] | 126 | asi->antsel_avail = false; |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 127 | WL_ERROR(("wlc_antsel_attach: 2o3 board cfg invalid\n")); |
| 128 | ASSERT(0); |
| 129 | } |
| 130 | break; |
| 131 | default: |
| 132 | break; |
| 133 | } |
| 134 | } else if ((asi->pub->sromrev == 4) && |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 135 | ((u16) getintvar(asi->pub->vars, "aa2g") == 7) && |
| 136 | ((u16) getintvar(asi->pub->vars, "aa5g") == 0)) { |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 137 | /* hack to match old 4321CB2 cards with 2of3 antenna switch */ |
| 138 | asi->antsel_type = ANTSEL_2x3; |
Greg Kroah-Hartman | 0f0881b | 2010-10-12 12:15:18 -0700 | [diff] [blame] | 139 | asi->antsel_avail = true; |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 140 | } else if (asi->pub->boardflags2 & BFL2_2X4_DIV) { |
| 141 | asi->antsel_type = ANTSEL_2x4; |
Greg Kroah-Hartman | 0f0881b | 2010-10-12 12:15:18 -0700 | [diff] [blame] | 142 | asi->antsel_avail = true; |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 143 | } |
| 144 | |
| 145 | /* Set the antenna selection type for the low driver */ |
| 146 | wlc_bmac_antsel_type_set(wlc_hw, asi->antsel_type); |
| 147 | |
| 148 | /* Init (auto/manual) antenna selection */ |
Greg Kroah-Hartman | 0f0881b | 2010-10-12 12:15:18 -0700 | [diff] [blame] | 149 | wlc_antsel_init_cfg(asi, &asi->antcfg_11n, true); |
| 150 | wlc_antsel_init_cfg(asi, &asi->antcfg_cur, true); |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 151 | |
| 152 | return asi; |
| 153 | } |
| 154 | |
Greg Kroah-Hartman | 0d2f072 | 2010-10-08 14:28:21 -0700 | [diff] [blame] | 155 | void wlc_antsel_detach(antsel_info_t *asi) |
Jason Cooper | a2627bc | 2010-09-14 09:45:31 -0400 | [diff] [blame] | 156 | { |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 157 | if (!asi) |
| 158 | return; |
| 159 | |
mike.rapoport@gmail.com | 182acb3 | 2010-10-13 00:09:12 +0200 | [diff] [blame] | 160 | kfree(asi); |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 161 | } |
| 162 | |
Jason Cooper | 7cc4a4c | 2010-09-14 09:45:30 -0400 | [diff] [blame] | 163 | void wlc_antsel_init(antsel_info_t *asi) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 164 | { |
| 165 | if ((asi->antsel_type == ANTSEL_2x3) || |
| 166 | (asi->antsel_type == ANTSEL_2x4)) |
| 167 | wlc_antsel_cfgupd(asi, &asi->antcfg_11n); |
| 168 | } |
| 169 | |
| 170 | /* boardlevel antenna selection: init antenna selection structure */ |
| 171 | static void |
Jason Cooper | 7cc4a4c | 2010-09-14 09:45:30 -0400 | [diff] [blame] | 172 | wlc_antsel_init_cfg(antsel_info_t *asi, wlc_antselcfg_t *antsel, |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 173 | bool auto_sel) |
| 174 | { |
| 175 | if (asi->antsel_type == ANTSEL_2x3) { |
Greg Kroah-Hartman | 41feb5e | 2010-10-05 10:09:00 -0700 | [diff] [blame] | 176 | u8 antcfg_def = ANT_SELCFG_DEF_2x3 | |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 177 | ((asi->antsel_avail && auto_sel) ? ANT_SELCFG_AUTO : 0); |
| 178 | antsel->ant_config[ANT_SELCFG_TX_DEF] = antcfg_def; |
| 179 | antsel->ant_config[ANT_SELCFG_TX_UNICAST] = antcfg_def; |
| 180 | antsel->ant_config[ANT_SELCFG_RX_DEF] = antcfg_def; |
| 181 | antsel->ant_config[ANT_SELCFG_RX_UNICAST] = antcfg_def; |
| 182 | antsel->num_antcfg = ANT_SELCFG_NUM_2x3; |
| 183 | |
| 184 | } else if (asi->antsel_type == ANTSEL_2x4) { |
| 185 | |
| 186 | antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x4; |
| 187 | antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x4; |
| 188 | antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x4; |
| 189 | antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x4; |
| 190 | antsel->num_antcfg = ANT_SELCFG_NUM_2x4; |
| 191 | |
| 192 | } else { /* no antenna selection available */ |
| 193 | |
| 194 | antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x2; |
| 195 | antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x2; |
| 196 | antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x2; |
| 197 | antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x2; |
| 198 | antsel->num_antcfg = 0; |
| 199 | } |
| 200 | } |
| 201 | |
| 202 | void BCMFASTPATH |
Jason Cooper | 7cc4a4c | 2010-09-14 09:45:30 -0400 | [diff] [blame] | 203 | wlc_antsel_antcfg_get(antsel_info_t *asi, bool usedef, bool sel, |
Greg Kroah-Hartman | 41feb5e | 2010-10-05 10:09:00 -0700 | [diff] [blame] | 204 | u8 antselid, u8 fbantselid, u8 *antcfg, |
| 205 | u8 *fbantcfg) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 206 | { |
Greg Kroah-Hartman | 41feb5e | 2010-10-05 10:09:00 -0700 | [diff] [blame] | 207 | u8 ant; |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 208 | |
| 209 | /* if use default, assign it and return */ |
| 210 | if (usedef) { |
| 211 | *antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_DEF]; |
| 212 | *fbantcfg = *antcfg; |
| 213 | return; |
| 214 | } |
| 215 | |
| 216 | if (!sel) { |
| 217 | *antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST]; |
| 218 | *fbantcfg = *antcfg; |
| 219 | |
| 220 | } else { |
| 221 | ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST]; |
| 222 | if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) { |
| 223 | *antcfg = wlc_antsel_id2antcfg(asi, antselid); |
| 224 | *fbantcfg = wlc_antsel_id2antcfg(asi, fbantselid); |
| 225 | } else { |
| 226 | *antcfg = |
| 227 | asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST]; |
| 228 | *fbantcfg = *antcfg; |
| 229 | } |
| 230 | } |
| 231 | return; |
| 232 | } |
| 233 | |
| 234 | /* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */ |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 235 | u8 wlc_antsel_antsel2id(antsel_info_t *asi, u16 antsel) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 236 | { |
Greg Kroah-Hartman | 41feb5e | 2010-10-05 10:09:00 -0700 | [diff] [blame] | 237 | u8 antselid = 0; |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 238 | |
| 239 | if (asi->antsel_type == ANTSEL_2x4) { |
| 240 | /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */ |
| 241 | antselid = mimo_2x4_div_antselid_tbl[(antsel & 0xf)]; |
| 242 | return antselid; |
| 243 | |
| 244 | } else if (asi->antsel_type == ANTSEL_2x3) { |
| 245 | /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */ |
| 246 | antselid = mimo_2x3_div_antselid_tbl[(antsel & 0xf)]; |
| 247 | return antselid; |
| 248 | } |
| 249 | |
| 250 | return antselid; |
| 251 | } |
| 252 | |
| 253 | /* boardlevel antenna selection: convert id to ant_cfg */ |
Greg Kroah-Hartman | 41feb5e | 2010-10-05 10:09:00 -0700 | [diff] [blame] | 254 | static u8 wlc_antsel_id2antcfg(antsel_info_t *asi, u8 id) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 255 | { |
Greg Kroah-Hartman | 41feb5e | 2010-10-05 10:09:00 -0700 | [diff] [blame] | 256 | u8 antcfg = ANT_SELCFG_DEF_2x2; |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 257 | |
| 258 | if (asi->antsel_type == ANTSEL_2x4) { |
| 259 | /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */ |
| 260 | antcfg = (((id & 0x2) << 3) | ((id & 0x1) + 2)); |
| 261 | return antcfg; |
| 262 | |
| 263 | } else if (asi->antsel_type == ANTSEL_2x3) { |
| 264 | /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */ |
| 265 | antcfg = (((id & 0x02) << 4) | ((id & 0x1) + 1)); |
| 266 | return antcfg; |
| 267 | } |
| 268 | |
| 269 | return antcfg; |
| 270 | } |
| 271 | |
| 272 | /* boardlevel antenna selection: convert ant_cfg to mimo_antsel (ucode interface) */ |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 273 | static u16 wlc_antsel_antcfg2antsel(antsel_info_t *asi, u8 ant_cfg) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 274 | { |
Greg Kroah-Hartman | 41feb5e | 2010-10-05 10:09:00 -0700 | [diff] [blame] | 275 | u8 idx = WLC_ANTIDX_11N(WLC_ANTSEL_11N(ant_cfg)); |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 276 | u16 mimo_antsel = 0; |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 277 | |
| 278 | if (asi->antsel_type == ANTSEL_2x4) { |
| 279 | /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */ |
| 280 | mimo_antsel = (mimo_2x4_div_antselpat_tbl[idx] & 0xf); |
| 281 | return mimo_antsel; |
| 282 | |
| 283 | } else if (asi->antsel_type == ANTSEL_2x3) { |
| 284 | /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */ |
| 285 | mimo_antsel = (mimo_2x3_div_antselpat_tbl[idx] & 0xf); |
| 286 | return mimo_antsel; |
| 287 | } |
| 288 | |
| 289 | return mimo_antsel; |
| 290 | } |
| 291 | |
| 292 | /* boardlevel antenna selection: ucode interface control */ |
Jason Cooper | 7cc4a4c | 2010-09-14 09:45:30 -0400 | [diff] [blame] | 293 | static int wlc_antsel_cfgupd(antsel_info_t *asi, wlc_antselcfg_t *antsel) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 294 | { |
| 295 | wlc_info_t *wlc = asi->wlc; |
Greg Kroah-Hartman | 41feb5e | 2010-10-05 10:09:00 -0700 | [diff] [blame] | 296 | u8 ant_cfg; |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 297 | u16 mimo_antsel; |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 298 | |
| 299 | ASSERT(asi->antsel_type != ANTSEL_NA); |
| 300 | |
| 301 | /* 1) Update TX antconfig for all frames that are not unicast data |
| 302 | * (aka default TX) |
| 303 | */ |
| 304 | ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF]; |
| 305 | mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg); |
| 306 | wlc_write_shm(wlc, M_MIMO_ANTSEL_TXDFLT, mimo_antsel); |
| 307 | /* Update driver stats for currently selected default tx/rx antenna config */ |
| 308 | asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg; |
| 309 | |
| 310 | /* 2) Update RX antconfig for all frames that are not unicast data |
| 311 | * (aka default RX) |
| 312 | */ |
| 313 | ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF]; |
| 314 | mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg); |
| 315 | wlc_write_shm(wlc, M_MIMO_ANTSEL_RXDFLT, mimo_antsel); |
| 316 | /* Update driver stats for currently selected default tx/rx antenna config */ |
| 317 | asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg; |
| 318 | |
| 319 | return 0; |
| 320 | } |
| 321 | |
| 322 | #endif /* WLANTSEL */ |