198d0edefSAdrian Chadd /*-
298d0edefSAdrian Chadd * Copyright (c) 2016 Adrian Chadd <adrian@freebsd.org>
398d0edefSAdrian Chadd * All rights reserved.
498d0edefSAdrian Chadd *
598d0edefSAdrian Chadd * Redistribution and use in source and binary forms, with or without
698d0edefSAdrian Chadd * modification, are permitted provided that the following conditions
798d0edefSAdrian Chadd * are met:
898d0edefSAdrian Chadd * 1. Redistributions of source code must retain the above copyright
998d0edefSAdrian Chadd * notice, this list of conditions and the following disclaimer,
1098d0edefSAdrian Chadd * without modification.
1198d0edefSAdrian Chadd * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1298d0edefSAdrian Chadd * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
1398d0edefSAdrian Chadd * redistribution must be conditioned upon including a substantially
1498d0edefSAdrian Chadd * similar Disclaimer requirement for further binary redistribution.
1598d0edefSAdrian Chadd *
1698d0edefSAdrian Chadd * NO WARRANTY
1798d0edefSAdrian Chadd * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1898d0edefSAdrian Chadd * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1998d0edefSAdrian Chadd * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
2098d0edefSAdrian Chadd * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
2198d0edefSAdrian Chadd * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
2298d0edefSAdrian Chadd * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2398d0edefSAdrian Chadd * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2498d0edefSAdrian Chadd * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
2598d0edefSAdrian Chadd * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2698d0edefSAdrian Chadd * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2798d0edefSAdrian Chadd * THE POSSIBILITY OF SUCH DAMAGES.
2898d0edefSAdrian Chadd */
2998d0edefSAdrian Chadd
3098d0edefSAdrian Chadd #include <sys/cdefs.h>
3198d0edefSAdrian Chadd /*
3298d0edefSAdrian Chadd * This is the top-level N-PHY support for the Broadcom softmac driver.
3398d0edefSAdrian Chadd */
3498d0edefSAdrian Chadd
3598d0edefSAdrian Chadd #include "opt_bwn.h"
3698d0edefSAdrian Chadd #include "opt_wlan.h"
3798d0edefSAdrian Chadd
3898d0edefSAdrian Chadd #include <sys/param.h>
3998d0edefSAdrian Chadd #include <sys/systm.h>
4098d0edefSAdrian Chadd #include <sys/kernel.h>
4198d0edefSAdrian Chadd #include <sys/malloc.h>
4298d0edefSAdrian Chadd #include <sys/module.h>
4398d0edefSAdrian Chadd #include <sys/endian.h>
4498d0edefSAdrian Chadd #include <sys/errno.h>
4598d0edefSAdrian Chadd #include <sys/firmware.h>
4698d0edefSAdrian Chadd #include <sys/lock.h>
4798d0edefSAdrian Chadd #include <sys/mutex.h>
4898d0edefSAdrian Chadd #include <machine/bus.h>
4998d0edefSAdrian Chadd #include <machine/resource.h>
5098d0edefSAdrian Chadd #include <sys/bus.h>
5198d0edefSAdrian Chadd #include <sys/rman.h>
5298d0edefSAdrian Chadd #include <sys/socket.h>
5398d0edefSAdrian Chadd #include <sys/sockio.h>
5498d0edefSAdrian Chadd
5598d0edefSAdrian Chadd #include <net/ethernet.h>
5698d0edefSAdrian Chadd #include <net/if.h>
5798d0edefSAdrian Chadd #include <net/if_var.h>
5898d0edefSAdrian Chadd #include <net/if_arp.h>
5998d0edefSAdrian Chadd #include <net/if_dl.h>
6098d0edefSAdrian Chadd #include <net/if_llc.h>
6198d0edefSAdrian Chadd #include <net/if_media.h>
6298d0edefSAdrian Chadd #include <net/if_types.h>
6398d0edefSAdrian Chadd
6498d0edefSAdrian Chadd #include <dev/pci/pcivar.h>
6598d0edefSAdrian Chadd #include <dev/pci/pcireg.h>
6698d0edefSAdrian Chadd
6798d0edefSAdrian Chadd #include <net80211/ieee80211_var.h>
6898d0edefSAdrian Chadd #include <net80211/ieee80211_radiotap.h>
6998d0edefSAdrian Chadd #include <net80211/ieee80211_regdomain.h>
7098d0edefSAdrian Chadd #include <net80211/ieee80211_phy.h>
7198d0edefSAdrian Chadd #include <net80211/ieee80211_ratectl.h>
7298d0edefSAdrian Chadd
7398d0edefSAdrian Chadd #include <dev/bwn/if_bwnreg.h>
7498d0edefSAdrian Chadd #include <dev/bwn/if_bwnvar.h>
7598d0edefSAdrian Chadd
7698d0edefSAdrian Chadd #include <dev/bwn/if_bwn_debug.h>
7798d0edefSAdrian Chadd #include <dev/bwn/if_bwn_misc.h>
7898d0edefSAdrian Chadd #include <dev/bwn/if_bwn_phy_n.h>
7998d0edefSAdrian Chadd
8098d0edefSAdrian Chadd #ifdef BWN_GPL_PHY
8198d0edefSAdrian Chadd #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.h>
8298d0edefSAdrian Chadd #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.h>
8398d0edefSAdrian Chadd #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_core.h>
8498d0edefSAdrian Chadd #endif
8598d0edefSAdrian Chadd
8698d0edefSAdrian Chadd /*
8798d0edefSAdrian Chadd * This module is always compiled into the kernel, regardless of
8898d0edefSAdrian Chadd * whether the GPL PHY is enabled. If the GPL PHY isn't enabled
8998d0edefSAdrian Chadd * then it'll just be stubs that will fail to attach.
9098d0edefSAdrian Chadd */
9198d0edefSAdrian Chadd
9298d0edefSAdrian Chadd int
bwn_phy_n_attach(struct bwn_mac * mac)9398d0edefSAdrian Chadd bwn_phy_n_attach(struct bwn_mac *mac)
9498d0edefSAdrian Chadd {
9598d0edefSAdrian Chadd
9698d0edefSAdrian Chadd #ifdef BWN_GPL_PHY
9798d0edefSAdrian Chadd return bwn_nphy_op_allocate(mac);
9898d0edefSAdrian Chadd #else
9959f341f8SAdrian Chadd device_printf(mac->mac_sc->sc_dev,
10059f341f8SAdrian Chadd "%s: BWN_GPL_PHY not in kernel config; "
10159f341f8SAdrian Chadd "no PHY-N support\n", __func__);
10298d0edefSAdrian Chadd return (ENXIO);
10398d0edefSAdrian Chadd #endif
10498d0edefSAdrian Chadd }
10598d0edefSAdrian Chadd
10698d0edefSAdrian Chadd void
bwn_phy_n_detach(struct bwn_mac * mac)10798d0edefSAdrian Chadd bwn_phy_n_detach(struct bwn_mac *mac)
10898d0edefSAdrian Chadd {
10998d0edefSAdrian Chadd
11098d0edefSAdrian Chadd #ifdef BWN_GPL_PHY
11198d0edefSAdrian Chadd return bwn_nphy_op_free(mac);
11298d0edefSAdrian Chadd #endif
11398d0edefSAdrian Chadd }
11498d0edefSAdrian Chadd
11598d0edefSAdrian Chadd int
bwn_phy_n_prepare_hw(struct bwn_mac * mac)11698d0edefSAdrian Chadd bwn_phy_n_prepare_hw(struct bwn_mac *mac)
11798d0edefSAdrian Chadd {
11898d0edefSAdrian Chadd
11998d0edefSAdrian Chadd #ifdef BWN_GPL_PHY
120*d177c199SLandon J. Fuller return (bwn_nphy_op_prepare_structs(mac));
12198d0edefSAdrian Chadd #else
12298d0edefSAdrian Chadd return (ENXIO);
12398d0edefSAdrian Chadd #endif
12498d0edefSAdrian Chadd }
12598d0edefSAdrian Chadd
12698d0edefSAdrian Chadd void
bwn_phy_n_init_pre(struct bwn_mac * mac)12798d0edefSAdrian Chadd bwn_phy_n_init_pre(struct bwn_mac *mac)
12898d0edefSAdrian Chadd {
12998d0edefSAdrian Chadd
13098d0edefSAdrian Chadd /* XXX TODO */
13198d0edefSAdrian Chadd }
13298d0edefSAdrian Chadd
13398d0edefSAdrian Chadd int
bwn_phy_n_init(struct bwn_mac * mac)13498d0edefSAdrian Chadd bwn_phy_n_init(struct bwn_mac *mac)
13598d0edefSAdrian Chadd {
13698d0edefSAdrian Chadd #ifdef BWN_GPL_PHY
13798d0edefSAdrian Chadd return bwn_nphy_op_init(mac);
13898d0edefSAdrian Chadd #else
13998d0edefSAdrian Chadd return (ENXIO);
14098d0edefSAdrian Chadd #endif
14198d0edefSAdrian Chadd }
14298d0edefSAdrian Chadd
14398d0edefSAdrian Chadd void
bwn_phy_n_exit(struct bwn_mac * mac)14498d0edefSAdrian Chadd bwn_phy_n_exit(struct bwn_mac *mac)
14598d0edefSAdrian Chadd {
14698d0edefSAdrian Chadd
14798d0edefSAdrian Chadd /* XXX TODO */
14898d0edefSAdrian Chadd }
14998d0edefSAdrian Chadd
15098d0edefSAdrian Chadd uint16_t
bwn_phy_n_read(struct bwn_mac * mac,uint16_t reg)15198d0edefSAdrian Chadd bwn_phy_n_read(struct bwn_mac *mac, uint16_t reg)
15298d0edefSAdrian Chadd {
15398d0edefSAdrian Chadd
15498d0edefSAdrian Chadd BWN_WRITE_2(mac, BWN_PHYCTL, reg);
15598d0edefSAdrian Chadd return BWN_READ_2(mac, BWN_PHYDATA);
15698d0edefSAdrian Chadd }
15798d0edefSAdrian Chadd
15898d0edefSAdrian Chadd void
bwn_phy_n_write(struct bwn_mac * mac,uint16_t reg,uint16_t value)15998d0edefSAdrian Chadd bwn_phy_n_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
16098d0edefSAdrian Chadd {
16198d0edefSAdrian Chadd
16298d0edefSAdrian Chadd BWN_WRITE_2(mac, BWN_PHYCTL, reg);
16398d0edefSAdrian Chadd BWN_WRITE_2(mac, BWN_PHYDATA, value);
16498d0edefSAdrian Chadd }
16598d0edefSAdrian Chadd
16698d0edefSAdrian Chadd uint16_t
bwn_phy_n_rf_read(struct bwn_mac * mac,uint16_t reg)16798d0edefSAdrian Chadd bwn_phy_n_rf_read(struct bwn_mac *mac, uint16_t reg)
16898d0edefSAdrian Chadd {
16998d0edefSAdrian Chadd
17098d0edefSAdrian Chadd /* Register 1 is a 32-bit register. */
17198d0edefSAdrian Chadd if (mac->mac_phy.rev < 7 && reg == 1) {
17298d0edefSAdrian Chadd BWN_ERRPRINTF(mac->mac_sc, "%s: bad reg access\n", __func__);
17398d0edefSAdrian Chadd }
17498d0edefSAdrian Chadd
17598d0edefSAdrian Chadd if (mac->mac_phy.rev >= 7)
17698d0edefSAdrian Chadd reg |= 0x200; /* radio 0x2057 */
17798d0edefSAdrian Chadd else
17898d0edefSAdrian Chadd reg |= 0x100;
17998d0edefSAdrian Chadd
18098d0edefSAdrian Chadd BWN_WRITE_2(mac, BWN_RFCTL, reg);
18198d0edefSAdrian Chadd return BWN_READ_2(mac, BWN_RFDATALO);
18298d0edefSAdrian Chadd }
18398d0edefSAdrian Chadd
18498d0edefSAdrian Chadd void
bwn_phy_n_rf_write(struct bwn_mac * mac,uint16_t reg,uint16_t value)18598d0edefSAdrian Chadd bwn_phy_n_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
18698d0edefSAdrian Chadd {
18798d0edefSAdrian Chadd
18898d0edefSAdrian Chadd /* Register 1 is a 32-bit register. */
18998d0edefSAdrian Chadd if (mac->mac_phy.rev < 7 && reg == 1) {
19098d0edefSAdrian Chadd BWN_ERRPRINTF(mac->mac_sc, "%s: bad reg access\n", __func__);
19198d0edefSAdrian Chadd }
19298d0edefSAdrian Chadd
19398d0edefSAdrian Chadd BWN_WRITE_2(mac, BWN_RFCTL, reg);
19498d0edefSAdrian Chadd BWN_WRITE_2(mac, BWN_RFDATALO, value);
19598d0edefSAdrian Chadd }
19698d0edefSAdrian Chadd
19798d0edefSAdrian Chadd int
bwn_phy_n_hwpctl(struct bwn_mac * mac)19898d0edefSAdrian Chadd bwn_phy_n_hwpctl(struct bwn_mac *mac)
19998d0edefSAdrian Chadd {
20098d0edefSAdrian Chadd
20198d0edefSAdrian Chadd return (0);
20298d0edefSAdrian Chadd }
20398d0edefSAdrian Chadd
20498d0edefSAdrian Chadd void
bwn_phy_n_rf_onoff(struct bwn_mac * mac,int on)20598d0edefSAdrian Chadd bwn_phy_n_rf_onoff(struct bwn_mac *mac, int on)
20698d0edefSAdrian Chadd {
20798d0edefSAdrian Chadd #ifdef BWN_GPL_PHY
20898d0edefSAdrian Chadd bwn_nphy_op_software_rfkill(mac, on);
20998d0edefSAdrian Chadd #endif
21098d0edefSAdrian Chadd }
21198d0edefSAdrian Chadd
21298d0edefSAdrian Chadd void
bwn_phy_n_switch_analog(struct bwn_mac * mac,int on)21398d0edefSAdrian Chadd bwn_phy_n_switch_analog(struct bwn_mac *mac, int on)
21498d0edefSAdrian Chadd {
21598d0edefSAdrian Chadd #ifdef BWN_GPL_PHY
21698d0edefSAdrian Chadd bwn_nphy_op_switch_analog(mac, on);
21798d0edefSAdrian Chadd #endif
21898d0edefSAdrian Chadd }
21998d0edefSAdrian Chadd
22098d0edefSAdrian Chadd int
bwn_phy_n_switch_channel(struct bwn_mac * mac,uint32_t newchan)22198d0edefSAdrian Chadd bwn_phy_n_switch_channel(struct bwn_mac *mac, uint32_t newchan)
22298d0edefSAdrian Chadd {
22398d0edefSAdrian Chadd #ifdef BWN_GPL_PHY
22498d0edefSAdrian Chadd return bwn_nphy_op_switch_channel(mac, newchan);
22598d0edefSAdrian Chadd #else
22698d0edefSAdrian Chadd return (ENXIO);
22798d0edefSAdrian Chadd #endif
22898d0edefSAdrian Chadd }
22998d0edefSAdrian Chadd
23098d0edefSAdrian Chadd uint32_t
bwn_phy_n_get_default_chan(struct bwn_mac * mac)23198d0edefSAdrian Chadd bwn_phy_n_get_default_chan(struct bwn_mac *mac)
23298d0edefSAdrian Chadd {
23398d0edefSAdrian Chadd
23498d0edefSAdrian Chadd if (bwn_current_band(mac) == BWN_BAND_2G)
23598d0edefSAdrian Chadd return (1);
23698d0edefSAdrian Chadd return (36);
23798d0edefSAdrian Chadd }
23898d0edefSAdrian Chadd
23998d0edefSAdrian Chadd void
bwn_phy_n_set_antenna(struct bwn_mac * mac,int antenna)24098d0edefSAdrian Chadd bwn_phy_n_set_antenna(struct bwn_mac *mac, int antenna)
24198d0edefSAdrian Chadd {
24298d0edefSAdrian Chadd /* XXX TODO */
24398d0edefSAdrian Chadd }
24498d0edefSAdrian Chadd
24598d0edefSAdrian Chadd int
bwn_phy_n_im(struct bwn_mac * mac,int mode)24698d0edefSAdrian Chadd bwn_phy_n_im(struct bwn_mac *mac, int mode)
24798d0edefSAdrian Chadd {
24898d0edefSAdrian Chadd /* XXX TODO */
24998d0edefSAdrian Chadd return (0);
25098d0edefSAdrian Chadd }
25198d0edefSAdrian Chadd
25298d0edefSAdrian Chadd bwn_txpwr_result_t
bwn_phy_n_recalc_txpwr(struct bwn_mac * mac,int ignore_tssi)25398d0edefSAdrian Chadd bwn_phy_n_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
25498d0edefSAdrian Chadd {
25598d0edefSAdrian Chadd #ifdef BWN_GPL_PHY
25698d0edefSAdrian Chadd return bwn_nphy_op_recalc_txpower(mac, ignore_tssi);
25798d0edefSAdrian Chadd #else
25898d0edefSAdrian Chadd return (BWN_TXPWR_RES_DONE);
25998d0edefSAdrian Chadd #endif
26098d0edefSAdrian Chadd }
26198d0edefSAdrian Chadd
26298d0edefSAdrian Chadd void
bwn_phy_n_set_txpwr(struct bwn_mac * mac)26398d0edefSAdrian Chadd bwn_phy_n_set_txpwr(struct bwn_mac *mac)
26498d0edefSAdrian Chadd {
26598d0edefSAdrian Chadd
26698d0edefSAdrian Chadd }
26798d0edefSAdrian Chadd
26898d0edefSAdrian Chadd void
bwn_phy_n_task_15s(struct bwn_mac * mac)26998d0edefSAdrian Chadd bwn_phy_n_task_15s(struct bwn_mac *mac)
27098d0edefSAdrian Chadd {
27198d0edefSAdrian Chadd
27298d0edefSAdrian Chadd }
27398d0edefSAdrian Chadd
27498d0edefSAdrian Chadd void
bwn_phy_n_task_60s(struct bwn_mac * mac)27598d0edefSAdrian Chadd bwn_phy_n_task_60s(struct bwn_mac *mac)
27698d0edefSAdrian Chadd {
27798d0edefSAdrian Chadd
27898d0edefSAdrian Chadd }
279