From 6696c7f416694a135c9cfec40fdd875cf7f586fb Mon Sep 17 00:00:00 2001 From: stsp Date: Wed, 31 Jan 2018 11:27:03 +0000 Subject: [PATCH] Fix 11g ifmedia modes in ath(4) (shown by 'ifconfig ath0 media'). There was code which set them up but didn't include 11b channels which are part of 11g. And there was a hack which effectively stripped important flag bits away and wouldn't work for modes with overlapping channels (b/g). As a result, some flags were missing from 11g channels the driver reported to net80211, which skipped over those channels when building the media list. This gets us one step closer to supporting the AR5424. ok mpi@ --- sys/dev/ic/ar5211.c | 25 +++++++++++++------------ sys/dev/ic/ar5212.c | 29 +++++++++++++++-------------- sys/dev/ic/ar5xxx.c | 12 ++++++------ sys/dev/ic/ath.c | 41 ++++++++--------------------------------- 4 files changed, 42 insertions(+), 65 deletions(-) diff --git a/sys/dev/ic/ar5211.c b/sys/dev/ic/ar5211.c index 956256e7bb9..221f044fc26 100644 --- a/sys/dev/ic/ar5211.c +++ b/sys/dev/ic/ar5211.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar5211.c,v 1.49 2017/10/15 13:06:12 stsp Exp $ */ +/* $OpenBSD: ar5211.c,v 1.50 2018/01/31 11:27:03 stsp Exp $ */ /* * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter @@ -443,24 +443,25 @@ ar5k_ar5211_reset(struct ath_hal *hal, HAL_OPMODE op_mode, HAL_CHANNEL *channel, */ hal->ah_op_mode = op_mode; - switch (channel->c_channel_flags & CHANNEL_MODES) { - case CHANNEL_A: + if ((channel->c_channel_flags & CHANNEL_A) == CHANNEL_A) { mode = AR5K_INI_VAL_11A; freq = AR5K_INI_RFGAIN_5GHZ; ee_mode = AR5K_EEPROM_MODE_11A; - break; - case CHANNEL_B: - mode = AR5K_INI_VAL_11B; + } else if ((channel->c_channel_flags & CHANNEL_B) == CHANNEL_B) { + if (hal->ah_capabilities.cap_mode & HAL_MODE_11B) { + mode = AR5K_INI_VAL_11B; + ee_mode = AR5K_EEPROM_MODE_11B; + } else { + mode = AR5K_INI_VAL_11G; + ee_mode = AR5K_EEPROM_MODE_11G; + } freq = AR5K_INI_RFGAIN_2GHZ; - ee_mode = AR5K_EEPROM_MODE_11B; - break; - case CHANNEL_G: - case CHANNEL_PUREG: + } else if ((channel->c_channel_flags & (CHANNEL_G | CHANNEL_PUREG)) == + (CHANNEL_G | CHANNEL_PUREG)) { mode = AR5K_INI_VAL_11G; freq = AR5K_INI_RFGAIN_2GHZ; ee_mode = AR5K_EEPROM_MODE_11G; - break; - default: + } else { AR5K_PRINTF("invalid channel: %d\n", channel->c_channel); return (AH_FALSE); } diff --git a/sys/dev/ic/ar5212.c b/sys/dev/ic/ar5212.c index 50a9b294119..6ed3468cc2d 100644 --- a/sys/dev/ic/ar5212.c +++ b/sys/dev/ic/ar5212.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar5212.c,v 1.57 2017/10/15 13:06:12 stsp Exp $ */ +/* $OpenBSD: ar5212.c,v 1.58 2018/01/31 11:27:03 stsp Exp $ */ /* * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter @@ -505,29 +505,30 @@ ar5k_ar5212_reset(struct ath_hal *hal, HAL_OPMODE op_mode, HAL_CHANNEL *channel, */ hal->ah_op_mode = op_mode; - switch (channel->c_channel_flags & CHANNEL_MODES) { - case CHANNEL_A: + if ((channel->c_channel_flags & CHANNEL_A) == CHANNEL_A) { mode = AR5K_INI_VAL_11A; freq = AR5K_INI_RFGAIN_5GHZ; ee_mode = AR5K_EEPROM_MODE_11A; - break; - case CHANNEL_B: - mode = AR5K_INI_VAL_11B; + } else if ((channel->c_channel_flags & CHANNEL_B) == CHANNEL_B) { + if (hal->ah_capabilities.cap_mode & HAL_MODE_11B) { + mode = AR5K_INI_VAL_11B; + ee_mode = AR5K_EEPROM_MODE_11B; + } else { + mode = AR5K_INI_VAL_11B; + mode = AR5K_INI_VAL_11G; + ee_mode = AR5K_EEPROM_MODE_11G; + } freq = AR5K_INI_RFGAIN_2GHZ; - ee_mode = AR5K_EEPROM_MODE_11B; - break; - case CHANNEL_G: - case CHANNEL_PUREG: + } else if ((channel->c_channel_flags & (CHANNEL_G | CHANNEL_PUREG)) == + (CHANNEL_G | CHANNEL_PUREG)) { mode = AR5K_INI_VAL_11G; freq = AR5K_INI_RFGAIN_2GHZ; ee_mode = AR5K_EEPROM_MODE_11G; - break; - case CHANNEL_XR: + } else if ((channel->c_channel_flags & CHANNEL_XR) == CHANNEL_XR) { mode = AR5K_INI_VAL_XR; freq = AR5K_INI_RFGAIN_5GHZ; ee_mode = AR5K_EEPROM_MODE_11A; - break; - default: + } else { AR5K_PRINTF("invalid channel: %d\n", channel->c_channel); return (AH_FALSE); } diff --git a/sys/dev/ic/ar5xxx.c b/sys/dev/ic/ar5xxx.c index a9271432646..416ab96b982 100644 --- a/sys/dev/ic/ar5xxx.c +++ b/sys/dev/ic/ar5xxx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar5xxx.c,v 1.62 2017/08/25 10:04:36 tb Exp $ */ +/* $OpenBSD: ar5xxx.c,v 1.63 2018/01/31 11:27:03 stsp Exp $ */ /* * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter @@ -472,11 +472,11 @@ ath_hal_init_channels(struct ath_hal *hal, HAL_CHANNEL *channels, (ar5k_2ghz_channels[i].rc_mode & IEEE80211_CHAN_CCK)) all_channels[c].c_channel_flags = CHANNEL_B; - if ((hal->ah_capabilities.cap_mode & HAL_MODE_11G) && - (ar5k_2ghz_channels[i].rc_mode & IEEE80211_CHAN_OFDM)) { - all_channels[c].c_channel_flags |= - hal->ah_version == AR5K_AR5211 ? - CHANNEL_PUREG : CHANNEL_G; + if (hal->ah_capabilities.cap_mode & HAL_MODE_11G) { + if (ar5k_2ghz_channels[i].rc_mode & IEEE80211_CHAN_CCK) + all_channels[c].c_channel_flags = CHANNEL_B; + if (ar5k_2ghz_channels[i].rc_mode & IEEE80211_CHAN_OFDM) + all_channels[c].c_channel_flags |= (CHANNEL_G | CHANNEL_PUREG); } /* Write channel and increment counter */ diff --git a/sys/dev/ic/ath.c b/sys/dev/ic/ath.c index 164d57e310a..c0c5f4241b0 100644 --- a/sys/dev/ic/ath.c +++ b/sys/dev/ic/ath.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ath.c,v 1.115 2017/05/31 09:17:39 stsp Exp $ */ +/* $OpenBSD: ath.c,v 1.116 2018/01/31 11:27:03 stsp Exp $ */ /* $NetBSD: ath.c,v 1.37 2004/08/18 21:59:39 dyoung Exp $ */ /*- @@ -88,7 +88,6 @@ int ath_ioctl(struct ifnet *, u_long, caddr_t); void ath_fatal_proc(void *, int); void ath_rxorn_proc(void *, int); void ath_bmiss_proc(void *, int); -u_int ath_chan2flags(struct ieee80211com *, struct ieee80211_channel *); int ath_initkeytable(struct ath_softc *); void ath_mcastfilter_accum(caddr_t, u_int32_t (*)[2]); void ath_mcastfilter_compute(struct ath_softc *, u_int32_t (*)[2]); @@ -601,26 +600,6 @@ ath_bmiss_proc(void *arg, int pending) } } -u_int -ath_chan2flags(struct ieee80211com *ic, struct ieee80211_channel *chan) -{ - enum ieee80211_phymode mode = ieee80211_chan2mode(ic, chan); - - switch (mode) { - case IEEE80211_MODE_AUTO: - return 0; - case IEEE80211_MODE_11A: - return CHANNEL_A; - case IEEE80211_MODE_11B: - return CHANNEL_B; - case IEEE80211_MODE_11G: - return CHANNEL_G; - default: - panic("%s: unsupported mode %d", __func__, mode); - return 0; - } -} - int ath_init(struct ifnet *ifp) { @@ -666,7 +645,7 @@ ath_init1(struct ath_softc *sc) * and then setup of the interrupt mask. */ hchan.channel = ic->ic_ibss_chan->ic_freq; - hchan.channelFlags = ath_chan2flags(ic, ic->ic_ibss_chan); + hchan.channelFlags = ic->ic_ibss_chan->ic_flags; if (!ath_hal_reset(ah, ic->ic_opmode, &hchan, AH_TRUE, &status)) { printf("%s: unable to reset hardware; hal status %u\n", ifp->if_xname, status); @@ -789,12 +768,11 @@ ath_reset(struct ath_softc *sc, int full) HAL_CHANNEL hchan; /* - * Convert to a HAL channel description with the flags - * constrained to reflect the current operating mode. + * Convert to a HAL channel description. */ c = ic->ic_ibss_chan; hchan.channel = c->ic_freq; - hchan.channelFlags = ath_chan2flags(ic, c); + hchan.channelFlags = c->ic_flags; ath_hal_set_intr(ah, 0); /* disable interrupts */ ath_draintxq(sc); /* stop xmit side */ @@ -2658,12 +2636,10 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) ath_draintxq(sc); /* clear pending tx frames */ ath_stoprecv(sc); /* turn off frame recv */ /* - * Convert to a HAL channel description with - * the flags constrained to reflect the current - * operating mode. + * Convert to a HAL channel description. */ hchan.channel = chan->ic_freq; - hchan.channelFlags = ath_chan2flags(ic, chan); + hchan.channelFlags = chan->ic_flags; if (!ath_hal_reset(ah, ic->ic_opmode, &hchan, AH_TRUE, &status)) { printf("%s: ath_chan_set: unable to reset " @@ -2753,12 +2729,11 @@ ath_calibrate(void *arg) sc->sc_stats.ast_per_cal++; /* - * Convert to a HAL channel description with the flags - * constrained to reflect the current operating mode. + * Convert to a HAL channel description. */ c = ic->ic_ibss_chan; hchan.channel = c->ic_freq; - hchan.channelFlags = ath_chan2flags(ic, c); + hchan.channelFlags = c->ic_flags; s = splnet(); DPRINTF(ATH_DEBUG_CALIBRATE, -- 2.20.1