1 // Author: Xianjun Jiao, Michael Mehari, Wei Liu 2 // SPDX-FileCopyrightText: 2019 UGent 3 // SPDX-License-Identifier: AGPL-3.0-or-later 4 5 static int openwifi_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void *data, int len) 6 { 7 struct openwifi_priv *priv = hw->priv; 8 struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; 9 struct sk_buff *skb; 10 int err; 11 u32 tmp=-1, reg_cat, reg_addr, reg_val, reg_addr_idx, tsft_high, tsft_low; 12 int tmp_int; 13 14 err = nla_parse(tb, OPENWIFI_ATTR_MAX, data, len, openwifi_testmode_policy, NULL); 15 if (err) 16 return err; 17 18 if (!tb[OPENWIFI_ATTR_CMD]) 19 return -EINVAL; 20 21 switch (nla_get_u32(tb[OPENWIFI_ATTR_CMD])) { 22 case OPENWIFI_CMD_SET_GAP: 23 if (!tb[OPENWIFI_ATTR_GAP]) 24 return -EINVAL; 25 tmp = nla_get_u32(tb[OPENWIFI_ATTR_GAP]); 26 printk("%s XPU_REG_CSMA_CFG_write %08x (Check openwifi_conf_tx() in sdr.c to understand)\n", sdr_compatible_str, tmp); 27 xpu_api->XPU_REG_CSMA_CFG_write(tmp); // unit us 28 return 0; 29 case OPENWIFI_CMD_GET_GAP: 30 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); 31 if (!skb) 32 return -ENOMEM; 33 tmp = xpu_api->XPU_REG_CSMA_CFG_read(); 34 if (nla_put_u32(skb, OPENWIFI_ATTR_GAP, tmp)) 35 goto nla_put_failure; 36 return cfg80211_testmode_reply(skb); 37 case OPENWIFI_CMD_SET_SLICE_IDX: 38 if (!tb[OPENWIFI_ATTR_SLICE_IDX]) 39 return -EINVAL; 40 tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_IDX]); 41 printk("%s set openwifi slice_idx in hex: %08x\n", sdr_compatible_str, tmp); 42 if (tmp == MAX_NUM_HW_QUEUE) { 43 printk("%s set openwifi slice_idx reset all queue counter.\n", sdr_compatible_str); 44 xpu_api->XPU_REG_MULTI_RST_write(1<<7); //bit7 reset the counter for all queues at the same time 45 xpu_api->XPU_REG_MULTI_RST_write(0<<7); 46 } else { 47 priv->slice_idx = tmp; 48 } 49 return 0; 50 case OPENWIFI_CMD_GET_SLICE_IDX: 51 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); 52 if (!skb) 53 return -ENOMEM; 54 tmp = priv->slice_idx; 55 if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_IDX, tmp)) 56 goto nla_put_failure; 57 printk("%s get openwifi slice_idx in hex: %08x\n", sdr_compatible_str, tmp); 58 return cfg80211_testmode_reply(skb); 59 case OPENWIFI_CMD_SET_ADDR: 60 if (!tb[OPENWIFI_ATTR_ADDR]) 61 return -EINVAL; 62 tmp = nla_get_u32(tb[OPENWIFI_ATTR_ADDR]); 63 if (priv->slice_idx>=MAX_NUM_HW_QUEUE) { 64 printk("%s set openwifi slice_target_mac_addr(low32) WARNING: current slice idx %d is invalid!\n", sdr_compatible_str, priv->slice_idx); 65 return -EOPNOTSUPP; 66 } else { 67 printk("%s set openwifi slice_target_mac_addr(low32) in hex: %08x to slice %d\n", sdr_compatible_str, tmp, priv->slice_idx); 68 priv->dest_mac_addr_queue_map[priv->slice_idx] = reverse32(tmp); 69 } 70 return 0; 71 case OPENWIFI_CMD_GET_ADDR: 72 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); 73 if (!skb) 74 return -ENOMEM; 75 if (priv->slice_idx>=MAX_NUM_HW_QUEUE) { 76 tmp = -1; 77 } else { 78 tmp = reverse32(priv->dest_mac_addr_queue_map[priv->slice_idx]); 79 } 80 if (nla_put_u32(skb, OPENWIFI_ATTR_ADDR, tmp)) 81 goto nla_put_failure; 82 printk("%s get openwifi slice_target_mac_addr(low32) in hex: %08x of slice %d\n", sdr_compatible_str, tmp, priv->slice_idx); 83 return cfg80211_testmode_reply(skb); 84 85 case OPENWIFI_CMD_SET_SLICE_TOTAL: 86 if (!tb[OPENWIFI_ATTR_SLICE_TOTAL]) 87 return -EINVAL; 88 tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_TOTAL]); 89 if (priv->slice_idx>=MAX_NUM_HW_QUEUE) { 90 printk("%s set SLICE_TOTAL(duration) WARNING: current slice idx %d is invalid!\n", sdr_compatible_str, priv->slice_idx); 91 return -EOPNOTSUPP; 92 } else { 93 printk("%s set SLICE_TOTAL(duration) %d usec to slice %d\n", sdr_compatible_str, tmp, priv->slice_idx); 94 xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((priv->slice_idx<<20)|tmp); 95 } 96 return 0; 97 case OPENWIFI_CMD_GET_SLICE_TOTAL: 98 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); 99 if (!skb) 100 return -ENOMEM; 101 tmp = (xpu_api->XPU_REG_SLICE_COUNT_TOTAL_read()); 102 printk("%s get SLICE_TOTAL(duration) %d usec of slice %d\n", sdr_compatible_str, tmp&0xFFFFF, tmp>>20); 103 if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_TOTAL, tmp)) 104 goto nla_put_failure; 105 return cfg80211_testmode_reply(skb); 106 107 case OPENWIFI_CMD_SET_SLICE_START: 108 if (!tb[OPENWIFI_ATTR_SLICE_START]) 109 return -EINVAL; 110 tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_START]); 111 if (priv->slice_idx>=MAX_NUM_HW_QUEUE) { 112 printk("%s set SLICE_START(duration) WARNING: current slice idx %d is invalid!\n", sdr_compatible_str, priv->slice_idx); 113 return -EOPNOTSUPP; 114 } else { 115 printk("%s set SLICE_START(duration) %d usec to slice %d\n", sdr_compatible_str, tmp, priv->slice_idx); 116 xpu_api->XPU_REG_SLICE_COUNT_START_write((priv->slice_idx<<20)|tmp); 117 } 118 return 0; 119 case OPENWIFI_CMD_GET_SLICE_START: 120 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); 121 if (!skb) 122 return -ENOMEM; 123 tmp = (xpu_api->XPU_REG_SLICE_COUNT_START_read()); 124 printk("%s get SLICE_START(duration) %d usec of slice %d\n", sdr_compatible_str, tmp&0xFFFFF, tmp>>20); 125 if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_START, tmp)) 126 goto nla_put_failure; 127 return cfg80211_testmode_reply(skb); 128 129 case OPENWIFI_CMD_SET_SLICE_END: 130 if (!tb[OPENWIFI_ATTR_SLICE_END]) 131 return -EINVAL; 132 tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_END]); 133 if (priv->slice_idx>=MAX_NUM_HW_QUEUE) { 134 printk("%s set SLICE_END(duration) WARNING: current slice idx %d is invalid!\n", sdr_compatible_str, priv->slice_idx); 135 return -EOPNOTSUPP; 136 } else { 137 printk("%s set SLICE_END(duration) %d usec to slice %d\n", sdr_compatible_str, tmp, priv->slice_idx); 138 xpu_api->XPU_REG_SLICE_COUNT_END_write((priv->slice_idx<<20)|tmp); 139 } 140 return 0; 141 case OPENWIFI_CMD_GET_SLICE_END: 142 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); 143 if (!skb) 144 return -ENOMEM; 145 tmp = (xpu_api->XPU_REG_SLICE_COUNT_END_read()); 146 printk("%s get SLICE_END(duration) %d usec of slice %d\n", sdr_compatible_str, tmp&0xFFFFF, tmp>>20); 147 if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_END, tmp)) 148 goto nla_put_failure; 149 return cfg80211_testmode_reply(skb); 150 151 // case OPENWIFI_CMD_SET_SLICE_TOTAL1: 152 // if (!tb[OPENWIFI_ATTR_SLICE_TOTAL1]) 153 // return -EINVAL; 154 // tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_TOTAL1]); 155 // printk("%s set SLICE_TOTAL1(duration) to %d usec\n", sdr_compatible_str, tmp); 156 // // xpu_api->XPU_REG_SLICE_COUNT_TOTAL1_write(tmp); 157 // return 0; 158 // case OPENWIFI_CMD_GET_SLICE_TOTAL1: 159 // skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); 160 // if (!skb) 161 // return -ENOMEM; 162 // // tmp = (xpu_api->XPU_REG_SLICE_COUNT_TOTAL1_read()); 163 // if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_TOTAL1, tmp)) 164 // goto nla_put_failure; 165 // return cfg80211_testmode_reply(skb); 166 167 // case OPENWIFI_CMD_SET_SLICE_START1: 168 // if (!tb[OPENWIFI_ATTR_SLICE_START1]) 169 // return -EINVAL; 170 // tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_START1]); 171 // printk("%s set SLICE_START1(duration) to %d usec\n", sdr_compatible_str, tmp); 172 // // xpu_api->XPU_REG_SLICE_COUNT_START1_write(tmp); 173 // return 0; 174 // case OPENWIFI_CMD_GET_SLICE_START1: 175 // skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); 176 // if (!skb) 177 // return -ENOMEM; 178 // // tmp = (xpu_api->XPU_REG_SLICE_COUNT_START1_read()); 179 // if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_START1, tmp)) 180 // goto nla_put_failure; 181 // return cfg80211_testmode_reply(skb); 182 183 // case OPENWIFI_CMD_SET_SLICE_END1: 184 // if (!tb[OPENWIFI_ATTR_SLICE_END1]) 185 // return -EINVAL; 186 // tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_END1]); 187 // printk("%s set SLICE_END1(duration) to %d usec\n", sdr_compatible_str, tmp); 188 // // xpu_api->XPU_REG_SLICE_COUNT_END1_write(tmp); 189 // return 0; 190 // case OPENWIFI_CMD_GET_SLICE_END1: 191 // skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); 192 // if (!skb) 193 // return -ENOMEM; 194 // // tmp = (xpu_api->XPU_REG_SLICE_COUNT_END1_read()); 195 // if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_END1, tmp)) 196 // goto nla_put_failure; 197 // return cfg80211_testmode_reply(skb); 198 199 case OPENWIFI_CMD_SET_RSSI_TH: 200 if (!tb[OPENWIFI_ATTR_RSSI_TH]) 201 return -EINVAL; 202 tmp = nla_get_u32(tb[OPENWIFI_ATTR_RSSI_TH]); 203 // printk("%s set RSSI_TH to %d\n", sdr_compatible_str, tmp); 204 // xpu_api->XPU_REG_LBT_TH_write(tmp); 205 // return 0; 206 printk("%s WARNING Please use command: sdrctl dev sdr0 set reg drv_xpu 0 reg_value! (1~2047, 0 means AUTO)!\n", sdr_compatible_str); 207 return -EOPNOTSUPP; 208 case OPENWIFI_CMD_GET_RSSI_TH: 209 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); 210 if (!skb) 211 return -ENOMEM; 212 tmp_int = rssi_half_db_to_rssi_dbm(xpu_api->XPU_REG_LBT_TH_read(), priv->rssi_correction); //rssi_dbm 213 tmp = (-tmp_int); 214 if (nla_put_u32(skb, OPENWIFI_ATTR_RSSI_TH, tmp)) 215 goto nla_put_failure; 216 return cfg80211_testmode_reply(skb); 217 218 case OPENWIFI_CMD_SET_TSF: 219 printk("openwifi_set_tsf_1"); 220 if ( (!tb[OPENWIFI_ATTR_HIGH_TSF]) || (!tb[OPENWIFI_ATTR_LOW_TSF]) ) 221 return -EINVAL; 222 printk("openwifi_set_tsf_2"); 223 tsft_high = nla_get_u32(tb[OPENWIFI_ATTR_HIGH_TSF]); 224 tsft_low = nla_get_u32(tb[OPENWIFI_ATTR_LOW_TSF]); 225 xpu_api->XPU_REG_TSF_LOAD_VAL_write(tsft_high,tsft_low); 226 printk("%s openwifi_set_tsf: %08x%08x\n", sdr_compatible_str,tsft_high,tsft_low); 227 return 0; 228 229 case REG_CMD_SET: 230 if ( (!tb[REG_ATTR_ADDR]) || (!tb[REG_ATTR_VAL]) ) 231 return -EINVAL; 232 reg_addr = nla_get_u32(tb[REG_ATTR_ADDR]); 233 reg_val = nla_get_u32(tb[REG_ATTR_VAL]); 234 reg_cat = ((reg_addr>>16)&0xFFFF); 235 reg_addr = (reg_addr&0xFFFF); 236 reg_addr_idx = (reg_addr>>2); 237 printk("%s recv set cmd reg cat %d addr %08x val %08x idx %d\n", sdr_compatible_str, reg_cat, reg_addr, reg_val, reg_addr_idx); 238 if (reg_cat==SDRCTL_REG_CAT_RF) { 239 // printk("%s WARNING reg cat 1 (rf) is not supported yet!\n", sdr_compatible_str); 240 // return -EOPNOTSUPP; 241 if (reg_addr_idx>=0 && reg_addr_idx<MAX_NUM_RF_REG) { 242 priv->rf_reg_val[reg_addr_idx]=reg_val; 243 if (reg_addr_idx==RF_TX_REG_IDX_ATT) {//change the tx ON att (if a RF chain is ON) 244 tmp = ad9361_get_tx_atten(priv->ad9361_phy, 1); 245 printk("%s ad9361_get_tx_atten ant0 %d\n",sdr_compatible_str, tmp); 246 if (tmp<AD9361_RADIO_OFF_TX_ATT) { 247 err = ad9361_set_tx_atten(priv->ad9361_phy, AD9361_RADIO_ON_TX_ATT+reg_val, true, false, true); 248 if (err < 0) { 249 printk("%s WARNING ad9361_set_tx_atten ant0 %d FAIL!\n",sdr_compatible_str, AD9361_RADIO_ON_TX_ATT+reg_val); 250 return -EIO; 251 } else { 252 printk("%s ad9361_set_tx_atten ant0 %d OK\n",sdr_compatible_str, AD9361_RADIO_ON_TX_ATT+reg_val); 253 } 254 } 255 tmp = ad9361_get_tx_atten(priv->ad9361_phy, 2); 256 printk("%s ad9361_get_tx_atten ant1 %d\n",sdr_compatible_str, tmp); 257 if (tmp<AD9361_RADIO_OFF_TX_ATT) { 258 err = ad9361_set_tx_atten(priv->ad9361_phy, AD9361_RADIO_ON_TX_ATT+reg_val, false, true, true); 259 if (err < 0) { 260 printk("%s WARNING ad9361_set_tx_atten ant1 %d FAIL!\n",sdr_compatible_str, AD9361_RADIO_ON_TX_ATT+reg_val); 261 return -EIO; 262 } else { 263 printk("%s ad9361_set_tx_atten ant1 %d OK\n",sdr_compatible_str, AD9361_RADIO_ON_TX_ATT+reg_val); 264 } 265 } 266 } else if (reg_addr_idx==RF_TX_REG_IDX_FREQ_MHZ) { // apply the tx fo 267 clk_set_rate(priv->ad9361_phy->clks[TX_RFPLL], ( ((u64)1000000ull)*((u64)priv->rf_reg_val[RF_TX_REG_IDX_FREQ_MHZ]) )>>1 ); 268 ad9361_tx_calibration(priv, priv->rf_reg_val[RF_TX_REG_IDX_FREQ_MHZ]); 269 printk("%s clk_set_rate TX_RFPLL %dMHz done\n",sdr_compatible_str, priv->rf_reg_val[RF_TX_REG_IDX_FREQ_MHZ]); 270 } else if (reg_addr_idx==RF_RX_REG_IDX_FREQ_MHZ) { // apply the rx fo 271 clk_set_rate(priv->ad9361_phy->clks[RX_RFPLL], ( ((u64)1000000ull)*((u64)priv->rf_reg_val[RF_RX_REG_IDX_FREQ_MHZ]) )>>1 ); 272 openwifi_rf_rx_update_after_tuning(priv, priv->rf_reg_val[RF_RX_REG_IDX_FREQ_MHZ]); 273 printk("%s clk_set_rate RX_RFPLL %dMHz done\n",sdr_compatible_str, priv->rf_reg_val[RF_RX_REG_IDX_FREQ_MHZ]); 274 } 275 } else { 276 printk("%s WARNING reg_addr_idx %d is out of range!\n", sdr_compatible_str, reg_addr_idx); 277 return -EOPNOTSUPP; 278 } 279 } 280 else if (reg_cat==SDRCTL_REG_CAT_RX_INTF) 281 rx_intf_api->reg_write(reg_addr,reg_val); 282 else if (reg_cat==SDRCTL_REG_CAT_TX_INTF) 283 tx_intf_api->reg_write(reg_addr,reg_val); 284 else if (reg_cat==SDRCTL_REG_CAT_RX) 285 openofdm_rx_api->reg_write(reg_addr,reg_val); 286 else if (reg_cat==SDRCTL_REG_CAT_TX) 287 openofdm_tx_api->reg_write(reg_addr,reg_val); 288 else if (reg_cat==SDRCTL_REG_CAT_XPU) 289 xpu_api->reg_write(reg_addr,reg_val); 290 else if (reg_cat==SDRCTL_REG_CAT_DRV_RX) { 291 if (reg_addr_idx>=0 && reg_addr_idx<MAX_NUM_DRV_REG) { 292 if (reg_addr_idx==DRV_RX_REG_IDX_ANT_CFG) { 293 tmp = openwifi_set_antenna(hw, (priv->drv_tx_reg_val[reg_addr_idx]==0?1:2), (reg_val==0?1:2)); 294 if (tmp) { 295 printk("%s WARNING openwifi_set_antenna return %d!\n", sdr_compatible_str, tmp); 296 return -EIO; 297 } else { 298 priv->drv_rx_reg_val[reg_addr_idx]=reg_val; 299 } 300 } else { 301 priv->drv_rx_reg_val[reg_addr_idx]=reg_val; 302 if (reg_addr_idx==DRV_RX_REG_IDX_DEMOD_TH) { 303 openofdm_rx_api->OPENOFDM_RX_REG_POWER_THRES_write((OPENOFDM_RX_DC_RUNNING_SUM_TH_INIT<<16)|rssi_dbm_to_rssi_half_db((reg_val==0?OPENOFDM_RX_RSSI_DBM_TH_DEFAULT:(-reg_val)), priv->rssi_correction)); 304 } 305 } 306 } else { 307 printk("%s WARNING reg_addr_idx %d is out of range!\n", sdr_compatible_str, reg_addr_idx); 308 return -EOPNOTSUPP; 309 } 310 } 311 else if (reg_cat==SDRCTL_REG_CAT_DRV_TX) { 312 if (reg_addr_idx>=0 && reg_addr_idx<MAX_NUM_DRV_REG) { 313 if ((reg_addr_idx == DRV_TX_REG_IDX_RATE || reg_addr_idx == DRV_TX_REG_IDX_RATE_HT) && 314 (reg_val != 0 && (!((reg_val&0xF)>=4 && (reg_val&0xF)<=11)) ) ) { 315 printk("%s WARNING rate override value should be 0 or 4~11!\n", sdr_compatible_str); 316 return -EOPNOTSUPP; 317 } else { 318 if (reg_addr_idx==DRV_TX_REG_IDX_ANT_CFG) { 319 tmp = openwifi_set_antenna(hw, reg_val+1, priv->drv_rx_reg_val[reg_addr_idx]+1); 320 if (tmp) { 321 printk("%s WARNING openwifi_set_antenna return %d!\n", sdr_compatible_str, tmp); 322 return -EIO; 323 } else { 324 priv->drv_tx_reg_val[reg_addr_idx]=reg_val; 325 } 326 } else { 327 priv->drv_tx_reg_val[reg_addr_idx]=reg_val; 328 } 329 } 330 } else { 331 printk("%s WARNING reg_addr_idx %d is out of range!\n", sdr_compatible_str, reg_addr_idx); 332 return -EOPNOTSUPP; 333 } 334 } 335 else if (reg_cat==SDRCTL_REG_CAT_DRV_XPU) { 336 if (reg_addr_idx>=0 && reg_addr_idx<MAX_NUM_DRV_REG) { 337 priv->drv_xpu_reg_val[reg_addr_idx]=reg_val; 338 if (reg_addr_idx==DRV_XPU_REG_IDX_LBT_TH) { 339 if (reg_val) { 340 tmp_int = (-reg_val); // rssi_dbm 341 tmp = rssi_dbm_to_rssi_half_db(tmp_int, priv->rssi_correction); 342 xpu_api->XPU_REG_LBT_TH_write( tmp ); 343 printk("%s override FPGA LBT threshold to %d(%ddBm). The last_auto_fpga_lbt_th %d(%ddBm). rssi corr %d (%d/%dMHz)\n", sdr_compatible_str, tmp, tmp_int, priv->last_auto_fpga_lbt_th, rssi_half_db_to_rssi_dbm(priv->last_auto_fpga_lbt_th, priv->rssi_correction), priv->rssi_correction, priv->actual_tx_lo, priv->actual_rx_lo); 344 } else { 345 xpu_api->XPU_REG_LBT_TH_write(priv->last_auto_fpga_lbt_th); 346 printk("%s Restore last_auto_fpga_lbt_th %d(%ddBm) to FPGA. ad9361_rf_set_channel will take control. rssi corr %d (%d/%dMHz)\n", sdr_compatible_str, priv->last_auto_fpga_lbt_th, rssi_half_db_to_rssi_dbm(priv->last_auto_fpga_lbt_th, priv->rssi_correction), priv->rssi_correction, priv->actual_tx_lo, priv->actual_rx_lo); 347 } 348 } 349 } else { 350 printk("%s WARNING reg_addr_idx %d is out of range!\n", sdr_compatible_str, reg_addr_idx); 351 return -EOPNOTSUPP; 352 } 353 } 354 else { 355 printk("%s WARNING reg cat %d is not supported yet!\n", sdr_compatible_str, reg_cat); 356 return -EOPNOTSUPP; 357 } 358 359 return 0; 360 case REG_CMD_GET: 361 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); 362 if (!skb) 363 return -ENOMEM; 364 reg_addr = nla_get_u32(tb[REG_ATTR_ADDR]); 365 reg_cat = ((reg_addr>>16)&0xFFFF); 366 reg_addr = (reg_addr&0xFFFF); 367 reg_addr_idx = (reg_addr>>2); 368 printk("%s recv get cmd reg cat %d addr %08x idx %d\n", sdr_compatible_str, reg_cat, reg_addr, reg_addr_idx); 369 if (reg_cat==SDRCTL_REG_CAT_RF) { 370 // printk("%s WARNING reg cat 1 (rf) is not supported yet!\n", sdr_compatible_str); 371 // tmp = 0xFFFFFFFF; 372 // return -EOPNOTSUPP; 373 if (reg_addr_idx>=0 && reg_addr_idx<MAX_NUM_RF_REG) { 374 tmp = priv->rf_reg_val[reg_addr_idx]; 375 } else { 376 printk("%s WARNING reg_addr_idx %d is out of range!\n", sdr_compatible_str, reg_addr_idx); 377 return -EOPNOTSUPP; 378 } 379 } 380 else if (reg_cat==SDRCTL_REG_CAT_RX_INTF) 381 tmp = rx_intf_api->reg_read(reg_addr); 382 else if (reg_cat==SDRCTL_REG_CAT_TX_INTF) 383 tmp = tx_intf_api->reg_read(reg_addr); 384 else if (reg_cat==SDRCTL_REG_CAT_RX) 385 tmp = openofdm_rx_api->reg_read(reg_addr); 386 else if (reg_cat==SDRCTL_REG_CAT_TX) 387 tmp = openofdm_tx_api->reg_read(reg_addr); 388 else if (reg_cat==SDRCTL_REG_CAT_XPU) 389 tmp = xpu_api->reg_read(reg_addr); 390 else if (reg_cat==SDRCTL_REG_CAT_DRV_RX) { 391 if (reg_addr_idx>=0 && reg_addr_idx<MAX_NUM_DRV_REG) { 392 tmp = priv->drv_rx_reg_val[reg_addr_idx]; 393 if (reg_addr_idx==DRV_RX_REG_IDX_ANT_CFG) 394 openwifi_get_antenna(hw, &tsft_high, &tsft_low); 395 } else { 396 printk("%s WARNING reg_addr_idx %d is out of range!\n", sdr_compatible_str, reg_addr_idx); 397 return -EOPNOTSUPP; 398 } 399 } 400 else if (reg_cat==SDRCTL_REG_CAT_DRV_TX) { 401 if (reg_addr_idx>=0 && reg_addr_idx<MAX_NUM_DRV_REG) { 402 tmp = priv->drv_tx_reg_val[reg_addr_idx]; 403 if (reg_addr_idx==DRV_TX_REG_IDX_ANT_CFG) 404 openwifi_get_antenna(hw, &tsft_high, &tsft_low); 405 } else { 406 printk("%s WARNING reg_addr_idx %d is out of range!\n", sdr_compatible_str, reg_addr_idx); 407 return -EOPNOTSUPP; 408 } 409 } 410 else if (reg_cat==SDRCTL_REG_CAT_DRV_XPU) { 411 if (reg_addr_idx>=0 && reg_addr_idx<MAX_NUM_DRV_REG) { 412 if (reg_addr_idx==DRV_XPU_REG_IDX_LBT_TH) { 413 tmp = xpu_api->XPU_REG_LBT_TH_read();//rssi_half_db 414 tmp_int = rssi_half_db_to_rssi_dbm(tmp, priv->rssi_correction); //rssi_dbm 415 printk("%s FPGA LBT threshold %d(%ddBm). The last_auto_fpga_lbt_th %d(%ddBm). rssi corr %d (%d/%dMHz)\n", sdr_compatible_str, tmp, tmp_int, priv->last_auto_fpga_lbt_th, rssi_half_db_to_rssi_dbm(priv->last_auto_fpga_lbt_th, priv->rssi_correction), priv->rssi_correction, priv->actual_tx_lo, priv->actual_rx_lo); 416 } 417 tmp = priv->drv_xpu_reg_val[reg_addr_idx]; 418 } else { 419 printk("%s WARNING reg_addr_idx %d is out of range!\n", sdr_compatible_str, reg_addr_idx); 420 return -EOPNOTSUPP; 421 } 422 } 423 else { 424 printk("%s WARNING reg cat %d is not supported yet!\n", sdr_compatible_str, reg_cat); 425 return -EOPNOTSUPP; 426 } 427 428 if (nla_put_u32(skb, REG_ATTR_VAL, tmp)) 429 goto nla_put_failure; 430 return cfg80211_testmode_reply(skb); 431 432 default: 433 return -EOPNOTSUPP; 434 } 435 436 nla_put_failure: 437 dev_kfree_skb(skb); 438 return -ENOBUFS; 439 } 440