Arend van Spriel | 5b435de | 2011-10-05 13:19:03 +0200 | [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 | */ |
Joe Perches | 02f7719 | 2012-01-15 00:38:44 -0800 | [diff] [blame] | 16 | |
Arend van Spriel | 5b435de | 2011-10-05 13:19:03 +0200 | [diff] [blame] | 17 | #include <linux/kernel.h> |
| 18 | #include <linux/string.h> |
Arend van Spriel | 5b435de | 2011-10-05 13:19:03 +0200 | [diff] [blame] | 19 | #include <linux/netdevice.h> |
Arend van Spriel | 5b435de | 2011-10-05 13:19:03 +0200 | [diff] [blame] | 20 | #include <brcmu_wifi.h> |
| 21 | #include <brcmu_utils.h> |
Hante Meuleman | 122d3d0 | 2014-10-28 14:56:18 +0100 | [diff] [blame] | 22 | #include "core.h" |
Hante Meuleman | d14f78b | 2014-10-28 14:56:14 +0100 | [diff] [blame] | 23 | #include "bus.h" |
Hante Meuleman | a8e8ed3 | 2014-10-28 14:56:13 +0100 | [diff] [blame] | 24 | #include "debug.h" |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 25 | #include "fwil.h" |
Arend van Spriel | 6f5838a | 2013-11-29 12:25:19 +0100 | [diff] [blame] | 26 | #include "fwil_types.h" |
Arend van Spriel | e548357 | 2013-03-03 12:45:21 +0100 | [diff] [blame] | 27 | #include "tracepoint.h" |
Hante Meuleman | 6b89dcb | 2014-12-21 12:43:52 +0100 | [diff] [blame] | 28 | #include "common.h" |
| 29 | |
| 30 | const u8 ALLFFMAC[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
Arend van Spriel | 5b435de | 2011-10-05 13:19:03 +0200 | [diff] [blame] | 31 | |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 32 | #define BRCMF_DEFAULT_BCN_TIMEOUT 3 |
| 33 | #define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40 |
| 34 | #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 |
Arend van Spriel | 5b435de | 2011-10-05 13:19:03 +0200 | [diff] [blame] | 35 | |
Daniel Kim | e09cc63 | 2014-05-12 10:47:26 +0200 | [diff] [blame] | 36 | /* boost value for RSSI_DELTA in preferred join selection */ |
| 37 | #define BRCMF_JOIN_PREF_RSSI_BOOST 8 |
| 38 | |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 39 | int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) |
Arend van Spriel | 5b435de | 2011-10-05 13:19:03 +0200 | [diff] [blame] | 40 | { |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 41 | s8 eventmask[BRCMF_EVENTING_MASK_LEN]; |
| 42 | u8 buf[BRCMF_DCMD_SMLEN]; |
Daniel Kim | e09cc63 | 2014-05-12 10:47:26 +0200 | [diff] [blame] | 43 | struct brcmf_join_pref_params join_pref_params[2]; |
Arend van Spriel | 4862290 | 2015-01-25 20:31:40 +0100 | [diff] [blame] | 44 | struct brcmf_rev_info_le revinfo; |
| 45 | struct brcmf_rev_info *ri; |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 46 | char *ptr; |
| 47 | s32 err; |
Arend van Spriel | 5b435de | 2011-10-05 13:19:03 +0200 | [diff] [blame] | 48 | |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 49 | /* retreive mac address */ |
| 50 | err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr, |
| 51 | sizeof(ifp->mac_addr)); |
| 52 | if (err < 0) { |
Arend van Spriel | 4862290 | 2015-01-25 20:31:40 +0100 | [diff] [blame] | 53 | brcmf_err("Retreiving cur_etheraddr failed, %d\n", err); |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 54 | goto done; |
Arend van Spriel | 5b435de | 2011-10-05 13:19:03 +0200 | [diff] [blame] | 55 | } |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 56 | memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac)); |
Arend van Spriel | 5b435de | 2011-10-05 13:19:03 +0200 | [diff] [blame] | 57 | |
Arend van Spriel | 4862290 | 2015-01-25 20:31:40 +0100 | [diff] [blame] | 58 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_REVINFO, |
| 59 | &revinfo, sizeof(revinfo)); |
Arend van Spriel | 7f52c81 | 2015-01-25 20:31:42 +0100 | [diff] [blame] | 60 | ri = &ifp->drvr->revinfo; |
Arend van Spriel | 4862290 | 2015-01-25 20:31:40 +0100 | [diff] [blame] | 61 | if (err < 0) { |
| 62 | brcmf_err("retrieving revision info failed, %d\n", err); |
| 63 | } else { |
Arend van Spriel | 4862290 | 2015-01-25 20:31:40 +0100 | [diff] [blame] | 64 | ri->vendorid = le32_to_cpu(revinfo.vendorid); |
| 65 | ri->deviceid = le32_to_cpu(revinfo.deviceid); |
| 66 | ri->radiorev = le32_to_cpu(revinfo.radiorev); |
| 67 | ri->chiprev = le32_to_cpu(revinfo.chiprev); |
| 68 | ri->corerev = le32_to_cpu(revinfo.corerev); |
| 69 | ri->boardid = le32_to_cpu(revinfo.boardid); |
| 70 | ri->boardvendor = le32_to_cpu(revinfo.boardvendor); |
| 71 | ri->boardrev = le32_to_cpu(revinfo.boardrev); |
| 72 | ri->driverrev = le32_to_cpu(revinfo.driverrev); |
| 73 | ri->ucoderev = le32_to_cpu(revinfo.ucoderev); |
| 74 | ri->bus = le32_to_cpu(revinfo.bus); |
| 75 | ri->chipnum = le32_to_cpu(revinfo.chipnum); |
| 76 | ri->phytype = le32_to_cpu(revinfo.phytype); |
| 77 | ri->phyrev = le32_to_cpu(revinfo.phyrev); |
| 78 | ri->anarev = le32_to_cpu(revinfo.anarev); |
| 79 | ri->chippkg = le32_to_cpu(revinfo.chippkg); |
| 80 | ri->nvramrev = le32_to_cpu(revinfo.nvramrev); |
| 81 | } |
Arend van Spriel | 7f52c81 | 2015-01-25 20:31:42 +0100 | [diff] [blame] | 82 | ri->result = err; |
Arend van Spriel | 4862290 | 2015-01-25 20:31:40 +0100 | [diff] [blame] | 83 | |
Arend van Spriel | 5b435de | 2011-10-05 13:19:03 +0200 | [diff] [blame] | 84 | /* query for 'ver' to get version info from firmware */ |
| 85 | memset(buf, 0, sizeof(buf)); |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 86 | strcpy(buf, "ver"); |
| 87 | err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf)); |
| 88 | if (err < 0) { |
Arend van Spriel | 5e8149f | 2012-12-07 10:49:57 +0100 | [diff] [blame] | 89 | brcmf_err("Retreiving version information failed, %d\n", |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 90 | err); |
| 91 | goto done; |
| 92 | } |
| 93 | ptr = (char *)buf; |
Arend van Spriel | 5b435de | 2011-10-05 13:19:03 +0200 | [diff] [blame] | 94 | strsep(&ptr, "\n"); |
Arend van Spriel | 55685b8 | 2013-11-29 12:25:17 +0100 | [diff] [blame] | 95 | |
Arend van Spriel | 5b435de | 2011-10-05 13:19:03 +0200 | [diff] [blame] | 96 | /* Print fw version info */ |
Arend van Spriel | 5e8149f | 2012-12-07 10:49:57 +0100 | [diff] [blame] | 97 | brcmf_err("Firmware version = %s\n", buf); |
Arend van Spriel | 5b435de | 2011-10-05 13:19:03 +0200 | [diff] [blame] | 98 | |
Arend van Spriel | 55685b8 | 2013-11-29 12:25:17 +0100 | [diff] [blame] | 99 | /* locate firmware version number for ethtool */ |
| 100 | ptr = strrchr(buf, ' ') + 1; |
| 101 | strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver)); |
| 102 | |
Daniel Kim | 5e787f7 | 2014-06-21 12:11:18 +0200 | [diff] [blame] | 103 | /* set mpc */ |
| 104 | err = brcmf_fil_iovar_int_set(ifp, "mpc", 1); |
| 105 | if (err) { |
| 106 | brcmf_err("failed setting mpc\n"); |
| 107 | goto done; |
| 108 | } |
| 109 | |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 110 | /* |
| 111 | * Setup timeout if Beacons are lost and roam is off to report |
| 112 | * link down |
| 113 | */ |
| 114 | err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", |
| 115 | BRCMF_DEFAULT_BCN_TIMEOUT); |
| 116 | if (err) { |
Arend van Spriel | 5e8149f | 2012-12-07 10:49:57 +0100 | [diff] [blame] | 117 | brcmf_err("bcn_timeout error (%d)\n", err); |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 118 | goto done; |
Arend van Spriel | 5b435de | 2011-10-05 13:19:03 +0200 | [diff] [blame] | 119 | } |
| 120 | |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 121 | /* Enable/Disable build-in roaming to allowed ext supplicant to take |
| 122 | * of romaing |
| 123 | */ |
| 124 | err = brcmf_fil_iovar_int_set(ifp, "roam_off", 1); |
| 125 | if (err) { |
Arend van Spriel | 5e8149f | 2012-12-07 10:49:57 +0100 | [diff] [blame] | 126 | brcmf_err("roam_off error (%d)\n", err); |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 127 | goto done; |
| 128 | } |
| 129 | |
Daniel Kim | e09cc63 | 2014-05-12 10:47:26 +0200 | [diff] [blame] | 130 | /* Setup join_pref to select target by RSSI(with boost on 5GHz) */ |
| 131 | join_pref_params[0].type = BRCMF_JOIN_PREF_RSSI_DELTA; |
| 132 | join_pref_params[0].len = 2; |
| 133 | join_pref_params[0].rssi_gain = BRCMF_JOIN_PREF_RSSI_BOOST; |
| 134 | join_pref_params[0].band = WLC_BAND_5G; |
| 135 | join_pref_params[1].type = BRCMF_JOIN_PREF_RSSI; |
| 136 | join_pref_params[1].len = 2; |
| 137 | join_pref_params[1].rssi_gain = 0; |
| 138 | join_pref_params[1].band = 0; |
| 139 | err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params, |
| 140 | sizeof(join_pref_params)); |
| 141 | if (err) |
| 142 | brcmf_err("Set join_pref error (%d)\n", err); |
| 143 | |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 144 | /* Setup event_msgs, enable E_IF */ |
| 145 | err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask, |
| 146 | BRCMF_EVENTING_MASK_LEN); |
| 147 | if (err) { |
Arend van Spriel | 5e8149f | 2012-12-07 10:49:57 +0100 | [diff] [blame] | 148 | brcmf_err("Get event_msgs error (%d)\n", err); |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 149 | goto done; |
| 150 | } |
| 151 | setbit(eventmask, BRCMF_E_IF); |
| 152 | err = brcmf_fil_iovar_data_set(ifp, "event_msgs", eventmask, |
| 153 | BRCMF_EVENTING_MASK_LEN); |
| 154 | if (err) { |
Arend van Spriel | 5e8149f | 2012-12-07 10:49:57 +0100 | [diff] [blame] | 155 | brcmf_err("Set event_msgs error (%d)\n", err); |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 156 | goto done; |
| 157 | } |
| 158 | |
| 159 | /* Setup default scan channel time */ |
| 160 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME, |
| 161 | BRCMF_DEFAULT_SCAN_CHANNEL_TIME); |
| 162 | if (err) { |
Arend van Spriel | 5e8149f | 2012-12-07 10:49:57 +0100 | [diff] [blame] | 163 | brcmf_err("BRCMF_C_SET_SCAN_CHANNEL_TIME error (%d)\n", |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 164 | err); |
| 165 | goto done; |
| 166 | } |
| 167 | |
| 168 | /* Setup default scan unassoc time */ |
| 169 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME, |
| 170 | BRCMF_DEFAULT_SCAN_UNASSOC_TIME); |
| 171 | if (err) { |
Arend van Spriel | 5e8149f | 2012-12-07 10:49:57 +0100 | [diff] [blame] | 172 | brcmf_err("BRCMF_C_SET_SCAN_UNASSOC_TIME error (%d)\n", |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 173 | err); |
| 174 | goto done; |
| 175 | } |
| 176 | |
Arend van Spriel | cf45828 | 2013-11-29 11:48:15 +0100 | [diff] [blame] | 177 | /* do bus specific preinit here */ |
| 178 | err = brcmf_bus_preinit(ifp->drvr->bus_if); |
Hante Meuleman | 0af29bf | 2012-10-22 10:36:25 -0700 | [diff] [blame] | 179 | done: |
| 180 | return err; |
Arend van Spriel | 5b435de | 2011-10-05 13:19:03 +0200 | [diff] [blame] | 181 | } |
Arend van Spriel | e548357 | 2013-03-03 12:45:21 +0100 | [diff] [blame] | 182 | |
Arend van Spriel | e548357 | 2013-03-03 12:45:21 +0100 | [diff] [blame] | 183 | #if defined(CONFIG_BRCM_TRACING) || defined(CONFIG_BRCMDBG) |
| 184 | void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...) |
| 185 | { |
| 186 | struct va_format vaf = { |
| 187 | .fmt = fmt, |
| 188 | }; |
| 189 | va_list args; |
| 190 | |
| 191 | va_start(args, fmt); |
| 192 | vaf.va = &args; |
| 193 | if (brcmf_msg_level & level) |
| 194 | pr_debug("%s %pV", func, &vaf); |
| 195 | trace_brcmf_dbg(level, func, &vaf); |
| 196 | va_end(args); |
| 197 | } |
| 198 | #endif |