Qualcommax NSS Build

i have not tested.

i am away for the next 9 days.

as tempting as it is to start remote flashing, i cannot afford our iot going down.

once im back ill probably break it up into sections (gcc 14 separately, then just the target opts etc)... and see how that goes.

im away so i wont be playing for a few days but just fyi:

just as someone else reported above, when just for kicks i merged in the bdf patch you posted before... my ipq8074 devices would refuse to boot.

failsafe would work fine, so it was ath11k* related as those dont load in failsafe.

when i am back ill get the kernel logs off the uart and let you know.

@AgustinLorenzo can batman-adv be added to your build? And howto setup vlan's.
If batman-adv is not possible, how to user mesh an vlans's?
Thanx in advance

qosmio modified my patch. i already wrote him what his misstakes where. use my version and all is fine. i can only comment on things i wrote and not about any modification. i can tell you that this code is tested on all chipsets including 8074 and my patch code will also not work if you use any other firmware then 2.12 (or you modify the bdf template version to match any older)

1 Like

ah was not aware of the changes.

I used the one off his gist assumed it was a copy paste outside of the target files.

thx!

for those with some time to burn i highly recommend @BrainSlayer very detailed qca wiki at

https://wiki.dd-wrt.com/wiki/index.php/QCA_wireless_settings#Advanced_Settings

although some of it looks to apply only to older chipsets most of it is still relevant for us. yes it's for dd-wrt but none the less much of it can be tuned via hostapd.

the gem here is that the above wiki actually explains why... not just "set x to y" without much of an explain why and what it does.

BTW @BrainSlayer I had the same issues with smps. it would drop down to the single antenna and on wake up for whatever reason it wouldn't jump back up. can this be disabled on the ap end easily for those not running dd-wrt? I've noticed that very rarely but sometimes the Intel ax2** driver for win will ignore the setting set in advanced and will signal to the ap that it wants smps dynamic. would love to turn this off on the ap end right out... looks like ddwrt has this option.

1 Like

smps can be disabled with a simple hostapd setting. its part of the ht_caps. you simply can remove it

here is the patch https://w1.fi/cgit/hostap/commit/?id=466e48dcd75f67889bc7ffbbda01adbc86ac8eaf , so looks like stations make the decision on if SMPS should be used or not regardless of what is / isnt sent in the hostapd flags on association? eg: you cannot disable it on the ap end :frowning:


edit:

at least on openwrt that seams to be the case:

root@OPENWRT-SALON:/var/run# logread | grep SMPS ;
Sat Aug 10 11:32:56 2024 daemon.notice hostapd: phy1-ap0: STA-OPMODE-SMPS-MODE-CHANGED 08:9d:xx...
root@OPENWRT-SALON:/var/run# cat /var/run/hostapd*conf | grep SMPS | wc -l
0

so in owrt at least even though no SMPS flags are set in hostapd*conf files, SMPS is active... im 99% sure this is the case for all recent hostapd builds openwrt or not...

the patch wasnt that recent btw... when i say recent... just saying hostapd has been in dev for a long time... i dont remember when but this was like a 2020 patch.


edit 2 : i admit, even though you see an SMPS msg in the hostapd logs, does not mean its actually working. also, i do not really know how smps is supposed to work... what i mean by that is:

is it something that the station notifys the ap of and the ap MUST accept?

or is it something that the ap advertises to the station on association and then the station knows if it can / cannot use it.


when i did research on the subject i found (im 99% sure on this) there was an update to hostapd that basically forced it on and your options were essentially

ON
STATIC
DYNAMIC

the reasoning they gave in the patch thread was that its part of the spec

i'll do my best to find the thread, i dont want to send you down some rabbit hole but im 99% sure on this. ill find the thread.

Is this the full patch code? Do I need to patch any other files?

the best way to find out is to try!

remove smps from ht caps. thats all. i dont know what you mean for the rest. if the smps flags arent included in ht caps, it will not be broadcasted as capability in any beacon and it will be disabled in driver code. no station can force the ap to anything if the ap isnt capable of it. if i correct understand the hostap patch it enforces the ap todo always smps and removes the configuration ability for it

i reverted that patch now to allow the ability to disable it like in the past. lets see how it goes for me

1 Like

if you happen to have a win laptop with an Intel adapter you can force the smps mode changes manually by going into advanced props of the wifi adapter

it's there

switching between static and dynamic you should see hostapd output the mode change line in the log

if it's truly disabled then you should see nothing in the hostapd log

i have this intel ax210 shit adapter. (the ping pong wifi system as i name it)
sometimes you have to power it off to get it working again

here a way more detailed and easier to understand variant of this patch. also with offset corrections since the offsets used in openwrt scripts where partially not correct and did not take care about the fact that the regdomain is u32 and not u16

Index: core.c
===================================================================
--- core.c      (revision 8024)
+++ core.c      (working copy)
@@ -23,6 +23,10 @@ module_param_named(nss_offload, nss_offload, uint,
 MODULE_PARM_DESC(nss_offload, "Enable NSS Offload support");
 #endif

+static int poweroffset=0;
+module_param_named(poweroffset, poweroffset, uint, 0644);
+MODULE_PARM_DESC(poweroffset, "power offset for power table. negative values are permitted. units in 0.25db");
+
 unsigned int ath11k_debug_mask;
 EXPORT_SYMBOL(ath11k_debug_mask);
 module_param_named(debug_mask, ath11k_debug_mask, uint, 0644);
@@ -1387,6 +1391,686 @@ int ath11k_core_fetch_board_data_api_1(struct ath1
        return 0;
 }

+static void calcrawchecksum(const void *caldata, int offset, int size)
+{
+       int i;
+       u16 *cdata = (u16 *)caldata;
+       u16 *ptr_eeprom = (u16 *)caldata;
+       u16 crc = 0;
+       cdata[offset] = 0;
+       for (i = 0; i < size; i += 2) {
+               crc ^= le16_to_cpu(*ptr_eeprom);
+               ptr_eeprom++;
+       }
+       crc = ~crc;
+       cdata[offset] = cpu_to_le16(crc);
+}
+
+static void calcchecksum(void *caldata, int size)
+{
+       calcrawchecksum(caldata, 5, size);
+}
+
+void *getsectionbyid(const void *bd, u16 id, u16 *nvlen)
+{
+       u16 *section = (u16 *)bd;
+       u8 *data = (u8 *)bd;
+       while (section[0] <= id) {
+               if (section[0] == id) {
+                       if (nvlen)
+                               *nvlen = section[1] - 4;
+                       return data + 8; // return without header
+               }
+               data += section[1] + 4;
+               section = (u16 *)data;
+       }
+       return NULL;
+}
+
+struct bdfmacaddr {
+       u8 val[6];
+} __packed;
+
+struct bdfhcaconfig {
+       u16 type;
+       u16 id;
+       u32 hwId;
+       u32 revId;
+       u32 chainMask;
+} __packed;
+
+struct bdfradardetconfig {
+       u16 radar_pd_ma_th_low;
+       u16 radar_pd_ma_th_high;
+       u16 radar_pd_jump_th;
+       u16 radar_pd_ma_th_high_dur_cac;
+       u16 radar_pd_jump_th_dur_cac;
+       u8 radar_time_amp_th;
+       u8 radar_time_amp_th_ext;
+       u8 radar_time_amp_th_dur_cac;
+       u8 radar_time_amp_th_ext_dur_cac;
+       u8 radar_zero_cross_noise_thr;
+       u8 reserved[5];
+} __packed;
+
+struct baseheader_8074 {
+       u16 nvId;
+       u16 nvLen;
+       u32 nvFlag;
+       u16 length;
+       u16 checksum;
+       u8 templateVerMinor;
+       u8 templateVerMajor;
+       struct bdfmacaddr macaddr[6];
+       u8 reserved[2];
+       u32 regDmn;
+       u8 refDesignId;
+       u8 customerId;
+       u8 projectId;
+       u8 boardDataRev;
+       u8 rfSilent;
+       u8 wlanLedGpio;
+       u8 nvMacFlag;
+       u8 calSmVersion;
+       u32 concurrencyModeMask;
+       u32 commonBoardFlags;
+       u16 overwriteCdacIn;
+       u16 overwriteCdacOut;
+       u16 otpCdacIn;
+       u16 otpCdacOut;
+       u8 fineCorrectionCdacIn;
+       u8 fineCorrectionCdacOut;
+       u16 checkTrainingStatusDelay;
+       u8 intPaConfig_rtcExSel;
+       u8 mipiPowerMode;
+       u8 calRFId;
+       u8 calBBId;
+       u8 dbsTableSelect[4];
+       u8 future;
+       u8 swreg;
+       u8 clkOutDriveStrengh;
+       u8 spectralShapingSelect;
+       s8 xtalCapInterval[4];
+       u8 custData[20];
+       u32 hwCReserved;
+       u32 boardFlags;
+       struct bdfhcaconfig hcaconfig[16];
+       s16 normal_maxCCApwr[8][4];
+       s16 dtim_maxCCApwr[8];
+       s8 rssiOffset[8];
+       u8 coexFlags;
+       u8 coexConfig;
+       s16 normal_maxCCApwr_1x1[8][4];
+       u32 swreg32;
+       u16 tpcCalVersion;
+       u16 calVersion;
+       u16 iniVersion;
+       u8 numMacAddr;
+       u8 numPhy;
+       u32 fwVersion;
+       u16 bdfVersion;
+       u8 cck_fir_wb_sel;
+       u8 defaultRFMode;
+       u8 fenType;
+       u8 bdfTemplateVer[3];
+       u8 regMismatchFeatureEnable;
+       u8 regMismatchIndicator;
+       u8 DfsRssiThreshold;
+       u8 enableRegulatory5Dot9;
+       u8 perPacketCMFeatureEnable;
+       struct bdfradardetconfig radarDetConfig[2];
+       u8 DfsRssiThresholdExtFlag;
+       u8 DfsRssiThreshold40;
+       u8 DfsRssiThreshold80;
+       u8 DfsRssiThreshold160;
+       u8 pad;
+       u32 custBoardSpecificFlags[4];
+       u8 futurebd[404];
+} __packed;
+
+struct perphysection_8074 {
+       u32 opflags;
+       u32 featureenable;
+       u32 miscconfig;
+       u32 reserved;
+       u16 txmask2g;
+       u16 rxmask2g;
+       u16 txmask5g;
+       u16 rxmask5g;
+       u8 reserved1[4][10];
+       u8 tpc_flag;
+       u8 xtalSettleTime;
+       s8 smartAntennaEnable;
+       s8 ccaThresh;
+       s8 dbsConcurrencyBackoff[4];
+       u32 regDmn;
+       s8 sensitivityAdjustment;
+       s8 minSensitivityLevel;
+       s8 maxSensitivityLevel;
+       u8 selfGenChainMask;
+       u32 chains_0_7_tx;
+       u32 chains_0_7_rx;
+       u32 reserved2[2];
+       u8 enableDynEdcca;
+       u8 perPhyFuture[71];
+} __packed;
+
+struct perphysection_5018 {
+       u32 opflags;
+       u32 featureenable;
+       u32 miscconfig;
+       u32 reserved;
+       u16 txmask;
+       u16 rxmask;
+       u8 reserved1[4][10];
+       u8 tpc_flag;
+       u8 xtalSettleTime;
+       s8 smartAntennaEnable;
+       s8 ccaThresh;
+       u32 regDmn;
+       s8 sensitivityAdjustment;
+       s8 minSensitivityLevel;
+       s8 maxSensitivityLevel;
+       u8 selfGenChainMask;
+       s16 temperatureSlope0;
+       s16 temperatureSlope1;
+       u8 crossPolar_enablePolDiversity;
+       u8 crossPolar_CTL_degreeOfFreedom;
+       u8 crossPolar_pad[2];
+       u32 crossPolar_antennaChainsToAxisMapping;
+       u8 crossPolarFuture[12];
+       u8 enableDynEdcca;
+       u8 perPhyFuture[71];
+} __packed;
+
+struct perphysection_6018 {
+       u32 opflags;
+       u32 featureenable;
+       u32 miscconfig;
+       u32 reserved;
+       u16 txmask2g;
+       u16 rxmask2g;
+       u16 txmask5g;
+       u16 rxmask5g;
+       u8 reserved1[4][10];
+       u8 tpc_flag;
+       u8 xtalSettleTime;
+       s8 smartAntennaEnable;
+       s8 ccaThresh;
+       s8 dbsConcurrencyBackoff[2];
+       u32 regDmn;
+       s8 sensitivityAdjustment;
+       s8 minSensitivityLevel;
+       s8 maxSensitivityLevel;
+       s16 temperatureSlope0;
+       s16 temperatureSlope1;
+       u8 enableDynEdcca;
+       u8 rxGainLutSel;
+       u8 perPhyFuture[85];
+} __packed;
+
+struct perphysection_9074 {
+       u32 opflags;
+       u32 featureenable;
+       u32 miscconfig;
+       u32 reserved;
+       u16 txmask;
+       u16 rxmask;
+       u8 reserved1[4][10];
+
+       u8 tpc_flag;
+       u8 xtalSettleTime;
+       s8 smartAntennaEnable;
+       s8 ccaThresh;
+       u32 regDmn;
+       s8 sensitivityAdjustment;
+       s8 minSensitivityLevel;
+       s8 maxSensitivityLevel;
+       u8 selfGenChainMask;
+       u8 dfsDisable;
+       u8 pad[3];
+       u32 chains_0_7_tx;
+       u32 chains_0_7_rx;
+       u32 reserved2[2];
+       u8 crossPolar_enablePolDiversity;
+       u8 crossPolar_CTL_degreeOfFreedom;
+       u8 crossPolar_pad[2];
+       u32 crossPolar_antennaChainsToAxisMapping;
+       u8 crossPolarFuture[12];
+       u8 enableDynEdcca;
+       u8 perPhyFuture[55];
+} __packed;
+
+static void removeregdomain(struct ath11k_base *ab, const void *data)
+{
+       struct baseheader_8074 *header = (struct baseheader_8074 *)data;
+       u16 *s = (u16 *)data;
+       u8 *s1 = (u8 *)data;
+       if (header->regDmn)
+               ath11k_info(ab, "remove regdomain0 0x%04x\n", header->regDmn);
+       header->regDmn = 0;
+       struct perphysection_8074 *section_8074 = (struct perphysection_8074 *)getsectionbyid(data, 2, NULL);
+       struct perphysection_5018 *section_5018 = (struct perphysection_5018 *)section_8074;
+       struct perphysection_6018 *section_6018 = (struct perphysection_6018 *)section_8074;
+       struct perphysection_9074 *section_9074 = (struct perphysection_9074 *)section_8074;
+
+       switch (ab->hw_rev) {
+       case ATH11K_HW_IPQ8074:
+               if (section_8074[0].regDmn)
+                       ath11k_info(ab, "remove regdomain1 0x%04x\n", section_8074[0].regDmn);
+               section_8074[0].regDmn = 0;
+
+               if (section_8074[1].regDmn)
+                       ath11k_info(ab, "remove regdomain2 0x%04x\n", section_8074[1].regDmn);
+               section_8074[1].regDmn = 0;
+
+               if (section_8074[2].regDmn)
+                       ath11k_info(ab, "remove regdomain3 0x%04x\n", section_8074[2].regDmn);
+               section_8074[2].regDmn = 0;
+
+               break;
+       case ATH11K_HW_IPQ5018_HW10:
+               if (section_5018->regDmn)
+                       ath11k_info(ab, "remove regdomain1 0x%04x\n", section_5018->regDmn);
+               section_5018->regDmn = 0;
+               break;
+       case ATH11K_HW_QCN9074_HW10:
+               if (section_9074->regDmn)
+                       ath11k_info(ab, "remove regdomain1 0x%04x\n", section_9074->regDmn);
+               section_9074->regDmn = 0;
+               break;
+       case ATH11K_HW_IPQ6018_HW10:
+               if (section_6018[0].regDmn)
+                       ath11k_info(ab, "remove regdomain1 0x%04x\n", section_6018[0].regDmn);
+               section_6018[0].regDmn = 0;
+               if (section_6018[1].regDmn)
+                       ath11k_info(ab, "remove regdomain2 0x%04x\n", section_6018[1].regDmn);
+               section_6018[1].regDmn = 0;
+               break;
+       default:
+               break;
+       }
+}
+enum {
+       WHAL_OPFLAGS_11A = 0x00000001,
+       WHAL_OPFLAGS_11G = 0x00000002,
+       WHAL_OPFLAGS_5G_HT40 = 0x00000004,
+       WHAL_OPFLAGS_2G_HT40 = 0x00000008,
+       WHAL_OPFLAGS_5G_HT20 = 0x00000010,
+       WHAL_OPFLAGS_2G_HT20 = 0x00000020,
+       WHAL_OPFLAGS_5G_VHT20 = 0x00000040,
+       WHAL_OPFLAGS_2G_VHT20 = 0x00000080,
+       WHAL_OPFLAGS_5G_VHT40 = 0x00000100,
+       WHAL_OPFLAGS_2G_VHT40 = 0x00000200,
+       WHAL_OPFLAGS_5G_VHT80 = 0x00000400,
+       WHAL_OPFLAGS_5G_VHT80P80 = 0x00000800,
+       WHAL_OPFLAGS_5G_VHT160 = 0x00001000
+};
+
+struct regdb_entry_8074 {
+       u16 country_code;
+       u16 reg_dmn_pair_id;
+       u8 alpha[3];
+       u8 alpha2_11d[3];
+       u8 max_bw_2g;
+       u8 max_bw_5g;
+       u8 phymode_bitmap;
+       u8 pad;
+};
+
+struct regdb_entry_9074 {
+       u16 country_code;
+       u16 reg_dmn_pair_id;
+       u8 super_dmn_6g_id;
+       u8 alpha[3];
+       u8 alpha2_11d[3];
+       u8 max_bw_2g;
+       u8 max_bw_5g;
+       u8 max_bw_6g;
+       u8 phymode_bitmap;
+       u8 flags;
+};
+
+struct regdb_8074 {
+       u16 nvid;
+       u16 nvlen;
+       u32 nvflag;
+       struct regdb_entry_8074 entry[0];
+};
+struct regdb_9074 {
+       u16 nvid;
+       u16 nvlen;
+       u32 nvflag;
+       struct regdb_entry_9074 entry[0];
+};
+
+void patchrawregdb(struct ath11k_base *ab, const void *bd)
+{
+       struct regdb_entry_8074 *regdb1 = (struct regdb_entry_8074 *)bd;
+       struct regdb_entry_9074 *regdb2 = (struct regdb_entry_9074 *)bd;
+
+       /*
+        * we detect here which format is used. since some chipsets like 9074 do make use of both formats
+        * so easiest way is to check for the reg domain code which is always identical as first entry
+        */
+       if (regdb1[0].alpha[0] == 65 && regdb1[0].alpha[1] == 70) {
+               int i;
+               ath11k_info(ab, "patch reg db in ipq8074 format\n");
+               for (i = 0; i < 220; i++) {
+                       if (regdb1[i].max_bw_5g == 80) {
+                               ath11k_info(ab, "patch entry %d\n", i);
+                               regdb1[i].max_bw_5g = 160;
+                       }
+               }
+       } else if (regdb2[0].alpha[0] == 65 && regdb2[0].alpha[1] == 70) {
+               int i;
+               ath11k_info(ab, "patch reg db in qcn9074 format\n");
+               for (i = 0; i < 220; i++) {
+                       if (regdb2[i].max_bw_5g == 80) {
+                               ath11k_info(ab, "patch entry %d\n", i);
+                               regdb2[i].max_bw_5g = 160;
+                       }
+               }
+       } else {
+               ath11k_info(ab, "something wrong. did not find a regdb\n");
+       }
+}
+
+void patchregdb(struct ath11k_base *ab, void *bd)
+{
+       int id;
+       int i;
+       switch (ab->hw_rev) {
+       case ATH11K_HW_IPQ8074:
+               id = 20;
+               break;
+       case ATH11K_HW_IPQ6018_HW10:
+               id = 20;
+               break;
+       case ATH11K_HW_QCN9074_HW10:
+               id = 19;
+               break;
+       case ATH11K_HW_IPQ5018_HW10:
+               id = 20;
+               break;
+       default:
+               return;
+       }
+       patchrawregdb(ab, getsectionbyid(bd, id, NULL));
+}
+
+struct targetpower {
+       s8 power[0];
+};
+
+static void showdbm(struct ath11k_base *ab, const char *lead, int val)
+{
+       ath11k_info(ab, "%s %d.%d dbm\n", lead, val / 4, (((val % 4) * 10) % 4) ? ((val % 4) * 100) / 4 : ((val % 4) * 10) / 4);
+}
+/* units in 0.25 db */
+static void patchpower(struct ath11k_base *ab, const void *bd, int poweroffset)
+{
+       int id;
+       int i;
+       u16 nvlen;
+       struct targetpower *power;
+       switch (ab->hw_rev) {
+       case ATH11K_HW_IPQ8074:
+               id = 12;
+               break;
+       case ATH11K_HW_IPQ6018_HW10:
+               id = 12;
+               break;
+       case ATH11K_HW_QCN9074_HW10:
+               id = 11;
+               break;
+       case ATH11K_HW_IPQ5018_HW10:
+               id = 11;
+               break;
+       default:
+               return;
+       }
+       power = (struct targetpower *)getsectionbyid(bd, id, &nvlen);
+       int max = -255;
+       for (i = 0; i < nvlen; i++) {
+               if ((power->power[i]) > max)
+                       max = power->power[i];
+       }
+       showdbm(ab, "maximum calibrated power", max);
+       if (max + poweroffset > 126) {
+               poweroffset = 126 - max;
+               showdbm(ab, "limit poweroffset to", poweroffset);
+       }
+       for (i = 0; i < nvlen; i++) {
+               int newpower = power->power[i] + poweroffset;
+               if (power->power[i] && newpower >= -40 && newpower <= 126)
+                       power->power[i] = newpower;
+       }
+       if (poweroffset) {
+               max = -255;
+               for (i = 0; i < nvlen; i++) {
+                       if ((power->power[i]) > max)
+                               max = power->power[i];
+               }
+               showdbm(ab, "new maximum calibrated power is", max);
+       }
+}
+#if 0
+struct gainperchanperchain {
+       u8 gain[4];
+};
+struct perchain2g {
+       u8 gainfreq[3];
+       u8 pad;
+       struct gainperchanperchain gain[3];
+};
+struct perchain5g {
+       u8 gainfreq[8];
+       struct gainperchanperchain gain[8];
+};
+struct antennagain_8074 {
+       u16 nvid;
+       u16 nvlen;
+       u32 nvflag;
+       struct perchain5g gain5g[3];
+       struct perchain2g gain2g;
+       u8 featureenable;
+};
+
+
+/* units in 0.25 db */
+static void patchantennagain(struct ath11k_base *ab, const void *bd)
+{
+       int id;
+       int i;
+       u16 nvlen;
+       struct targetpower *power;
+       switch (ab->hw_rev) {
+       case ATH11K_HW_IPQ8074:
+               id = 22;
+               break;
+       case ATH11K_HW_IPQ6018_HW10:
+               id = 22;
+               break;
+       case ATH11K_HW_QCN9074_HW10:
+               id = 20;
+               break;
+       case ATH11K_HW_IPQ5018_HW10:
+               id = 21;
+               break;
+       default:
+               return;
+       }
+       power = (struct targetpower *)getsectionbyid(bd, id, &nvlen);
+       int max = 0;
+       for (i = 0; i < nvlen; i++) {
+               if ((power->power[i]) > max)
+                       max = power->power[i];
+       }
+       showdbm(ab, "antenna gain", max);
+}
+#endif
+
+static void patchradiolimits(struct ath11k_base *ab, const void *bd)
+{
+       u8 *data = (u8 *)bd;
+       if (ab->hw_rev != ATH11K_HW_IPQ8074)
+               return;
+       switch (data[557]) {
+       case 0:
+               ath11k_info(ab, "RF_MODE: PHYA Only\n");
+               break;
+       case 1:
+               ath11k_info(ab, "RF_MODE: DBS PHYA=5G, PHYB=2.4G\n");
+               break;
+       case 2:
+               ath11k_info(ab, "RF_MODE: SBS PHYA0=5G, PHYA1=5G\n");
+               break;
+       case 3:
+               ath11k_info(ab, "RF_MODE: PHYB Only\n");
+               break;
+       case 4:
+               ath11k_info(ab, "RF_MODE: DBS_SBS PHYA0=5G (lower freq), PHYA1=5G (upper freq), PHYB=2.4G\n");
+               //              ath11k_info(ab, "patch to mode 5\n");
+               //              data[557] = 5;
+               break;
+       case 5:
+               ath11k_info(ab, "RF_MODE: DBS OR SBS PHYA0=5G, PHYA1=5G, PHYB=2.4G\n");
+               break;
+       }
+}
+
+struct boardflags {
+       u32 opflags;
+       u32 featureenable;
+       u32 miscconfig;
+       u32 reserved;
+       u16 txmask2g;
+       u16 rxmask2g;
+       u16 txmask5g;
+       u16 rxmask5g;
+};
+
+struct feature6g {
+       u8 enable7115Chan; //    1
+       u8 afc_local_rsvd; //    0
+       u8 Deployment_Enable; //         1
+       u8 Deployment_Type; //   1
+       u8 Power_mode_mask; //   7
+};
+
+void patchvht160(struct ath11k_base *ab, const void *data, int phynum, int type)
+{
+       u8 *s = (u8 *)data;
+       u32 *tmp;
+       u8 *regdb = (u8 *)data;
+       struct perphysection_8074 *phy = (struct perphysection_8074 *)getsectionbyid(data, 2, NULL);
+       struct feature6g *f6g = (struct feature6g *)&regdb[603];
+       struct baseheader_8074 *header = (struct baseheader_8074 *)data;
+       if (!data)
+               return;
+       header->commonBoardFlags &= ~(1 << 13);
+       switch (phynum) {
+       case 0:
+               if ((phy->opflags & WHAL_OPFLAGS_5G_VHT80) && !(phy->opflags & WHAL_OPFLAGS_5G_VHT160)) {
+                       ath11k_info(ab, "patch board1 flags %X to %X\n", phy->opflags,
+                                   phy->opflags | WHAL_OPFLAGS_5G_VHT80P80 | WHAL_OPFLAGS_5G_VHT160);
+                       phy->opflags |= WHAL_OPFLAGS_5G_VHT80P80;
+                       phy->opflags |= WHAL_OPFLAGS_5G_VHT160;
+               }
+               /*              if (type) {OA
+                       f->miscconfig |= 0x400; // 6ghz
+                       f6g->enable7115Chan=1;
+                       f6g->Deployment_Enable=1;
+                       f6g->Deployment_Type=1;
+                       f6g->Power_mode_mask=7;
+               }*/
+               break;
+       case 1:
+               if ((phy[1].opflags & WHAL_OPFLAGS_5G_VHT80) && !(phy[1].opflags & WHAL_OPFLAGS_5G_VHT160)) {
+                       ath11k_info(ab, "patch board2 flags %X to %X\n", phy[1].opflags,
+                                   phy[1].opflags | WHAL_OPFLAGS_5G_VHT80P80 | WHAL_OPFLAGS_5G_VHT160);
+                       phy[1].opflags |= WHAL_OPFLAGS_5G_VHT80P80;
+                       phy[1].opflags |= WHAL_OPFLAGS_5G_VHT160;
+               }
+               break;
+       case 2:
+               if ((phy[2].opflags & WHAL_OPFLAGS_5G_VHT80) && !(phy[2].opflags & WHAL_OPFLAGS_5G_VHT160)) {
+                       ath11k_info(ab, "patch board3 flags %X to %X\n", phy[2].opflags,
+                                   phy[2].opflags | WHAL_OPFLAGS_5G_VHT80P80 | WHAL_OPFLAGS_5G_VHT160);
+                       phy[2].opflags |= WHAL_OPFLAGS_5G_VHT80P80;
+                       phy[2].opflags |= WHAL_OPFLAGS_5G_VHT160;
+               }
+               break;
+       }
+       /* patch max bw 5g to 160 */
+       patchregdb(ab, regdb);
+}
+
+void show_bdf_version(const char *name, struct ath11k_base *ab, const void *bd)
+{
+       u8 *data = (u8 *)bd;
+       u32 offset;
+       u8 patch[3];
+       u32 size = 0x10000;
+       if (!bd)
+               return;
+       switch (ab->hw_rev) {
+       case ATH11K_HW_IPQ8074:
+               patch[0] = 7;
+               patch[1] = 2;
+               patch[2] = 3;
+               offset = 559;
+               size = 0x20000;
+               removeregdomain(ab, bd);
+               patchvht160(ab, bd, 0, 0);
+               patchvht160(ab, bd, 1, 0);
+               patchvht160(ab, bd, 2, 0);
+               break;
+       case ATH11K_HW_IPQ6018_HW10:
+               patch[0] = 1;
+               patch[1] = 4;
+               patch[2] = 3;
+               offset = 495;
+               size = 0x10000;
+               removeregdomain(ab, bd);
+               break;
+       case ATH11K_HW_QCN9074_HW10:
+               patch[0] = 4;
+               patch[1] = 2;
+               patch[2] = 0;
+               offset = 555;
+               size = 0x20000;
+               removeregdomain(ab, bd);
+               patchvht160(ab, bd, 0, 1);
+               break;
+       case ATH11K_HW_IPQ5018_HW10:
+               patch[0] = 3;
+               patch[1] = 4;
+               patch[2] = 0;
+               offset = 0x1eb;
+               size = 0x20000;
+               removeregdomain(ab, bd);
+               break;
+       default:
+               return;
+       }
+
+       if (data) {
+               //              if (data[offset] != patch[0]) {
+               //                      ath11k_info(ab, "warning. incompatible bdf template revision v%d.%d.%d, boardrev %d (major version must be %d)\n", data[offset], data[offset+1], data[offset+2], data[59], patch[0]);
+               //              } else
+               {
+                       ath11k_info(ab, "%s template revision v%d.%d.%d, boardrev %d, patch to v%d.%d.%d\n", name, data[offset],
+                                   data[offset + 1], data[offset + 2], data[59], patch[0], patch[1], patch[2]);
+                       memcpy(&data[offset], patch, 3);
+                       patchpower(ab, data, poweroffset);
+                       patchradiolimits(ab, data);
+                       calcchecksum(data, size);
+               }
+       }
+}
+
 #define BOARD_NAME_SIZE 200
 int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
 {
@@ -1412,8 +2096,10 @@ int ath11k_core_fetch_bdf(struct ath11k_base *ab,
                                                 ATH11K_BD_IE_BOARD,
                                                 ATH11K_BD_IE_BOARD_NAME,
                                                 ATH11K_BD_IE_BOARD_DATA);
-       if (!ret)
+       if (!ret) {
+               show_bdf_version("bdf", ab, bd->data);
                goto exit;
+       }

        fallback_boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL);
        if (!fallback_boardname) {
@@ -1432,9 +2118,11 @@ int ath11k_core_fetch_bdf(struct ath11k_base *ab,
                                                 ATH11K_BD_IE_BOARD,
                                                 ATH11K_BD_IE_BOARD_NAME,
                                                 ATH11K_BD_IE_BOARD_DATA);
-       if (!ret)
+       if (!ret) {
+               show_bdf_version("bdf", ab, bd->data);
                goto exit;
-
+       }
+
        chip_id_boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL);
        if (!chip_id_boardname) {
                ret = -ENOMEM;
@@ -1453,9 +2141,11 @@ int ath11k_core_fetch_bdf(struct ath11k_base *ab,
                                                 ATH11K_BD_IE_BOARD_NAME,
                                                 ATH11K_BD_IE_BOARD_DATA);

-       if (!ret)
+       if (!ret) {
+               show_bdf_version("bdf", ab, bd->data);
                goto exit;
-
+       }
+
        ab->bd_api = 1;
        ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_DEFAULT_BOARD_FILE);
        if (ret) {
@@ -1472,6 +2162,8 @@ int ath11k_core_fetch_bdf(struct ath11k_base *ab,

                ath11k_err(ab, "failed to fetch board.bin from %s\n",
                           ab->hw_params.fw.dir);
+       } else {
+               show_bdf_version("bdf", ab, bd->data);
        }

 exit:
@@ -1501,8 +2193,11 @@ int ath11k_core_fetch_regdb(struct ath11k_base *ab
                                                 ATH11K_BD_IE_REGDB,
                                                 ATH11K_BD_IE_REGDB_NAME,
                                                 ATH11K_BD_IE_REGDB_DATA);
-       if (!ret)
+       if (!ret) {
+               patchrawregdb(ab, (u8*)bd->data+2);
+               calcrawchecksum(bd->data, 0, bd->len);
                goto exit;
+       }

        ret = ath11k_core_create_bus_type_board_name(ab, default_boardname,
                                                     BOARD_NAME_SIZE);
@@ -1516,14 +2211,19 @@ int ath11k_core_fetch_regdb(struct ath11k_base *ab
                                                 ATH11K_BD_IE_REGDB,
                                                 ATH11K_BD_IE_REGDB_NAME,
                                                 ATH11K_BD_IE_REGDB_DATA);
-       if (!ret)
+       if (!ret){
+               patchrawregdb(ab, (u8*)bd->data+2);
+               calcrawchecksum(bd->data, 0, bd->len);
                goto exit;
-
+       }
        ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_REGDB_FILE_NAME);
        if (ret)
                ath11k_dbg(ab, ATH11K_DBG_BOOT, "failed to fetch %s from %s\n",
                           ATH11K_REGDB_FILE_NAME, ab->hw_params.fw.dir);
-
+       else  {
+               patchrawregdb(ab, (u8*)bd->data+2);
+               calcrawchecksum(bd->data, 0, bd->len);
+       }
 exit:
        if (!ret)
                ath11k_dbg(ab, ATH11K_DBG_BOOT, "fetched regdb\n");

2 Likes

fixed for nss crypto crashes

Index: cryptoapi/v2.0/nss_cryptoapi_skcipher.c
===================================================================
--- cryptoapi/v2.0/nss_cryptoapi_skcipher.c     (revision 57878)
+++ cryptoapi/v2.0/nss_cryptoapi_skcipher.c     (working copy)
@@ -92,10 +92,10 @@
        struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(tfm);

        BUG_ON(!ctx);
-       NSS_CRYPTOAPI_SET_MAGIC(ctx);

        memset(ctx, 0, sizeof(struct nss_cryptoapi_ctx));

+       NSS_CRYPTOAPI_SET_MAGIC(ctx);
        ctx->user = g_cryptoapi.user;
        ctx->stats.init++;
        ctx->sid = NSS_CRYPTO_SESSION_MAX;
@@ -220,11 +220,11 @@
 void nss_cryptoapi_skcipher_done(void *app_data, struct nss_crypto_hdr *ch, uint8_t status)
 {
        struct skcipher_request *req = app_data;
-       struct nss_cryptoapi_ctx *ctx = skcipher_request_ctx(req);
+       struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req);
+       struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(cipher);
        int error;

        BUG_ON(!ch);
-
        /*
         * Check cryptoapi context magic number.
         */
@@ -256,7 +256,7 @@
         * Decrement cryptoapi reference
         */
        nss_cryptoapi_ref_dec(ctx);
-       req->base.complete(&req->base, error);
+       skcipher_request_complete(req, error);
 }

 /*
Index: cryptoapi/v2.0/nss_cryptoapi_aead.c
===================================================================
--- cryptoapi/v2.0/nss_cryptoapi_aead.c (revision 57878)
+++ cryptoapi/v2.0/nss_cryptoapi_aead.c (working copy)
@@ -97,9 +97,9 @@
        bool need_fallback;

        BUG_ON(!ctx);
-       NSS_CRYPTOAPI_SET_MAGIC(ctx);

        memset(ctx, 0, sizeof(struct nss_cryptoapi_ctx));
+       NSS_CRYPTOAPI_SET_MAGIC(ctx);

        ctx->user = g_cryptoapi.user;
        ctx->stats.init++;
Index: cryptoapi/v2.0/nss_cryptoapi_ahash.c
===================================================================
--- cryptoapi/v2.0/nss_cryptoapi_ahash.c        (revision 57878)
+++ cryptoapi/v2.0/nss_cryptoapi_ahash.c        (working copy)
@@ -231,8 +231,10 @@
 void nss_cryptoapi_ahash_done(void *app_data, struct nss_crypto_hdr *ch, uint8_t status)
 {
        struct ahash_request *req = app_data;
-       struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+       struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
+       struct nss_cryptoapi_ctx *ctx = crypto_ahash_ctx(ahash);
        struct nss_cryptoapi_req_ctx *rctx = ahash_request_ctx(req);
+
        uint8_t *hw_hmac;
        int error;

@@ -268,7 +270,7 @@
         * Decrement cryptoapi reference
         */
        nss_cryptoapi_ref_dec(ctx);
-       req->base.complete(&req->base, error);
+       ahash_request_complete(req, error);
 }

 /*
Index: cryptoapi/v2.0/nss_cryptoapi_ablk.c
===================================================================
--- cryptoapi/v2.0/nss_cryptoapi_ablk.c (revision 57878)
+++ cryptoapi/v2.0/nss_cryptoapi_ablk.c (working copy)
@@ -113,9 +113,9 @@
        struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(tfm);

        BUG_ON(!ctx);
-       NSS_CRYPTOAPI_SET_MAGIC(ctx);

        memset(ctx, 0, sizeof(struct nss_cryptoapi_ctx));
+       NSS_CRYPTOAPI_SET_MAGIC(ctx);

        ctx->user = g_cryptoapi.user;
        ctx->stats.init++;

2 Likes

Is this patch the patch of mac80211 or the patch of hostapd?

Which software is this patch for?

@qosmio

hi!

was wondering if I / we could get your most recent recommend re. disable_gro as well as what if any crypto accel is best to use?

re disable_gro I've scrolled above somewhat and most posts says to disable gro as it's skipping nss offloading on some traffic? but it defaults to 0 so gro enabled?

re the crypto the latest posts say don't use either nss or dev crypto but the arm cflags, correct?

if you have ever looked in the software and sourcecode you would know for what it is. dont play if it if you arent skilled how to handle this information. so just wait until qosmio integrated it

1 Like