From owner-svn-src-all@freebsd.org Sat May 14 23:48:27 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 79A03B3B6B7; Sat, 14 May 2016 23:48:27 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 51051164B; Sat, 14 May 2016 23:48:27 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u4ENmQaa091339; Sat, 14 May 2016 23:48:26 GMT (envelope-from adrian@FreeBSD.org) Received: (from adrian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u4ENmQgg091338; Sat, 14 May 2016 23:48:26 GMT (envelope-from adrian@FreeBSD.org) Message-Id: <201605142348.u4ENmQgg091338@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: adrian set sender to adrian@FreeBSD.org using -f From: Adrian Chadd Date: Sat, 14 May 2016 23:48:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r299799 - head/sys/dev/bwn X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 14 May 2016 23:48:27 -0000 Author: adrian Date: Sat May 14 23:48:26 2016 New Revision: 299799 URL: https://svnweb.freebsd.org/changeset/base/299799 Log: [bwn] fill out phyctl_1 fields for N-PHY (and later, eventually.) N-PHY and later require a lot more plcp specific setup for the PHY to know what to transmit. I've been spoilt by the atheros, intel and realtek parts where you don't have to hand-assemble the PLCP but .. well, apparently Broadcom require a lot more work. This, and PHY-N itself, was the last major missing bit to get 11a OFDM transmit to work. Without this, CCK transmit worked but OFDM transmit would always fail (with stat.phy_err set to 0x80.) I have no idea what 0x80 is, and I went mad reading the broadcom vendor driver to try and figure it out. Tested: * BCM4312 (PHY-LP) * BCM4321 (PHY-N), 11a, 11bg. Modified: head/sys/dev/bwn/if_bwn.c Modified: head/sys/dev/bwn/if_bwn.c ============================================================================== --- head/sys/dev/bwn/if_bwn.c Sat May 14 23:45:47 2016 (r299798) +++ head/sys/dev/bwn/if_bwn.c Sat May 14 23:48:26 2016 (r299799) @@ -5985,6 +5985,77 @@ bwn_ieeerate2hwrate(struct bwn_softc *sc return (BWN_CCK_RATE_1MB); } +static uint16_t +bwn_set_txhdr_phyctl1(struct bwn_mac *mac, uint8_t bitrate) +{ + struct bwn_phy *phy = &mac->mac_phy; + uint16_t control = 0; + uint16_t bw; + + /* XXX TODO: this is for LP phy, what about N-PHY, etc? */ + bw = BWN_TXH_PHY1_BW_20; + + if (BWN_ISCCKRATE(bitrate) && phy->type != BWN_PHYTYPE_LP) { + control = bw; + } else { + control = bw; + /* Figure out coding rate and modulation */ + /* XXX TODO: table-ize, for MCS transmit */ + /* Note: this is BWN_*_RATE values */ + switch (bitrate) { + case BWN_CCK_RATE_1MB: + control |= 0; + break; + case BWN_CCK_RATE_2MB: + control |= 1; + break; + case BWN_CCK_RATE_5MB: + control |= 2; + break; + case BWN_CCK_RATE_11MB: + control |= 3; + break; + case BWN_OFDM_RATE_6MB: + control |= BWN_TXH_PHY1_CRATE_1_2; + control |= BWN_TXH_PHY1_MODUL_BPSK; + break; + case BWN_OFDM_RATE_9MB: + control |= BWN_TXH_PHY1_CRATE_3_4; + control |= BWN_TXH_PHY1_MODUL_BPSK; + break; + case BWN_OFDM_RATE_12MB: + control |= BWN_TXH_PHY1_CRATE_1_2; + control |= BWN_TXH_PHY1_MODUL_QPSK; + break; + case BWN_OFDM_RATE_18MB: + control |= BWN_TXH_PHY1_CRATE_3_4; + control |= BWN_TXH_PHY1_MODUL_QPSK; + break; + case BWN_OFDM_RATE_24MB: + control |= BWN_TXH_PHY1_CRATE_1_2; + control |= BWN_TXH_PHY1_MODUL_QAM16; + break; + case BWN_OFDM_RATE_36MB: + control |= BWN_TXH_PHY1_CRATE_3_4; + control |= BWN_TXH_PHY1_MODUL_QAM16; + break; + case BWN_OFDM_RATE_48MB: + control |= BWN_TXH_PHY1_CRATE_1_2; + control |= BWN_TXH_PHY1_MODUL_QAM64; + break; + case BWN_OFDM_RATE_54MB: + control |= BWN_TXH_PHY1_CRATE_3_4; + control |= BWN_TXH_PHY1_MODUL_QAM64; + break; + default: + break; + } + control |= BWN_TXH_PHY1_MODE_SISO; + } + + return control; +} + static int bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) @@ -6004,6 +6075,7 @@ bwn_set_txhdr(struct bwn_mac *mac, struc int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; uint16_t phyctl = 0; uint8_t rate, rate_fb; + int fill_phy_ctl1 = 0; wh = mtod(m, struct ieee80211_frame *); memset(txhdr, 0, sizeof(*txhdr)); @@ -6012,6 +6084,10 @@ bwn_set_txhdr(struct bwn_mac *mac, struc ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; + if ((phy->type == BWN_PHYTYPE_N) || (phy->type == BWN_PHYTYPE_LP) + || (phy->type == BWN_PHYTYPE_HT)) + fill_phy_ctl1 = 1; + /* * Find TX rate */ @@ -6165,6 +6241,16 @@ bwn_set_txhdr(struct bwn_mac *mac, struc } txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; + + if (fill_phy_ctl1) { + txhdr->phyctl_1rts = htole16(bwn_set_txhdr_phyctl1(mac, rts_rate)); + txhdr->phyctl_1rtsfb = htole16(bwn_set_txhdr_phyctl1(mac, rts_rate_fb)); + } + } + + if (fill_phy_ctl1) { + txhdr->phyctl_1 = htole16(bwn_set_txhdr_phyctl1(mac, rate)); + txhdr->phyctl_1fb = htole16(bwn_set_txhdr_phyctl1(mac, rate_fb)); } if (BWN_ISOLDFMT(mac))