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 #include <dev/siba/siba_ids.h> 69 #include <dev/siba/sibareg.h> 70 #include <dev/siba/sibavar.h> 71 72 #include <net80211/ieee80211_var.h> 73 #include <net80211/ieee80211_radiotap.h> 74 #include <net80211/ieee80211_regdomain.h> 75 #include <net80211/ieee80211_phy.h> 76 #include <net80211/ieee80211_ratectl.h> 77 78 #include <dev/bwn/if_bwnreg.h> 79 #include <dev/bwn/if_bwnvar.h> 80 81 #include <dev/bwn/if_bwn_debug.h> 82 #include <dev/bwn/if_bwn_misc.h> 83 #include <dev/bwn/if_bwn_phy_n.h> 84 85 #ifdef BWN_GPL_PHY 86 #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.h> 87 #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.h> 88 #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_core.h> 89 #endif 90 91 /* 92 * This module is always compiled into the kernel, regardless of 93 * whether the GPL PHY is enabled. If the GPL PHY isn't enabled 94 * then it'll just be stubs that will fail to attach. 95 */ 96 97 int 98 bwn_phy_n_attach(struct bwn_mac *mac) 99 { 100 101 #ifdef BWN_GPL_PHY 102 return bwn_nphy_op_allocate(mac); 103 #else 104 return (ENXIO); 105 #endif 106 } 107 108 void 109 bwn_phy_n_detach(struct bwn_mac *mac) 110 { 111 112 #ifdef BWN_GPL_PHY 113 return bwn_nphy_op_free(mac); 114 #endif 115 } 116 117 int 118 bwn_phy_n_prepare_hw(struct bwn_mac *mac) 119 { 120 121 #ifdef BWN_GPL_PHY 122 bwn_nphy_op_prepare_structs(mac); 123 return (0); 124 #else 125 return (ENXIO); 126 #endif 127 } 128 129 void 130 bwn_phy_n_init_pre(struct bwn_mac *mac) 131 { 132 133 /* XXX TODO */ 134 } 135 136 int 137 bwn_phy_n_init(struct bwn_mac *mac) 138 { 139 #ifdef BWN_GPL_PHY 140 return bwn_nphy_op_init(mac); 141 #else 142 return (ENXIO); 143 #endif 144 } 145 146 void 147 bwn_phy_n_exit(struct bwn_mac *mac) 148 { 149 150 /* XXX TODO */ 151 } 152 153 uint16_t 154 bwn_phy_n_read(struct bwn_mac *mac, uint16_t reg) 155 { 156 157 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 158 return BWN_READ_2(mac, BWN_PHYDATA); 159 } 160 161 void 162 bwn_phy_n_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 163 { 164 165 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 166 BWN_WRITE_2(mac, BWN_PHYDATA, value); 167 } 168 169 uint16_t 170 bwn_phy_n_rf_read(struct bwn_mac *mac, uint16_t reg) 171 { 172 173 /* Register 1 is a 32-bit register. */ 174 if (mac->mac_phy.rev < 7 && reg == 1) { 175 BWN_ERRPRINTF(mac->mac_sc, "%s: bad reg access\n", __func__); 176 } 177 178 if (mac->mac_phy.rev >= 7) 179 reg |= 0x200; /* radio 0x2057 */ 180 else 181 reg |= 0x100; 182 183 BWN_WRITE_2(mac, BWN_RFCTL, reg); 184 return BWN_READ_2(mac, BWN_RFDATALO); 185 } 186 187 void 188 bwn_phy_n_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 189 { 190 191 /* Register 1 is a 32-bit register. */ 192 if (mac->mac_phy.rev < 7 && reg == 1) { 193 BWN_ERRPRINTF(mac->mac_sc, "%s: bad reg access\n", __func__); 194 } 195 196 BWN_WRITE_2(mac, BWN_RFCTL, reg); 197 BWN_WRITE_2(mac, BWN_RFDATALO, value); 198 } 199 200 int 201 bwn_phy_n_hwpctl(struct bwn_mac *mac) 202 { 203 204 return (0); 205 } 206 207 void 208 bwn_phy_n_rf_onoff(struct bwn_mac *mac, int on) 209 { 210 #ifdef BWN_GPL_PHY 211 bwn_nphy_op_software_rfkill(mac, on); 212 #endif 213 } 214 215 void 216 bwn_phy_n_switch_analog(struct bwn_mac *mac, int on) 217 { 218 #ifdef BWN_GPL_PHY 219 bwn_nphy_op_switch_analog(mac, on); 220 #endif 221 } 222 223 int 224 bwn_phy_n_switch_channel(struct bwn_mac *mac, uint32_t newchan) 225 { 226 #ifdef BWN_GPL_PHY 227 return bwn_nphy_op_switch_channel(mac, newchan); 228 #else 229 return (ENXIO); 230 #endif 231 } 232 233 uint32_t 234 bwn_phy_n_get_default_chan(struct bwn_mac *mac) 235 { 236 237 if (bwn_current_band(mac) == BWN_BAND_2G) 238 return (1); 239 return (36); 240 } 241 242 void 243 bwn_phy_n_set_antenna(struct bwn_mac *mac, int antenna) 244 { 245 /* XXX TODO */ 246 } 247 248 int 249 bwn_phy_n_im(struct bwn_mac *mac, int mode) 250 { 251 /* XXX TODO */ 252 return (0); 253 } 254 255 bwn_txpwr_result_t 256 bwn_phy_n_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 257 { 258 #ifdef BWN_GPL_PHY 259 return bwn_nphy_op_recalc_txpower(mac, ignore_tssi); 260 #else 261 return (BWN_TXPWR_RES_DONE); 262 #endif 263 } 264 265 void 266 bwn_phy_n_set_txpwr(struct bwn_mac *mac) 267 { 268 269 } 270 271 void 272 bwn_phy_n_task_15s(struct bwn_mac *mac) 273 { 274 275 } 276 277 void 278 bwn_phy_n_task_60s(struct bwn_mac *mac) 279 { 280 281 } 282