1 /*- 2 * Copyright (c) 2016 Adrian Chadd <adrian@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13 * redistribution must be conditioned upon including a substantially 14 * similar Disclaimer requirement for further binary redistribution. 15 * 16 * NO WARRANTY 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 /* 34 * This is the top-level N-PHY support for the Broadcom softmac driver. 35 */ 36 37 #include "opt_bwn.h" 38 #include "opt_wlan.h" 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/kernel.h> 43 #include <sys/malloc.h> 44 #include <sys/module.h> 45 #include <sys/endian.h> 46 #include <sys/errno.h> 47 #include <sys/firmware.h> 48 #include <sys/lock.h> 49 #include <sys/mutex.h> 50 #include <machine/bus.h> 51 #include <machine/resource.h> 52 #include <sys/bus.h> 53 #include <sys/rman.h> 54 #include <sys/socket.h> 55 #include <sys/sockio.h> 56 57 #include <net/ethernet.h> 58 #include <net/if.h> 59 #include <net/if_var.h> 60 #include <net/if_arp.h> 61 #include <net/if_dl.h> 62 #include <net/if_llc.h> 63 #include <net/if_media.h> 64 #include <net/if_types.h> 65 66 #include <dev/pci/pcivar.h> 67 #include <dev/pci/pcireg.h> 68 69 #include <net80211/ieee80211_var.h> 70 #include <net80211/ieee80211_radiotap.h> 71 #include <net80211/ieee80211_regdomain.h> 72 #include <net80211/ieee80211_phy.h> 73 #include <net80211/ieee80211_ratectl.h> 74 75 #include <dev/bwn/if_bwn_siba.h> 76 77 #include <dev/bwn/if_bwnreg.h> 78 #include <dev/bwn/if_bwnvar.h> 79 80 #include <dev/bwn/if_bwn_debug.h> 81 #include <dev/bwn/if_bwn_misc.h> 82 #include <dev/bwn/if_bwn_phy_n.h> 83 84 #ifdef BWN_GPL_PHY 85 #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.h> 86 #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.h> 87 #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_core.h> 88 #endif 89 90 /* 91 * This module is always compiled into the kernel, regardless of 92 * whether the GPL PHY is enabled. If the GPL PHY isn't enabled 93 * then it'll just be stubs that will fail to attach. 94 */ 95 96 int 97 bwn_phy_n_attach(struct bwn_mac *mac) 98 { 99 100 #ifdef BWN_GPL_PHY 101 return bwn_nphy_op_allocate(mac); 102 #else 103 device_printf(mac->mac_sc->sc_dev, 104 "%s: BWN_GPL_PHY not in kernel config; " 105 "no PHY-N support\n", __func__); 106 return (ENXIO); 107 #endif 108 } 109 110 void 111 bwn_phy_n_detach(struct bwn_mac *mac) 112 { 113 114 #ifdef BWN_GPL_PHY 115 return bwn_nphy_op_free(mac); 116 #endif 117 } 118 119 int 120 bwn_phy_n_prepare_hw(struct bwn_mac *mac) 121 { 122 123 #ifdef BWN_GPL_PHY 124 bwn_nphy_op_prepare_structs(mac); 125 return (0); 126 #else 127 return (ENXIO); 128 #endif 129 } 130 131 void 132 bwn_phy_n_init_pre(struct bwn_mac *mac) 133 { 134 135 /* XXX TODO */ 136 } 137 138 int 139 bwn_phy_n_init(struct bwn_mac *mac) 140 { 141 #ifdef BWN_GPL_PHY 142 return bwn_nphy_op_init(mac); 143 #else 144 return (ENXIO); 145 #endif 146 } 147 148 void 149 bwn_phy_n_exit(struct bwn_mac *mac) 150 { 151 152 /* XXX TODO */ 153 } 154 155 uint16_t 156 bwn_phy_n_read(struct bwn_mac *mac, uint16_t reg) 157 { 158 159 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 160 return BWN_READ_2(mac, BWN_PHYDATA); 161 } 162 163 void 164 bwn_phy_n_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 165 { 166 167 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 168 BWN_WRITE_2(mac, BWN_PHYDATA, value); 169 } 170 171 uint16_t 172 bwn_phy_n_rf_read(struct bwn_mac *mac, uint16_t reg) 173 { 174 175 /* Register 1 is a 32-bit register. */ 176 if (mac->mac_phy.rev < 7 && reg == 1) { 177 BWN_ERRPRINTF(mac->mac_sc, "%s: bad reg access\n", __func__); 178 } 179 180 if (mac->mac_phy.rev >= 7) 181 reg |= 0x200; /* radio 0x2057 */ 182 else 183 reg |= 0x100; 184 185 BWN_WRITE_2(mac, BWN_RFCTL, reg); 186 return BWN_READ_2(mac, BWN_RFDATALO); 187 } 188 189 void 190 bwn_phy_n_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 191 { 192 193 /* Register 1 is a 32-bit register. */ 194 if (mac->mac_phy.rev < 7 && reg == 1) { 195 BWN_ERRPRINTF(mac->mac_sc, "%s: bad reg access\n", __func__); 196 } 197 198 BWN_WRITE_2(mac, BWN_RFCTL, reg); 199 BWN_WRITE_2(mac, BWN_RFDATALO, value); 200 } 201 202 int 203 bwn_phy_n_hwpctl(struct bwn_mac *mac) 204 { 205 206 return (0); 207 } 208 209 void 210 bwn_phy_n_rf_onoff(struct bwn_mac *mac, int on) 211 { 212 #ifdef BWN_GPL_PHY 213 bwn_nphy_op_software_rfkill(mac, on); 214 #endif 215 } 216 217 void 218 bwn_phy_n_switch_analog(struct bwn_mac *mac, int on) 219 { 220 #ifdef BWN_GPL_PHY 221 bwn_nphy_op_switch_analog(mac, on); 222 #endif 223 } 224 225 int 226 bwn_phy_n_switch_channel(struct bwn_mac *mac, uint32_t newchan) 227 { 228 #ifdef BWN_GPL_PHY 229 return bwn_nphy_op_switch_channel(mac, newchan); 230 #else 231 return (ENXIO); 232 #endif 233 } 234 235 uint32_t 236 bwn_phy_n_get_default_chan(struct bwn_mac *mac) 237 { 238 239 if (bwn_current_band(mac) == BWN_BAND_2G) 240 return (1); 241 return (36); 242 } 243 244 void 245 bwn_phy_n_set_antenna(struct bwn_mac *mac, int antenna) 246 { 247 /* XXX TODO */ 248 } 249 250 int 251 bwn_phy_n_im(struct bwn_mac *mac, int mode) 252 { 253 /* XXX TODO */ 254 return (0); 255 } 256 257 bwn_txpwr_result_t 258 bwn_phy_n_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 259 { 260 #ifdef BWN_GPL_PHY 261 return bwn_nphy_op_recalc_txpower(mac, ignore_tssi); 262 #else 263 return (BWN_TXPWR_RES_DONE); 264 #endif 265 } 266 267 void 268 bwn_phy_n_set_txpwr(struct bwn_mac *mac) 269 { 270 271 } 272 273 void 274 bwn_phy_n_task_15s(struct bwn_mac *mac) 275 { 276 277 } 278 279 void 280 bwn_phy_n_task_60s(struct bwn_mac *mac) 281 { 282 283 } 284