Hi tech@ Here is a diff to update bwi_tbl_write_{2|4} functions and to add bwi_tbl_read_{2|4}. Switching these functions parameters from addr, data to addr, index, data will be more natural and will simplify diffs with the linux driver.
I take example on tables.c code in the b43 driver. Like the 2 other diffs I've sent few minutes ago it works for me and it will be great to have feedback on other cards. Comments/OK/NOK ? Cheers, Index: bwi.c =================================================================== RCS file: /cvs/src/sys/dev/ic/bwi.c,v retrieving revision 1.97 diff -u -p -u -p -r1.97 bwi.c --- bwi.c 31 Dec 2012 10:07:51 -0000 1.97 +++ bwi.c 9 Sep 2013 12:07:45 -0000 @@ -191,8 +191,10 @@ uint16_t bwi_phy_read(struct bwi_mac *, int bwi_phy_attach(struct bwi_mac *); void bwi_phy_set_bbp_atten(struct bwi_mac *, uint16_t); int bwi_phy_calibrate(struct bwi_mac *); -void bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t); -void bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t); +uint16_t bwi_tbl_read_2(struct bwi_mac *, uint16_t, uint16_t); +uint32_t bwi_tbl_read_4(struct bwi_mac *, uint16_t, uint16_t); +void bwi_tbl_write_2(struct bwi_mac *, uint16_t, uint16_t, uint16_t); +void bwi_tbl_write_4(struct bwi_mac *, uint16_t, uint16_t, uint32_t); void bwi_nrssi_write(struct bwi_mac *, uint16_t, int16_t); int16_t bwi_nrssi_read(struct bwi_mac *, uint16_t); void bwi_phy_init_11a(struct bwi_mac *); @@ -2855,6 +2857,8 @@ bwi_phy_attach(struct bwi_mac *mac) * Verify whether the revision of the PHY type is supported * Convert PHY type to ieee80211_phymode */ + phy->phy_tbl_dir = BWI_TBL_DIR_UNKNOWN; + phy->phy_tbl_addr = 0; switch (phytype) { case BWI_PHYINFO_TYPE_11A: if (phyrev >= 4) { @@ -2864,9 +2868,6 @@ bwi_phy_attach(struct bwi_mac *mac) } phy->phy_init = bwi_phy_init_11a; phy->phy_mode = IEEE80211_MODE_11A; - phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11A; - phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11A; - phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11A; break; case BWI_PHYINFO_TYPE_11B: for (i = 0; i < nitems(bwi_sup_bphy); ++i) { @@ -2890,9 +2891,6 @@ bwi_phy_attach(struct bwi_mac *mac) } phy->phy_init = bwi_phy_init_11g; phy->phy_mode = IEEE80211_MODE_11G; - phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11G; - phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11G; - phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11G; break; default: printf("%s: unsupported PHY type %d\n", @@ -2947,27 +2945,77 @@ bwi_phy_calibrate(struct bwi_mac *mac) return (0); } +uint16_t +bwi_tbl_read_2(struct bwi_mac *mac, uint16_t tbl, uint16_t ofs) +{ + struct bwi_phy *phy = &mac->mac_phy; + uint16_t addr; + + addr = tbl + ofs; + if ((phy->phy_tbl_dir != BWI_TBL_DIR_READ) && + (addr - 1 != phy->phy_tbl_addr)) { + PHY_WRITE(mac, BWI_PHYR_TBL_CTRL_11G, addr); + phy->phy_tbl_dir = BWI_TBL_DIR_READ; + } + + phy->phy_tbl_addr = addr; + return (PHY_READ(mac, BWI_PHYR_TBL_DATA_LO_11G)); +} + +uint32_t +bwi_tbl_read_4(struct bwi_mac *mac, uint16_t tbl, uint16_t ofs) +{ + struct bwi_phy *phy = &mac->mac_phy; + uint16_t addr; + uint32_t val; + + addr = tbl + ofs; + if ((phy->phy_tbl_dir != BWI_TBL_DIR_READ) && + (addr - 1 != phy->phy_tbl_addr)) { + PHY_WRITE(mac, BWI_PHYR_TBL_CTRL_11G, addr); + phy->phy_tbl_dir = BWI_TBL_DIR_READ; + } + + phy->phy_tbl_addr = addr; + val = PHY_READ(mac, BWI_PHYR_TBL_DATA_HI_11G); + val <<= 16; + val |= PHY_READ(mac, BWI_PHYR_TBL_DATA_LO_11G); + return (val); +} + void -bwi_tbl_write_2(struct bwi_mac *mac, uint16_t ofs, uint16_t data) +bwi_tbl_write_2(struct bwi_mac *mac, uint16_t tbl, uint16_t ofs, uint16_t data) { struct bwi_phy *phy = &mac->mac_phy; + uint16_t addr; - KASSERT(phy->phy_tbl_ctrl != 0 && phy->phy_tbl_data_lo != 0); - PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs); - PHY_WRITE(mac, phy->phy_tbl_data_lo, data); + addr = tbl + ofs; + if ((phy->phy_tbl_dir != BWI_TBL_DIR_WRITE) && + (addr - 1 != phy->phy_tbl_addr)) { + PHY_WRITE(mac, BWI_PHYR_TBL_CTRL_11G, addr); + phy->phy_tbl_dir = BWI_TBL_DIR_WRITE; + } + + phy->phy_tbl_addr = addr; + PHY_WRITE(mac, BWI_PHYR_TBL_DATA_LO_11G, data); } void -bwi_tbl_write_4(struct bwi_mac *mac, uint16_t ofs, uint32_t data) +bwi_tbl_write_4(struct bwi_mac *mac, uint16_t tbl, uint16_t ofs, uint32_t data) { struct bwi_phy *phy = &mac->mac_phy; + uint16_t addr; - KASSERT(phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 && - phy->phy_tbl_ctrl != 0); + addr = tbl + ofs; + if ((phy->phy_tbl_dir != BWI_TBL_DIR_WRITE) && + (addr - 1 != phy->phy_tbl_addr)) { + PHY_WRITE(mac, BWI_PHYR_TBL_CTRL_11G, addr); + phy->phy_tbl_dir = BWI_TBL_DIR_WRITE; + } - PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs); - PHY_WRITE(mac, phy->phy_tbl_data_hi, data >> 16); - PHY_WRITE(mac, phy->phy_tbl_data_lo, data & 0xffff); + phy->phy_tbl_addr = addr; + PHY_WRITE(mac, BWI_PHYR_TBL_DATA_HI_11G, (data & 0xffff)); + PHY_WRITE(mac, BWI_PHYR_TBL_DATA_LO_11G, (data >> 16)); } void @@ -3439,20 +3487,20 @@ bwi_phy_config_11g(struct bwi_mac *mac) /* Fill frequency table */ for (i = 0; i < nitems(bwi_phy_freq_11g_rev1); ++i) { - bwi_tbl_write_2(mac, BWI_PHYTBL_FREQ + i, + bwi_tbl_write_2(mac, BWI_PHYTBL_FREQ, i, bwi_phy_freq_11g_rev1[i]); } /* Fill noise table */ for (i = 0; i < nitems(bwi_phy_noise_11g_rev1); ++i) { - bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i, + bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE, i, bwi_phy_noise_11g_rev1[i]); } /* Fill rotor table */ for (i = 0; i < nitems(bwi_phy_rotor_11g_rev1); ++i) { /* NB: data length is 4 bytes */ - bwi_tbl_write_4(mac, BWI_PHYTBL_ROTOR + i, + bwi_tbl_write_4(mac, BWI_PHYTBL_ROTOR, i, bwi_phy_rotor_11g_rev1[i]); } } else { @@ -3470,11 +3518,11 @@ bwi_phy_config_11g(struct bwi_mac *mac) /* Fill RSSI table */ for (i = 0; i < 64; ++i) - bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI + i, i); + bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI, i, i); /* Fill noise table */ for (i = 0; i < nitems(bwi_phy_noise_11g); ++i) { - bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i, + bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE, i, bwi_phy_noise_11g[i]); } } @@ -3493,7 +3541,7 @@ bwi_phy_config_11g(struct bwi_mac *mac) n = nitems(bwi_phy_noise_scale_11g); } for (i = 0; i < n; ++i) - bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE_SCALE + i, tbl[i]); + bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE_SCALE, i, tbl[i]); /* * Fill sigma square table @@ -3509,18 +3557,18 @@ bwi_phy_config_11g(struct bwi_mac *mac) n = 0; } for (i = 0; i < n; ++i) - bwi_tbl_write_2(mac, BWI_PHYTBL_SIGMA_SQ + i, tbl[i]); + bwi_tbl_write_2(mac, BWI_PHYTBL_SIGMA_SQ, i, tbl[i]); if (phy->phy_rev == 1) { /* Fill delay table */ for (i = 0; i < nitems(bwi_phy_delay_11g_rev1); ++i) { - bwi_tbl_write_4(mac, BWI_PHYTBL_DELAY + i, + bwi_tbl_write_4(mac, BWI_PHYTBL_DELAY, i, bwi_phy_delay_11g_rev1[i]); } /* Fill WRSSI (Wide-Band RSSI) table */ for (i = 4; i < 20; ++i) - bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI_REV1 + i, 0x20); + bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI_REV1, i, 0x20); bwi_phy_config_agc(mac); @@ -3529,22 +3577,22 @@ bwi_phy_config_11g(struct bwi_mac *mac) } else { /* Fill WRSSI (Wide-Band RSSI) table */ for (i = 0; i < 0x20; ++i) - bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI + i, 0x820); + bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI, i, 0x820); bwi_phy_config_agc(mac); PHY_READ(mac, 0x400); /* Dummy read */ PHY_WRITE(mac, 0x403, 0x1000); - bwi_tbl_write_2(mac, 0x3c02, 0xf); - bwi_tbl_write_2(mac, 0x3c03, 0x14); + bwi_tbl_write_2(mac, 0x3c00, 2, 0xf); + bwi_tbl_write_2(mac, 0x3c00, 3, 0x14); wrd_ofs1 = 0x401; wrd_ofs2 = 0x402; } if (!(BWI_IS_BRCM_BU4306(sc) && sc->sc_pci_revid == 0x17)) { - bwi_tbl_write_2(mac, wrd_ofs1, 0x2); - bwi_tbl_write_2(mac, wrd_ofs2, 0x1); + bwi_tbl_write_2(mac, wrd_ofs1, 0, 0x2); + bwi_tbl_write_2(mac, wrd_ofs2, 0, 0x1); } /* phy->phy_flags & BWI_PHY_F_LINKED ? */ @@ -3564,16 +3612,16 @@ bwi_phy_config_agc(struct bwi_mac *mac) ofs = phy->phy_rev == 1 ? 0x4c00 : 0; - bwi_tbl_write_2(mac, ofs, 0xfe); - bwi_tbl_write_2(mac, ofs + 1, 0xd); - bwi_tbl_write_2(mac, ofs + 2, 0x13); - bwi_tbl_write_2(mac, ofs + 3, 0x19); + bwi_tbl_write_2(mac, ofs, 0, 0xfe); + bwi_tbl_write_2(mac, ofs, 1, 0xd); + bwi_tbl_write_2(mac, ofs, 2, 0x13); + bwi_tbl_write_2(mac, ofs, 3, 0x19); if (phy->phy_rev == 1) { - bwi_tbl_write_2(mac, 0x1800, 0x2710); - bwi_tbl_write_2(mac, 0x1801, 0x9b83); - bwi_tbl_write_2(mac, 0x1802, 0x9b83); - bwi_tbl_write_2(mac, 0x1803, 0xf8d); + bwi_tbl_write_2(mac, 0x1800, 0, 0x2710); + bwi_tbl_write_2(mac, 0x1800, 1, 0x9b83); + bwi_tbl_write_2(mac, 0x1800, 2, 0x9b83); + bwi_tbl_write_2(mac, 0x1800, 3, 0xf8d); PHY_WRITE(mac, 0x455, 0x4); } @@ -3626,10 +3674,10 @@ bwi_phy_config_agc(struct bwi_mac *mac) PHY_WRITE(mac, 0x48d, 0x2); } - bwi_tbl_write_2(mac, ofs + 0x800, 0); - bwi_tbl_write_2(mac, ofs + 0x801, 7); - bwi_tbl_write_2(mac, ofs + 0x802, 16); - bwi_tbl_write_2(mac, ofs + 0x803, 28); + bwi_tbl_write_2(mac, ofs + 0x800, 0, 0); + bwi_tbl_write_2(mac, ofs + 0x800, 1, 7); + bwi_tbl_write_2(mac, ofs + 0x800, 2, 16); + bwi_tbl_write_2(mac, ofs + 0x800, 3, 28); if (phy->phy_rev >= 6) { PHY_CLRBITS(mac, 0x426, 0x3); @@ -3660,7 +3708,7 @@ bwi_set_gains(struct bwi_mac *mac, const tbl_gain = (i & 0x1) << 1; tbl_gain |= (i & 0x2) >> 1; } - bwi_tbl_write_2(mac, tbl_gain_ofs1 + i, tbl_gain); + bwi_tbl_write_2(mac, tbl_gain_ofs1, i, tbl_gain); } for (i = 0; i < 16; ++i) { @@ -3668,7 +3716,7 @@ bwi_set_gains(struct bwi_mac *mac, const tbl_gain = gains->tbl_gain2; else tbl_gain = i; - bwi_tbl_write_2(mac, tbl_gain_ofs2 + i, tbl_gain); + bwi_tbl_write_2(mac, tbl_gain_ofs2, i, tbl_gain); } if (gains == NULL || (gains != NULL && gains->phy_gain != -1)) { Index: bwivar.h =================================================================== RCS file: /cvs/src/sys/dev/ic/bwivar.h,v retrieving revision 1.26 diff -u -p -u -p -r1.26 bwivar.h --- bwivar.h 6 Aug 2010 05:26:24 -0000 1.26 +++ bwivar.h 9 Sep 2013 12:07:45 -0000 @@ -324,9 +324,8 @@ struct bwi_phy { int phy_version; uint32_t phy_flags; /* BWI_PHY_F_ */ - uint16_t phy_tbl_ctrl; - uint16_t phy_tbl_data_lo; - uint16_t phy_tbl_data_hi; + uint16_t phy_tbl_dir; + uint16_t phy_tbl_addr; void (*phy_init)(struct bwi_mac *); }; @@ -334,6 +333,9 @@ struct bwi_phy { #define BWI_PHY_F_CALIBRATED 0x1 #define BWI_PHY_F_LINKED 0x2 #define BWI_CLEAR_PHY_FLAGS (BWI_PHY_F_CALIBRATED) +#define BWI_TBL_DIR_UNKNOWN 0x0 +#define BWI_TBL_DIR_READ 0x1 +#define BWI_TBL_DIR_WRITE 0x2 /* TX power control */ struct bwi_tpctl {