1 /* $NetBSD: if_ath_arbus.c,v 1.23 2022/09/29 07:00:46 skrll Exp $ */ 2 3 /*- 4 * Copyright (c) 2006 Jared D. McNeill <jmcneill@invisible.ca> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the NetBSD 18 * Foundation, Inc. and its contributors. 19 * 4. Neither the name of The NetBSD Foundation nor the names of its 20 * contributors may be used to endorse or promote products derived 21 * from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 27 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #include <sys/cdefs.h> 37 __KERNEL_RCSID(0, "$NetBSD: if_ath_arbus.c,v 1.23 2022/09/29 07:00:46 skrll Exp $"); 38 39 #include <sys/param.h> 40 #include <sys/bus.h> 41 #include <sys/device.h> 42 #include <sys/errno.h> 43 #include <sys/intr.h> 44 #include <sys/kernel.h> 45 #include <sys/mbuf.h> 46 #include <sys/systm.h> 47 48 #include <net/if.h> 49 #include <net/if_media.h> 50 #include <net/if_ether.h> 51 #include <net/if_llc.h> 52 #include <net/if_arp.h> 53 54 #include <netinet/in.h> 55 56 #include <net80211/ieee80211_netbsd.h> 57 #include <net80211/ieee80211_var.h> 58 59 #include <mips/atheros/include/arbusvar.h> 60 #include <mips/atheros/include/platform.h> 61 62 #include <dev/pci/pcidevs.h> 63 #include <dev/ic/ath_netbsd.h> 64 #include <dev/ic/athvar.h> 65 66 #include <ah.h> 67 #include <ah_soc.h> /* XXX really doesn't belong in hal */ 68 69 struct ath_arbus_softc { 70 struct ath_softc sc_ath; 71 bus_space_tag_t sc_iot; 72 bus_space_handle_t sc_ioh; 73 void *sc_ih; 74 struct ar531x_config sc_config; 75 }; 76 77 static int ath_arbus_match(device_t, cfdata_t, void *); 78 static void ath_arbus_attach(device_t, device_t, void *); 79 static int ath_arbus_detach(device_t, int); 80 81 CFATTACH_DECL_NEW(ath_arbus, sizeof(struct ath_arbus_softc), 82 ath_arbus_match, ath_arbus_attach, ath_arbus_detach, NULL); 83 84 static int 85 ath_arbus_match(device_t parent, cfdata_t cf, void *opaque) 86 { 87 struct arbus_attach_args *aa; 88 89 aa = (struct arbus_attach_args *)opaque; 90 if (strcmp(aa->aa_name, "ath") == 0) 91 return 1; 92 93 return 0; 94 } 95 96 static bool 97 ath_arbus_resume(device_t dv, const pmf_qual_t *qual) 98 { 99 struct ath_arbus_softc *asc = device_private(dv); 100 ath_resume(&asc->sc_ath); 101 102 return true; 103 } 104 105 106 static void 107 ath_arbus_attach(device_t parent, device_t self, void *opaque) 108 { 109 struct ath_arbus_softc *asc; 110 struct ath_softc *sc; 111 struct arbus_attach_args *aa; 112 const char *name; 113 prop_number_t prop; 114 int rv; 115 uint16_t devid; 116 117 asc = device_private(self); 118 sc = &asc->sc_ath; 119 sc->sc_dev = self; 120 aa = (struct arbus_attach_args *)opaque; 121 122 prop = prop_dictionary_get(device_properties(sc->sc_dev), 123 "wmac-rev"); 124 if (prop == NULL) { 125 printf(": unable to get wmac-rev property\n"); 126 return; 127 } 128 KDASSERT(prop_object_type(prop) == PROP_TYPE_NUMBER); 129 130 devid = (uint16_t)prop_number_integer_value(prop); 131 name = ath_hal_probe(PCI_VENDOR_ATHEROS, devid); 132 133 printf(": %s\n", name ? name : "Unknown AR531X WLAN"); 134 135 asc->sc_iot = aa->aa_bst; 136 rv = bus_space_map(asc->sc_iot, aa->aa_addr, aa->aa_size, 0, 137 &asc->sc_ioh); 138 if (rv) { 139 aprint_error_dev(self, "unable to map registers\n"); 140 return; 141 } 142 /* 143 * Setup HAL configuration state for use by the driver. 144 */ 145 rv = atheros_get_board_config(&asc->sc_config); 146 if (rv) { 147 aprint_error_dev(self, "unable to locate board configuration\n"); 148 return; 149 } 150 asc->sc_config.unit = device_unit(sc->sc_dev); 151 asc->sc_config.tag = asc->sc_iot; 152 153 /* NB: the HAL expects the config state passed as the tag */ 154 sc->sc_st = (HAL_BUS_TAG) &asc->sc_config; 155 sc->sc_sh = (HAL_BUS_HANDLE) asc->sc_ioh; 156 sc->sc_dmat = aa->aa_dmat; 157 158 asc->sc_ih = arbus_intr_establish(aa->aa_cirq, aa->aa_mirq, ath_intr, 159 sc); 160 if (asc->sc_ih == NULL) { 161 aprint_error_dev(self, "couldn't establish interrupt\n"); 162 return; 163 } 164 165 //ATH_LOCK_INIT(sc); 166 167 if (!pmf_device_register(self, NULL, ath_arbus_resume)) 168 aprint_error_dev(self, "couldn't establish power handler\n"); 169 else 170 pmf_class_network_register(self, &sc->sc_if); 171 172 if (ath_attach(devid, sc) != 0) { 173 aprint_error_dev(self, "ath_attach failed\n"); 174 goto err; 175 } 176 177 return; 178 179 err: 180 arbus_intr_disestablish(asc->sc_ih); 181 } 182 183 static int 184 ath_arbus_detach(device_t self, int flags) 185 { 186 struct ath_arbus_softc *asc = device_private(self); 187 188 ath_detach(&asc->sc_ath); 189 arbus_intr_disestablish(asc->sc_ih); 190 191 return (0); 192 } 193