diff --git a/driver/hw_def.h b/driver/hw_def.h index 91c03af..a72bdf0 100644 --- a/driver/hw_def.h +++ b/driver/hw_def.h @@ -26,11 +26,12 @@ const char *tx_intf_compatible_str = "sdr,tx_intf"; #define TX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_ADDR (8*4) #define TX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_ADDR (9*4) #define TX_INTF_REG_CFG_DATA_TO_ANT_ADDR (10*4) +#define TX_INTF_REG_S_AXIS_FIFO_TH_ADDR (11*4) #define TX_INTF_REG_TX_HOLD_THRESHOLD_ADDR (12*4) #define TX_INTF_REG_BB_GAIN_ADDR (13*4) #define TX_INTF_REG_INTERRUPT_SEL_ADDR (14*4) #define TX_INTF_REG_ANT_SEL_ADDR (16*4) -#define TX_INTF_REG_S_AXIS_FIFO_DATA_COUNT_ADDR (21*4) +#define TX_INTF_REG_S_AXIS_FIFO_NO_ROOM_ADDR (21*4) #define TX_INTF_REG_PKT_INFO_ADDR (22*4) #define TX_INTF_REG_QUEUE_FIFO_DATA_COUNT_ADDR (24*4) @@ -50,6 +51,7 @@ enum tx_intf_mode { }; const int tx_intf_fo_mapping[] = {0, 0, 0, 0,-10,10,-10,10}; +const u32 dma_symbol_fifo_size_hw_queue[] = {4*1024, 4*1024, 4*1024, 4*1024}; // !!!make sure align to fifo in tx_intf_s_axis.v struct tx_intf_driver_api { u32 (*hw_init)(enum tx_intf_mode mode, u32 num_dma_symbol_to_pl, u32 num_dma_symbol_to_ps); @@ -68,11 +70,12 @@ struct tx_intf_driver_api { u32 (*TX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_read)(void); u32 (*TX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_read)(void); u32 (*TX_INTF_REG_CFG_DATA_TO_ANT_read)(void); + u32 (*TX_INTF_REG_S_AXIS_FIFO_TH_read)(void); u32 (*TX_INTF_REG_TX_HOLD_THRESHOLD_read)(void); u32 (*TX_INTF_REG_INTERRUPT_SEL_read)(void); u32 (*TX_INTF_REG_BB_GAIN_read)(void); u32 (*TX_INTF_REG_ANT_SEL_read)(void); - u32 (*TX_INTF_REG_S_AXIS_FIFO_DATA_COUNT_read)(void); + u32 (*TX_INTF_REG_S_AXIS_FIFO_NO_ROOM_read)(void); u32 (*TX_INTF_REG_PKT_INFO_read)(void); u32 (*TX_INTF_REG_QUEUE_FIFO_DATA_COUNT_read)(void); @@ -87,11 +90,12 @@ struct tx_intf_driver_api { void (*TX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write)(u32 value); void (*TX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write)(u32 value); void (*TX_INTF_REG_CFG_DATA_TO_ANT_write)(u32 value); + void (*TX_INTF_REG_S_AXIS_FIFO_TH_write)(u32 value); void (*TX_INTF_REG_TX_HOLD_THRESHOLD_write)(u32 value); void (*TX_INTF_REG_INTERRUPT_SEL_write)(u32 value); void (*TX_INTF_REG_BB_GAIN_write)(u32 value); void (*TX_INTF_REG_ANT_SEL_write)(u32 value); - void (*TX_INTF_REG_S_AXIS_FIFO_DATA_COUNT_write)(u32 value); + void (*TX_INTF_REG_S_AXIS_FIFO_NO_ROOM_write)(u32 value); void (*TX_INTF_REG_PKT_INFO_write)(u32 value); }; @@ -251,12 +255,9 @@ const char *xpu_compatible_str = "sdr,xpu"; #define XPU_REG_SEND_ACK_WAIT_TOP_ADDR (18*4) #define XPU_REG_CSMA_CFG_ADDR (19*4) -#define XPU_REG_SLICE_COUNT_TOTAL0_ADDR (20*4) -#define XPU_REG_SLICE_COUNT_START0_ADDR (21*4) -#define XPU_REG_SLICE_COUNT_END0_ADDR (22*4) -#define XPU_REG_SLICE_COUNT_TOTAL1_ADDR (23*4) -#define XPU_REG_SLICE_COUNT_START1_ADDR (24*4) -#define XPU_REG_SLICE_COUNT_END1_ADDR (25*4) +#define XPU_REG_SLICE_COUNT_TOTAL_ADDR (20*4) +#define XPU_REG_SLICE_COUNT_START_ADDR (21*4) +#define XPU_REG_SLICE_COUNT_END_ADDR (22*4) #define XPU_REG_CTS_TO_RTS_CONFIG_ADDR (26*4) #define XPU_REG_FILTER_FLAG_ADDR (27*4) @@ -364,16 +365,16 @@ struct xpu_driver_api { void (*XPU_REG_CSMA_CFG_write)(u32 value); u32 (*XPU_REG_CSMA_CFG_read)(void); - void (*XPU_REG_SLICE_COUNT_TOTAL0_write)(u32 value); - void (*XPU_REG_SLICE_COUNT_START0_write)(u32 value); - void (*XPU_REG_SLICE_COUNT_END0_write)(u32 value); + void (*XPU_REG_SLICE_COUNT_TOTAL_write)(u32 value); + void (*XPU_REG_SLICE_COUNT_START_write)(u32 value); + void (*XPU_REG_SLICE_COUNT_END_write)(u32 value); void (*XPU_REG_SLICE_COUNT_TOTAL1_write)(u32 value); void (*XPU_REG_SLICE_COUNT_START1_write)(u32 value); void (*XPU_REG_SLICE_COUNT_END1_write)(u32 value); - u32 (*XPU_REG_SLICE_COUNT_TOTAL0_read)(void); - u32 (*XPU_REG_SLICE_COUNT_START0_read)(void); - u32 (*XPU_REG_SLICE_COUNT_END0_read)(void); + u32 (*XPU_REG_SLICE_COUNT_TOTAL_read)(void); + u32 (*XPU_REG_SLICE_COUNT_START_read)(void); + u32 (*XPU_REG_SLICE_COUNT_END_read)(void); u32 (*XPU_REG_SLICE_COUNT_TOTAL1_read)(void); u32 (*XPU_REG_SLICE_COUNT_START1_read)(void); u32 (*XPU_REG_SLICE_COUNT_END1_read)(void); diff --git a/driver/openofdm_rx/openofdm_rx.c b/driver/openofdm_rx/openofdm_rx.c index 6c529e1..beb101c 100644 --- a/driver/openofdm_rx/openofdm_rx.c +++ b/driver/openofdm_rx/openofdm_rx.c @@ -63,7 +63,7 @@ static struct openofdm_rx_driver_api *openofdm_rx_api = &openofdm_rx_driver_api_ EXPORT_SYMBOL(openofdm_rx_api); static inline u32 hw_init(enum openofdm_rx_mode mode){ - int err=0; + int err=0, i; printk("%s hw_init mode %d\n", openofdm_rx_compatible_str, mode); @@ -95,13 +95,13 @@ static inline u32 hw_init(enum openofdm_rx_mode mode){ openofdm_rx_api->OPENOFDM_RX_REG_POWER_THRES_write(0); openofdm_rx_api->OPENOFDM_RX_REG_MIN_PLATEAU_write(100); - openofdm_rx_api->OPENOFDM_RX_REG_MULTI_RST_write(0xFFFFFFFF); - openofdm_rx_api->OPENOFDM_RX_REG_MULTI_RST_write(0xFFFFFFFF); - openofdm_rx_api->OPENOFDM_RX_REG_MULTI_RST_write(0xFFFFFFFF); - openofdm_rx_api->OPENOFDM_RX_REG_MULTI_RST_write(0xFFFFFFFF); - openofdm_rx_api->OPENOFDM_RX_REG_MULTI_RST_write(0xFFFFFFFF); - openofdm_rx_api->OPENOFDM_RX_REG_MULTI_RST_write(0xFFFFFFFF); - openofdm_rx_api->OPENOFDM_RX_REG_MULTI_RST_write(0); + //rst + for (i=0;i<8;i++) + openofdm_rx_api->OPENOFDM_RX_REG_MULTI_RST_write(0); + for (i=0;i<32;i++) + openofdm_rx_api->OPENOFDM_RX_REG_MULTI_RST_write(0xFFFFFFFF); + for (i=0;i<8;i++) + openofdm_rx_api->OPENOFDM_RX_REG_MULTI_RST_write(0); printk("%s hw_init err %d\n", openofdm_rx_compatible_str, err); diff --git a/driver/openofdm_tx/openofdm_tx.c b/driver/openofdm_tx/openofdm_tx.c index d99d499..8cb33ce 100644 --- a/driver/openofdm_tx/openofdm_tx.c +++ b/driver/openofdm_tx/openofdm_tx.c @@ -58,7 +58,7 @@ static struct openofdm_tx_driver_api *openofdm_tx_api = &openofdm_tx_driver_api_ EXPORT_SYMBOL(openofdm_tx_api); static inline u32 hw_init(enum openofdm_tx_mode mode){ - int err=0; + int err=0, i; printk("%s hw_init mode %d\n", openofdm_tx_compatible_str, mode); @@ -77,13 +77,13 @@ static inline u32 hw_init(enum openofdm_tx_mode mode){ err=1; } - openofdm_tx_api->OPENOFDM_TX_REG_MULTI_RST_write(0xFFFFFFFF); - openofdm_tx_api->OPENOFDM_TX_REG_MULTI_RST_write(0xFFFFFFFF); - openofdm_tx_api->OPENOFDM_TX_REG_MULTI_RST_write(0xFFFFFFFF); - openofdm_tx_api->OPENOFDM_TX_REG_MULTI_RST_write(0xFFFFFFFF); - openofdm_tx_api->OPENOFDM_TX_REG_MULTI_RST_write(0xFFFFFFFF); - openofdm_tx_api->OPENOFDM_TX_REG_MULTI_RST_write(0xFFFFFFFF); - openofdm_tx_api->OPENOFDM_TX_REG_MULTI_RST_write(0); + //rst + for (i=0;i<8;i++) + openofdm_tx_api->OPENOFDM_TX_REG_MULTI_RST_write(0); + for (i=0;i<32;i++) + openofdm_tx_api->OPENOFDM_TX_REG_MULTI_RST_write(0xFFFFFFFF); + for (i=0;i<8;i++) + openofdm_tx_api->OPENOFDM_TX_REG_MULTI_RST_write(0); openofdm_tx_api->OPENOFDM_TX_REG_INIT_PILOT_STATE_write(0x7E); openofdm_tx_api->OPENOFDM_TX_REG_INIT_DATA_STATE_write(0x7F); diff --git a/driver/rx_intf/rx_intf.c b/driver/rx_intf/rx_intf.c index a4fd920..7e6cb25 100644 --- a/driver/rx_intf/rx_intf.c +++ b/driver/rx_intf/rx_intf.c @@ -163,27 +163,25 @@ static const struct of_device_id dev_of_ids[] = { MODULE_DEVICE_TABLE(of, dev_of_ids); static struct rx_intf_driver_api rx_intf_driver_api_inst; -//EXPORT_SYMBOL(rx_intf_driver_api_inst); static struct rx_intf_driver_api *rx_intf_api = &rx_intf_driver_api_inst; EXPORT_SYMBOL(rx_intf_api); static inline u32 hw_init(enum rx_intf_mode mode, u32 num_dma_symbol_to_pl, u32 num_dma_symbol_to_ps){ - int err=0; + int err=0, i; u32 reg_val, mixer_cfg=0, ant_sel=0; printk("%s hw_init mode %d\n", rx_intf_compatible_str, mode); - ////rst wifi rx -- slv_reg11[2] is actual rx reset. slv_reg11[0] only reset axi lite of rx - //printk("%s hw_init reset wifi rx\n", rx_intf_compatible_str); - //rx_intf_api->RX_INTF_REG_RST_START_TO_EXT_write(0); - //rx_intf_api->RX_INTF_REG_RST_START_TO_EXT_write(4); - //rx_intf_api->RX_INTF_REG_RST_START_TO_EXT_write(0); - rx_intf_api->RX_INTF_REG_TLAST_TIMEOUT_TOP_write(7000); - //rst ddc internal module - for (reg_val=0;reg_val<32;reg_val++) + + //rst + for (i=0;i<8;i++) + rx_intf_api->RX_INTF_REG_MULTI_RST_write(0); + for (i=0;i<32;i++) rx_intf_api->RX_INTF_REG_MULTI_RST_write(0xFFFFFFFF); - rx_intf_api->RX_INTF_REG_MULTI_RST_write(0); + for (i=0;i<8;i++) + rx_intf_api->RX_INTF_REG_MULTI_RST_write(0); + rx_intf_api->RX_INTF_REG_M_AXIS_RST_write(1); // hold M AXIS in reset status. will be released when openwifi_start switch(mode) diff --git a/driver/sdr.c b/driver/sdr.c index a3787bf..40f8d99 100644 --- a/driver/sdr.c +++ b/driver/sdr.c @@ -100,7 +100,7 @@ void openwifi_rfkill_poll(struct ieee80211_hw *hw) struct openwifi_priv *priv = hw->priv; enabled = openwifi_is_radio_enabled(priv); - printk("%s openwifi_rfkill_poll: wireless radio switch turned %s\n", sdr_compatible_str, enabled ? "on" : "off"); + // printk("%s openwifi_rfkill_poll: wireless radio switch turned %s\n", sdr_compatible_str, enabled ? "on" : "off"); if (unlikely(enabled != priv->rfkill_off)) { priv->rfkill_off = enabled; printk("%s openwifi_rfkill_poll: WARNING wireless radio switch turned %s\n", sdr_compatible_str, enabled ? "on" : "off"); @@ -210,12 +210,12 @@ u32 reverse32(u32 d) { return(tmp1.a); } -static int openwifi_init_tx_ring(struct openwifi_priv *priv) +static int openwifi_init_tx_ring(struct openwifi_priv *priv, int ring_idx) { - struct openwifi_ring *ring = &(priv->tx_ring); + struct openwifi_ring *ring = &(priv->tx_ring[ring_idx]); int i; - priv->tx_queue_stopped = false; + ring->stop_flag = 0; ring->bd_wr_idx = 0; ring->bd_rd_idx = 0; ring->bds = kmalloc(sizeof(struct openwifi_buffer_descriptor)*NUM_TX_BD,GFP_KERNEL); @@ -225,12 +225,6 @@ static int openwifi_init_tx_ring(struct openwifi_priv *priv) } for (i = 0; i < NUM_TX_BD; i++) { - ring->bds[i].num_dma_byte=0; - ring->bds[i].sn=0; - ring->bds[i].hw_queue_idx=0; - ring->bds[i].retry_limit=0; - ring->bds[i].need_ack=0; - ring->bds[i].skb_linked=0; // for tx, skb is from upper layer //at frist right after skb allocated, head, data, tail are the same. ring->bds[i].dma_mapping_addr = 0; // for tx, mapping is done after skb is received from uppler layer in tx routine @@ -239,29 +233,25 @@ static int openwifi_init_tx_ring(struct openwifi_priv *priv) return 0; } -static void openwifi_free_tx_ring(struct openwifi_priv *priv) +static void openwifi_free_tx_ring(struct openwifi_priv *priv, int ring_idx) { - struct openwifi_ring *ring = &(priv->tx_ring); + struct openwifi_ring *ring = &(priv->tx_ring[ring_idx]); int i; + ring->stop_flag = 0; ring->bd_wr_idx = 0; ring->bd_rd_idx = 0; for (i = 0; i < NUM_TX_BD; i++) { - ring->bds[i].num_dma_byte=0; - ring->bds[i].sn=0; - ring->bds[i].hw_queue_idx=0; - ring->bds[i].retry_limit=0; - ring->bds[i].need_ack=0; - if (ring->bds[i].skb_linked == 0 && ring->bds[i].dma_mapping_addr == 0) continue; if (ring->bds[i].dma_mapping_addr != 0) - dma_unmap_single(priv->tx_chan->device->dev, ring->bds[i].dma_mapping_addr,ring->bds[i].num_dma_byte, DMA_MEM_TO_DEV); + dma_unmap_single(priv->tx_chan->device->dev, ring->bds[i].dma_mapping_addr,ring->bds[i].skb_linked->len, DMA_MEM_TO_DEV); // if (ring->bds[i].skb_linked!=NULL) -// dev_kfree_skb(ring->bds[i].skb_linked); +// dev_kfree_skb(ring->bds[i].skb_linked); // only use dev_kfree_skb when there is exception if ( (ring->bds[i].dma_mapping_addr != 0 && ring->bds[i].skb_linked == 0) || (ring->bds[i].dma_mapping_addr == 0 && ring->bds[i].skb_linked != 0)) - printk("%s openwifi_free_tx_ring: WARNING %d skb_linked %p dma_mapping_addr %08llx\n", sdr_compatible_str, i, (void*)(ring->bds[i].skb_linked), ring->bds[i].dma_mapping_addr); + printk("%s openwifi_free_tx_ring: WARNING ring %d i %d skb_linked %p dma_mapping_addr %08llx\n", sdr_compatible_str, + ring_idx, i, (void*)(ring->bds[i].skb_linked), ring->bds[i].dma_mapping_addr); ring->bds[i].skb_linked=0; ring->bds[i].dma_mapping_addr = 0; @@ -322,9 +312,9 @@ static irqreturn_t openwifi_rx_interrupt(int irq, void *dev_id) struct ieee80211_rx_status rx_status = {0}; struct sk_buff *skb; struct ieee80211_hdr *hdr; - u32 addr1_low32=0, addr2_low32=0, addr3_low32=0, len, rate_idx, ht_flag, tsft_low, tsft_high;//, fc_di; - u32 dma_driver_buf_idx_mod; - u8 *pdata_tmp, fcs_ok, phy_rx_sn_hw, target_buf_idx; + u32 addr1_low32=0, addr2_low32=0, addr3_low32=0, len, rate_idx, tsft_low, tsft_high, loop_count=0;//, ht_flag//;//, fc_di; + // u32 dma_driver_buf_idx_mod; + u8 *pdata_tmp, fcs_ok, target_buf_idx;//, phy_rx_sn_hw; s8 signal; u16 rssi_val, addr1_high16=0, addr2_high16=0, addr3_high16=0, sc=0; bool content_ok = false, len_overflow = false; @@ -334,101 +324,104 @@ static irqreturn_t openwifi_rx_interrupt(int irq, void *dev_id) spin_lock(&priv->lock); priv->rx_chan->device->device_tx_status(priv->rx_chan,priv->rx_cookie,&state); target_buf_idx = ((state.residue-1)&(NUM_RX_BD-1)); - if (target_buf_idx==target_buf_idx_old) { - //printk("%s openwifi_rx_interrupt: WARNING same idx %d\n", sdr_compatible_str,target_buf_idx); - goto openwifi_rx_interrupt_out; - } - if ( ((target_buf_idx-target_buf_idx_old)&(NUM_RX_BD-1))!=1 ) - printk("%s openwifi_rx_interrupt: WARNING jump idx target %d old %d diff %02x\n", sdr_compatible_str,target_buf_idx,target_buf_idx_old,((target_buf_idx-target_buf_idx_old)&(NUM_RX_BD-1))); - target_buf_idx_old = target_buf_idx; - pdata_tmp = priv->rx_cyclic_buf + target_buf_idx*RX_BD_BUF_SIZE; // our header insertion is at the beginning - tsft_low = (*((u32*)(pdata_tmp+0 ))); - tsft_high = (*((u32*)(pdata_tmp+4 ))); - rssi_val = (*((u16*)(pdata_tmp+8 ))); - len = (*((u16*)(pdata_tmp+12))); + while( target_buf_idx_old!=target_buf_idx ) { // loop all rx buffers that have new rx packets + target_buf_idx_old=((target_buf_idx_old+1)&(NUM_RX_BD-1)); + pdata_tmp = priv->rx_cyclic_buf + target_buf_idx_old*RX_BD_BUF_SIZE; // our header insertion is at the beginning + tsft_low = (*((u32*)(pdata_tmp+0 ))); + tsft_high = (*((u32*)(pdata_tmp+4 ))); + rssi_val = (*((u16*)(pdata_tmp+8 ))); + len = (*((u16*)(pdata_tmp+12))); - len_overflow = (len>(RX_BD_BUF_SIZE-16)?true:false); + len_overflow = (len>(RX_BD_BUF_SIZE-16)?true:false); - rate_idx = (*((u16*)(pdata_tmp+14))); + rate_idx = (*((u16*)(pdata_tmp+14))); - // fc_di = (*((u32*)(pdata_tmp+16))); - // addr1_high16 = (*((u16*)(pdata_tmp+16+4))); - // addr1_low32 = (*((u32*)(pdata_tmp+16+4+2))); - // addr2_high16 = (*((u16*)(pdata_tmp+16+6+4))); - // addr2_low32 = (*((u32*)(pdata_tmp+16+6+4+2))); - // addr3_high16 = (*((u16*)(pdata_tmp+16+12+4))); - // addr3_low32 = (*((u32*)(pdata_tmp+16+12+4+2))); - hdr = (struct ieee80211_hdr *)(pdata_tmp+16); - addr1_low32 = *((u32*)(hdr->addr1+2)); - addr1_high16 = *((u16*)(hdr->addr1)); - if (len>=20) { - addr2_low32 = *((u32*)(hdr->addr2+2)); - addr2_high16 = *((u16*)(hdr->addr2)); - } - if (len>=26) { - addr3_low32 = *((u32*)(hdr->addr3+2)); - addr3_high16 = *((u16*)(hdr->addr3)); - } - if (len>=28) - sc = hdr->seq_ctrl; + fcs_ok = ( len_overflow?0:(*(( u8*)(pdata_tmp+16+len-1))) ); - fcs_ok = ( len_overflow?0:(*(( u8*)(pdata_tmp+16+len-1))) ); + //phy_rx_sn_hw = (fcs_ok&(NUM_RX_BD-1)); + // phy_rx_sn_hw = (fcs_ok&0x7f);//0x7f is FPGA limitation + // dma_driver_buf_idx_mod = (state.residue&0x7f); + fcs_ok = ((fcs_ok&0x80)!=0); + // ht_flag = ((rate_idx&0x10)!=0); + rate_idx = (rate_idx&0xF); - //phy_rx_sn_hw = (fcs_ok&(NUM_RX_BD-1)); - phy_rx_sn_hw = (fcs_ok&0x7f);//0x7f is FPGA limitation - dma_driver_buf_idx_mod = (state.residue&0x7f); - fcs_ok = ((fcs_ok&0x80)!=0); - ht_flag = ((rate_idx&0x10)!=0); - rate_idx = (rate_idx&0xF); + if ( (len>=14 && (!len_overflow)) && (rate_idx>=8 && rate_idx<=15)) { + // if ( phy_rx_sn_hw!=dma_driver_buf_idx_mod) { + // printk("%s openwifi_rx_interrupt: WARNING sn %d next buf_idx %d!\n", sdr_compatible_str,phy_rx_sn_hw,dma_driver_buf_idx_mod); + // } + content_ok = true; + } else { + printk("%s openwifi_rx_interrupt: WARNING content!\n", sdr_compatible_str); + content_ok = false; + } - if ( (len>=14 && (!len_overflow)) && (rate_idx>=8 && rate_idx<=15)) { - // if ( phy_rx_sn_hw!=dma_driver_buf_idx_mod) { - // printk("%s openwifi_rx_interrupt: WARNING sn %d next buf_idx %d!\n", sdr_compatible_str,phy_rx_sn_hw,dma_driver_buf_idx_mod); - // } - content_ok = true; - } else { - printk("%s openwifi_rx_interrupt: WARNING content!\n", sdr_compatible_str); - content_ok = false; + rssi_val = (rssi_val>>1); + if ( (rssi_val+128)rssi_correction ) + signal = -128; + else + signal = rssi_val - priv->rssi_correction; + + // fc_di = (*((u32*)(pdata_tmp+16))); + // addr1_high16 = (*((u16*)(pdata_tmp+16+4))); + // addr1_low32 = (*((u32*)(pdata_tmp+16+4+2))); + // addr2_high16 = (*((u16*)(pdata_tmp+16+6+4))); + // addr2_low32 = (*((u32*)(pdata_tmp+16+6+4+2))); + // addr3_high16 = (*((u16*)(pdata_tmp+16+12+4))); + // addr3_low32 = (*((u32*)(pdata_tmp+16+12+4+2))); + if ( (priv->drv_rx_reg_val[DRV_RX_REG_IDX_PRINT_CFG]&2) || ( (priv->drv_rx_reg_val[DRV_RX_REG_IDX_PRINT_CFG]&1) && fcs_ok==0 ) ) { + hdr = (struct ieee80211_hdr *)(pdata_tmp+16); + addr1_low32 = *((u32*)(hdr->addr1+2)); + addr1_high16 = *((u16*)(hdr->addr1)); + if (len>=20) { + addr2_low32 = *((u32*)(hdr->addr2+2)); + addr2_high16 = *((u16*)(hdr->addr2)); + } + if (len>=26) { + addr3_low32 = *((u32*)(hdr->addr3+2)); + addr3_high16 = *((u16*)(hdr->addr3)); + } + if (len>=28) + sc = hdr->seq_ctrl; + + if ( addr1_low32!=0xffffffff || addr1_high16!=0xffff ) + printk("%s openwifi_rx_interrupt:%4dbytes %2dM FC%04x DI%04x addr1/2/3:%04x%08x/%04x%08x/%04x%08x SC%04x fcs%d buf_idx%d %ddBm\n", sdr_compatible_str, + len, wifi_rate_table[rate_idx], hdr->frame_control, hdr->duration_id, + reverse16(addr1_high16), reverse32(addr1_low32), reverse16(addr2_high16), reverse32(addr2_low32), reverse16(addr3_high16), reverse32(addr3_low32), + sc, fcs_ok, target_buf_idx_old, signal); + } + + // priv->phy_rx_sn_hw_old = phy_rx_sn_hw; + if (content_ok) { + skb = dev_alloc_skb(len); + if (skb) { + skb_put_data(skb,pdata_tmp+16,len); + + rx_status.antenna = 0; + // def in ieee80211_rate openwifi_rates 0~11. 0~3 11b(1M~11M), 4~11 11a/g(6M~54M) + rx_status.rate_idx = wifi_rate_table_mapping[rate_idx]; + rx_status.signal = signal; + rx_status.freq = dev->conf.chandef.chan->center_freq; + rx_status.band = dev->conf.chandef.chan->band; + rx_status.mactime = ( ( (u64)tsft_low ) | ( ((u64)tsft_high)<<32 ) ); + rx_status.flag |= RX_FLAG_MACTIME_START; + if (!fcs_ok) + rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; + rx_status.encoding = RX_ENC_LEGACY; + rx_status.bw = RATE_INFO_BW_20; + + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); // put rx_status into skb->cb, from now on skb->cb is not dma_dsts any more. + ieee80211_rx_irqsafe(dev, skb); // call mac80211 function + } else + printk("%s openwifi_rx_interrupt: WARNING dev_alloc_skb failed!\n", sdr_compatible_str); + } + loop_count++; } - rssi_val = (rssi_val>>1); - if ( (rssi_val+128)rssi_correction ) - signal = -128; - else - signal = rssi_val - priv->rssi_correction; - - if (addr1_low32!=0xffffffff && addr1_high16!=0xffff) - printk("%s openwifi_rx_interrupt:%4dbytes ht%d %2dM FC%04x DI%04x addr1/2/3:%04x%08x/%04x%08x/%04x%08x SC%04x fcs%d sn%d i%d %ddBm\n", sdr_compatible_str, - len, ht_flag, wifi_rate_table[rate_idx], hdr->frame_control,hdr->duration_id, - reverse16(addr1_high16), reverse32(addr1_low32), reverse16(addr2_high16), reverse32(addr2_low32), reverse16(addr3_high16), reverse32(addr3_low32), - sc,fcs_ok, phy_rx_sn_hw,dma_driver_buf_idx_mod,signal); - - // priv->phy_rx_sn_hw_old = phy_rx_sn_hw; - if (content_ok) { - skb = dev_alloc_skb(len); - if (skb) { - skb_put_data(skb,pdata_tmp+16,len); - - rx_status.antenna = 0; - // def in ieee80211_rate openwifi_rates 0~11. 0~3 11b(1M~11M), 4~11 11a/g(6M~54M) - rx_status.rate_idx = wifi_rate_table_mapping[rate_idx]; - rx_status.signal = signal; - rx_status.freq = dev->conf.chandef.chan->center_freq; - rx_status.band = dev->conf.chandef.chan->band; - rx_status.mactime = ( ( (u64)tsft_low ) | ( ((u64)tsft_high)<<32 ) ); - rx_status.flag |= RX_FLAG_MACTIME_START; - if (!fcs_ok) - rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; - rx_status.encoding = RX_ENC_LEGACY; - rx_status.bw = RATE_INFO_BW_20; - - memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); // put rx_status into skb->cb, from now on skb->cb is not dma_dsts any more. - ieee80211_rx_irqsafe(dev, skb); // call mac80211 function - } else - printk("%s openwifi_rx_interrupt: WARNING skb!\n", sdr_compatible_str); - } -openwifi_rx_interrupt_out: + if ( loop_count!=1 && (priv->drv_rx_reg_val[DRV_RX_REG_IDX_PRINT_CFG]&1) ) + printk("%s openwifi_rx_interrupt: WARNING loop_count %d\n", sdr_compatible_str,loop_count); + +// openwifi_rx_interrupt_out: spin_unlock(&priv->lock); return IRQ_HANDLED; } @@ -437,102 +430,87 @@ static irqreturn_t openwifi_tx_interrupt(int irq, void *dev_id) { struct ieee80211_hw *dev = dev_id; struct openwifi_priv *priv = dev->priv; - struct openwifi_ring *ring = &(priv->tx_ring); + struct openwifi_ring *ring; struct sk_buff *skb; struct ieee80211_tx_info *info; - u32 reg_val,ring_len, ring_room_left, just_wr_idx, current_rd_idx; //queue_idx_hw, ; - u32 num_dma_byte_hw; - u32 phy_tx_sn_hw; - u8 tx_result; + u32 reg_val, hw_queue_len, prio, queue_idx, dma_fifo_no_room_flag, loop_count=0;//, i; + u8 tx_result_report; + // u16 prio_rd_idx_store[64]={0}; spin_lock(&priv->lock); - tx_result = xpu_api->XPU_REG_TX_RESULT_read(); - reg_val = tx_intf_api->TX_INTF_REG_PKT_INFO_read();// current interrupt is the end of phy_tx_sn_hw pkt transmitting. - num_dma_byte_hw = (reg_val&0xFFFF); - phy_tx_sn_hw = ((reg_val>>16)&MAX_PHY_TX_SN); - //queue_idx_hw = (reg_val&(MAX_NUM_HW_QUEUE-1)); + while(1) { // loop all packets that have been sent by FPGA + reg_val = tx_intf_api->TX_INTF_REG_PKT_INFO_read(); + if (reg_val!=0x7FFFF) { + prio = (reg_val>>(5+NUM_BIT_MAX_PHY_TX_SN+NUM_BIT_MAX_NUM_HW_QUEUE)); + ring = &(priv->tx_ring[prio]); + ring->bd_rd_idx = ((reg_val>>5)&MAX_PHY_TX_SN); + skb = ring->bds[ring->bd_rd_idx].skb_linked; - //just_wr_idx = (ring->bd_wr_idx==0?(NUM_TX_BD-1):(ring->bd_wr_idx-1)); - just_wr_idx = ((ring->bd_wr_idx-1)&(NUM_TX_BD-1)); - while(1) { - current_rd_idx = ring->bd_rd_idx; + dma_unmap_single(priv->tx_chan->device->dev,ring->bds[ring->bd_rd_idx].dma_mapping_addr, + skb->len, DMA_MEM_TO_DEV); - dma_unmap_single(priv->tx_chan->device->dev,ring->bds[current_rd_idx].dma_mapping_addr, - ring->bds[current_rd_idx].num_dma_byte, DMA_MEM_TO_DEV); + if ( ring->stop_flag == 1) { + // Wake up Linux queue if FPGA and driver ring have room + queue_idx = ((reg_val>>(5+NUM_BIT_MAX_PHY_TX_SN))&(MAX_NUM_HW_QUEUE-1)); + dma_fifo_no_room_flag = tx_intf_api->TX_INTF_REG_S_AXIS_FIFO_NO_ROOM_read(); + hw_queue_len = tx_intf_api->TX_INTF_REG_QUEUE_FIFO_DATA_COUNT_read(); - if (phy_tx_sn_hw != ring->bds[current_rd_idx].sn) { - ring->bd_rd_idx = ((ring->bd_rd_idx+1)&(NUM_TX_BD-1)); - if (current_rd_idx == just_wr_idx) { - printk("%s openwifi_tx_interrupt: WARNING can not find hw sn %d in driver! curr rd %d just wr %d\n", sdr_compatible_str,phy_tx_sn_hw,current_rd_idx,just_wr_idx); - break; - } else + // printk("%s openwifi_tx_interrupt: WARNING loop %d prio %d queue %d no room flag %x hw queue len %08x wr %d rd %d call %d\n", sdr_compatible_str, + // loop_count, prio, queue_idx, dma_fifo_no_room_flag, hw_queue_len, ring->bd_wr_idx, ring->bd_rd_idx, priv->call_counter); + + if ( ((dma_fifo_no_room_flag>>queue_idx)&1)==0 && (NUM_TX_BD-((hw_queue_len>>(queue_idx*8))&0xFF))>=RING_ROOM_THRESHOLD ) { + // printk("%s openwifi_tx_interrupt: WARNING ieee80211_wake_queue loop %d call %d\n", sdr_compatible_str, loop_count, priv->call_counter); + printk("%s openwifi_tx_interrupt: WARNING ieee80211_wake_queue prio %d queue %d no room flag %x hw queue len %08x wr %d rd %d\n", sdr_compatible_str, + prio, queue_idx, dma_fifo_no_room_flag, hw_queue_len, ring->bd_wr_idx, ring->bd_rd_idx); + ieee80211_wake_queue(dev, prio); + ring->stop_flag = 0; + } + } + + if ( ((*(u32*)(&(skb->data[0])))&0xFF000000) || (*(u32*)(&(skb->data[12]))) || (*(u32*)(&(skb->data[8]))) || (*(u32*)(&(skb->data[4]))) ) { + printk("%s openwifi_tx_interrupt: WARNING %08x %08x %08x %08x\n", sdr_compatible_str, *(u32*)(&(skb->data[12])), *(u32*)(&(skb->data[8])), *(u32*)(&(skb->data[4])), *(u32*)(&(skb->data[0]))); continue; - } + } - // a know bd has just been sent to the air - if (num_dma_byte_hw!=ring->bds[current_rd_idx].num_dma_byte) { - ring->bd_rd_idx = ((ring->bd_rd_idx+1)&(NUM_TX_BD-1)); - printk("%s openwifi_tx_interrupt: WARNING num_dma_byte is different %d VS %d at sn %d curr rd %d just wr %d\n", sdr_compatible_str,num_dma_byte_hw,ring->bds[current_rd_idx].num_dma_byte,phy_tx_sn_hw,current_rd_idx,just_wr_idx); - if (current_rd_idx == just_wr_idx) - break; - else - continue; - } + skb_pull(skb, LEN_PHY_HEADER); + //skb_trim(skb, num_byte_pad_skb); + info = IEEE80211_SKB_CB(skb); + ieee80211_tx_info_clear_status(info); - // num_dma_byte_hw is correct - skb = ring->bds[current_rd_idx].skb_linked; - // dma_buf = skb->data; - //phy_tx_sn_skb = (*((u16*)(dma_buf+6))); - //num_dma_byte_skb = (*((u32*)(dma_buf+8))); - //num_byte_pad_skb = (*((u32*)(dma_buf+12))); - - //if ( phy_tx_sn_hw!=phy_tx_sn_entry || phy_tx_sn_hw!=phy_tx_sn_skb || phy_tx_sn_entry!=phy_tx_sn_skb ) - // printk("%s openwifi_tx_interrupt: WARNING hw/entry/skb num byte %d/%d/%d pkt sn %d/%d/%d pad %d\n", sdr_compatible_str, - // num_dma_byte_hw, num_dma_byte_entry, num_dma_byte_skb, phy_tx_sn_hw, phy_tx_sn_entry, phy_tx_sn_skb, num_byte_pad_skb); + tx_result_report = (reg_val&0x1F); + if ( !(info->flags & IEEE80211_TX_CTL_NO_ACK) ) { + if ((tx_result_report&0x10)==0) + info->flags |= IEEE80211_TX_STAT_ACK; - skb_pull(skb, LEN_PHY_HEADER); - //skb_trim(skb, num_byte_pad_skb); - info = IEEE80211_SKB_CB(skb); - ieee80211_tx_info_clear_status(info); + // printk("%s openwifi_tx_interrupt: rate&try: %d %d %03x; %d %d %03x; %d %d %03x; %d %d %03x\n", sdr_compatible_str, + // info->status.rates[0].idx,info->status.rates[0].count,info->status.rates[0].flags, + // info->status.rates[1].idx,info->status.rates[1].count,info->status.rates[1].flags, + // info->status.rates[2].idx,info->status.rates[2].count,info->status.rates[2].flags, + // info->status.rates[3].idx,info->status.rates[3].count,info->status.rates[3].flags); + } - if ( !(info->flags & IEEE80211_TX_CTL_NO_ACK) ) { - if ((tx_result&0x10)==0) - info->flags |= IEEE80211_TX_STAT_ACK; + info->status.rates[0].count = (tx_result_report&0xF) + 1; //according to our test, the 1st rate is the most important. we only do retry on the 1st rate + info->status.rates[1].idx = -1; + info->status.rates[2].idx = -1; + info->status.rates[3].idx = -1;//in mac80211.h: #define IEEE80211_TX_MAX_RATES 4 + + if ( (tx_result_report&0x10) && ((priv->drv_tx_reg_val[DRV_TX_REG_IDX_PRINT_CFG])&1) ) + printk("%s openwifi_tx_interrupt: WARNING tx_result %02x prio%d wr%d rd%d\n", sdr_compatible_str, tx_result_report, prio, ring->bd_wr_idx, ring->bd_rd_idx); - // printk("%s openwifi_tx_interrupt: rate&try: %d %d %03x; %d %d %03x; %d %d %03x; %d %d %03x\n", sdr_compatible_str, - // info->status.rates[0].idx,info->status.rates[0].count,info->status.rates[0].flags, - // info->status.rates[1].idx,info->status.rates[1].count,info->status.rates[1].flags, - // info->status.rates[2].idx,info->status.rates[2].count,info->status.rates[2].flags, - // info->status.rates[3].idx,info->status.rates[3].count,info->status.rates[3].flags); - } + ieee80211_tx_status_irqsafe(dev, skb); + + loop_count++; + + // printk("%s openwifi_tx_interrupt: loop %d prio %d rd %d\n", sdr_compatible_str, loop_count, prio, ring->bd_rd_idx); - info->status.rates[0].count = (tx_result&0xF) + 1; //according to our test, the 1st rate is the most important. we only do retry on the 1st rate - info->status.rates[1].idx = -1; - info->status.rates[2].idx = -1; - info->status.rates[3].idx = -1;//in mac80211.h: #define IEEE80211_TX_MAX_RATES 4 - if (tx_result&0x10) - printk("%s openwifi_tx_interrupt: WARNING tx_result %02x phy_tx_sn_hw %d. curr rd %d just wr %d\n", sdr_compatible_str,tx_result,phy_tx_sn_hw,current_rd_idx,just_wr_idx); - - ieee80211_tx_status_irqsafe(dev, skb); - //ring_len = (just_wr_idx>=current_rd_idx)?(just_wr_idx-current_rd_idx):(just_wr_idx+NUM_TX_BD-current_rd_idx); - ring_len = ((just_wr_idx-current_rd_idx)&(NUM_TX_BD-1)); - ring_room_left = NUM_TX_BD - ring_len; - if (ring_room_left > RING_ROOM_THRESHOLD && priv->tx_queue_stopped) { - unsigned int prio = skb_get_queue_mapping(skb); - ieee80211_wake_queue(dev, prio); - printk("%s openwifi_tx_interrupt: WARNING ieee80211_wake_queue. ring_room_left %d prio %d curr rd %d just wr %d\n", sdr_compatible_str,ring_room_left,prio,current_rd_idx,just_wr_idx); - priv->tx_queue_stopped = false; - } - - ring->bd_rd_idx = ((ring->bd_rd_idx+1)&(NUM_TX_BD-1)); - - //if (current_rd_idx == just_wr_idx) - break; // we have hit the sn, we should break + } else + break; } + if ( loop_count!=1 && ((priv->drv_tx_reg_val[DRV_TX_REG_IDX_PRINT_CFG])&1) ) + printk("%s openwifi_tx_interrupt: WARNING loop_count %d\n", sdr_compatible_str, loop_count); spin_unlock(&priv->lock); - return IRQ_HANDLED; } @@ -580,21 +558,22 @@ static void openwifi_tx(struct ieee80211_hw *dev, struct ieee80211_tx_control *control, struct sk_buff *skb) { + struct openwifi_priv *priv = dev->priv; + unsigned long flags; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct openwifi_priv *priv = dev->priv; - struct openwifi_ring *ring = &(priv->tx_ring); + struct openwifi_ring *ring; dma_addr_t dma_mapping_addr; - unsigned long flags; unsigned int prio, i; u32 num_dma_symbol, len_mac_pdu, num_dma_byte, len_phy_packet, num_byte_pad; u32 rate_signal_value,rate_hw_value,ack_flag; - u32 pkt_need_ack, addr1_low32=0, addr2_low32=0, addr3_low32=0, queue_idx=2, ring_len, ring_room_left, dma_reg, cts_reg;//, openofdm_state_history; + u32 pkt_need_ack, addr1_low32=0, addr2_low32=0, addr3_low32=0, queue_idx=2, dma_reg, cts_reg;//, openofdm_state_history; u16 addr1_high16=0, addr2_high16=0, addr3_high16=0, sc=0, cts_duration=0, cts_rate_hw_value = 0, cts_rate_signal_value=0, sifs, ack_duration=0, traffic_pkt_duration; u8 fc_flag,fc_type,fc_subtype,retry_limit_raw,*dma_buf,retry_limit_hw_value,rc_flags; - bool use_rts_cts, use_cts_protect, force_use_cts_protect=false, addr_flag, cts_use_traffic_rate; + bool use_rts_cts, use_cts_protect, addr_flag, cts_use_traffic_rate=false, force_use_cts_protect=false; __le16 frame_control,duration_id; - // static u32 openofdm_state_history_old=0; + u32 dma_fifo_no_room_flag, hw_queue_len; + enum dma_status status; // static bool led_status=0; // struct gpio_led_data *led_dat = cdev_to_gpio_led_data(priv->led[3]); @@ -608,31 +587,50 @@ static void openwifi_tx(struct ieee80211_hw *dev, // } if (test_mode==1){ - printk("%s openwifi_tx: test_mode==1\n", sdr_compatible_str); + printk("%s openwifi_tx: WARNING test_mode==1\n", sdr_compatible_str); goto openwifi_tx_early_out; } - if (skb->data_len>0)// more data are not in linear data area skb->data + + if (skb->data_len>0) {// more data are not in linear data area skb->data + printk("%s openwifi_tx: WARNING skb->data_len>0\n", sdr_compatible_str); goto openwifi_tx_early_out; + } len_mac_pdu = skb->len; len_phy_packet = len_mac_pdu + LEN_PHY_HEADER; num_dma_symbol = (len_phy_packet>>TX_INTF_NUM_BYTE_PER_DMA_SYMBOL_IN_BITS) + ((len_phy_packet&(TX_INTF_NUM_BYTE_PER_DMA_SYMBOL-1))!=0); + + // get Linux priority/queue setting info and target mac address + prio = skb_get_queue_mapping(skb); + addr1_low32 = *((u32*)(hdr->addr1+2)); + ring = &(priv->tx_ring[prio]); + + // -------------- DO your idea here! Map Linux/SW "prio" to hardware "queue_idx" ----------- + if (priv->slice_idx == 0xFFFFFFFF) {// use Linux default prio setting, if there isn't any slice config + queue_idx = prio; + } else {// customized prio to queue_idx mapping + //if (fc_type==2 && fc_subtype==0 && (!addr_flag)) { // for unicast data packet only + // check current packet belonging to which slice/hw-queue + for (i=0; idest_mac_addr_queue_map[i] == addr1_low32 ) { + break; + } + } + //} + queue_idx = (i>=MAX_NUM_HW_QUEUE?2:i); // if no address is hit, use FPGA queue 2. becuase the queue 2 is the longest. + } + // -------------------- end of Map Linux/SW "prio" to hardware "queue_idx" ------------------ + + // check whether the packet is bigger than DMA buffer size num_dma_byte = (num_dma_symbol< TX_BD_BUF_SIZE) { - dev_err(priv->tx_chan->device->dev, "WARNING num_dma_byte > TX_BD_BUF_SIZE\n"); + // dev_err(priv->tx_chan->device->dev, "sdr,sdr openwifi_tx: WARNING num_dma_byte > TX_BD_BUF_SIZE\n"); + printk("%s openwifi_tx: WARNING sn %d num_dma_byte > TX_BD_BUF_SIZE\n", sdr_compatible_str, ring->bd_wr_idx); goto openwifi_tx_early_out; } num_byte_pad = num_dma_byte-len_phy_packet; - // -----------preprocess some info from header and skb---------------- - prio = skb_get_queue_mapping(skb); - if (prio) { - printk("%s openwifi_tx: WARNING prio %d\n", sdr_compatible_str, prio); - } - - rate_hw_value = ieee80211_get_tx_rate(dev, info)->hw_value; - - addr1_low32 = *((u32*)(hdr->addr1+2)); + // get other info from packet header addr1_high16 = *((u16*)(hdr->addr1)); if (len_mac_pdu>=20) { addr2_low32 = *((u32*)(hdr->addr2+2)); @@ -662,22 +660,11 @@ static void openwifi_tx(struct ieee80211_hw *dev, pkt_need_ack = 0; } + // get Linux rate (MCS) setting + rate_hw_value = ieee80211_get_tx_rate(dev, info)->hw_value; //rate_hw_value = 10; //4:6M, 5:9M, 6:12M, 7:18M, 8:24M, 9:36M, 10:48M, 11:54M - if (priv->drv_tx_reg_val[0]>0 && fc_type==2 && (!addr_flag)) - rate_hw_value = priv->drv_tx_reg_val[0]; - - // check current packet belonging to which slice/hw-queue - i=0; - if (fc_type==2 && fc_subtype==0 && (!addr_flag)) { - for (; idest_mac_addr_queue_map[i] == addr1_low32 ) { - break; - } - } - } - queue_idx = i; - if (i>=MAX_NUM_HW_QUEUE) - queue_idx = 0; + if (priv->drv_tx_reg_val[DRV_TX_REG_IDX_RATE]>0 && fc_type==2 && (!addr_flag)) //rate override command + rate_hw_value = priv->drv_tx_reg_val[DRV_TX_REG_IDX_RATE]; retry_limit_raw = info->control.rates[0].count; @@ -686,10 +673,8 @@ static void openwifi_tx(struct ieee80211_hw *dev, use_cts_protect = ((rc_flags&IEEE80211_TX_RC_USE_CTS_PROTECT)!=0); if (use_rts_cts) - printk("%s openwifi_tx: WARNING use_rts_cts is not supported!\n", sdr_compatible_str); + printk("%s openwifi_tx: WARNING sn %d use_rts_cts is not supported!\n", sdr_compatible_str, ring->bd_wr_idx); - cts_use_traffic_rate = false; - force_use_cts_protect = false; if (use_cts_protect) { cts_rate_hw_value = ieee80211_get_rts_cts_rate(dev, info)->hw_value; cts_duration = le16_to_cpu(ieee80211_ctstoself_duration(dev,info->control.vif,len_mac_pdu,info)); @@ -702,12 +687,12 @@ static void openwifi_tx(struct ieee80211_hw *dev, cts_duration = traffic_pkt_duration + sifs + pkt_need_ack*(sifs+ack_duration); } - if ( !addr_flag ) - printk("%s openwifi_tx: %4dbytes %2dM FC%04x DI%04x addr1/2/3:%04x%08x/%04x%08x/%04x%08x SC%04x flag%08x retry%d ack%d q%d sn%04d R/CTS %d%d %dM %dus wr/rd %d/%d\n", sdr_compatible_str, + if ( (!addr_flag) && (priv->drv_tx_reg_val[DRV_TX_REG_IDX_PRINT_CFG]&2) ) + printk("%s openwifi_tx: %4dbytes %2dM FC%04x DI%04x addr1/2/3:%04x%08x/%04x%08x/%04x%08x SC%04x flag%08x retr%d ack%d prio%d q%d wr%d rd%d\n", sdr_compatible_str, len_mac_pdu, wifi_rate_all[rate_hw_value],frame_control,duration_id, reverse16(addr1_high16), reverse32(addr1_low32), reverse16(addr2_high16), reverse32(addr2_low32), reverse16(addr3_high16), reverse32(addr3_low32), - sc,info->flags,retry_limit_raw,pkt_need_ack,queue_idx,priv->phy_tx_sn, - use_rts_cts,use_cts_protect|force_use_cts_protect,wifi_rate_all[cts_rate_hw_value],cts_duration, + sc, info->flags, retry_limit_raw, pkt_need_ack, prio, queue_idx, + // use_rts_cts,use_cts_protect|force_use_cts_protect,wifi_rate_all[cts_rate_hw_value],cts_duration, ring->bd_wr_idx,ring->bd_rd_idx); // printk("%s openwifi_tx: rate&try: %d %d %03x; %d %d %03x; %d %d %03x; %d %d %03x\n", sdr_compatible_str, @@ -747,8 +732,9 @@ static void openwifi_tx(struct ieee80211_hw *dev, // when skb does not have enough headroom, skb_push will cause kernel panic. headroom needs to be extended if necessary if (skb_headroom(skb)bd_wr_idx); if ((skb_new = skb_realloc_headroom(skb, LEN_PHY_HEADER)) == NULL) { - printk("%s openwifi_tx: WARNING skb_realloc_headroom failed!\n", sdr_compatible_str); + printk("%s openwifi_tx: WARNING sn %d skb_realloc_headroom failed!\n", sdr_compatible_str, ring->bd_wr_idx); goto openwifi_tx_early_out; } if (skb->sk != NULL) @@ -759,38 +745,21 @@ static void openwifi_tx(struct ieee80211_hw *dev, skb_push( skb, LEN_PHY_HEADER ); rate_signal_value = calc_phy_header(rate_hw_value, len_mac_pdu+LEN_PHY_CRC, skb->data); //fill the phy header + //make sure dma length is integer times of DDC_NUM_BYTE_PER_DMA_SYMBOL if (skb_tailroom(skb)bd_wr_idx); + // skb_pull(skb, LEN_PHY_HEADER); goto openwifi_tx_early_out; } skb_put( skb, num_byte_pad ); retry_limit_hw_value = (retry_limit_raw - 1)&0xF; dma_buf = skb->data; - //(*((u16*)(dma_buf+6))) = priv->phy_tx_sn; - //(*((u32*)(dma_buf+8))) = num_dma_byte; - //(*((u32*)(dma_buf+12))) = num_byte_pad; cts_rate_signal_value = wifi_mcs_table_11b_force_up[cts_rate_hw_value]; cts_reg = (((use_cts_protect|force_use_cts_protect)<<31)|(cts_use_traffic_rate<<30)|(cts_duration<<8)|(cts_rate_signal_value<<4)|rate_signal_value); - dma_reg = ( (( ((priv->phy_tx_sn<lock, flags); // from now on, we'd better avoid interrupt because wr/rd idx will matter - - //ring_len = (ring->bd_wr_idx>=ring->bd_rd_idx)?(ring->bd_wr_idx-ring->bd_rd_idx):(ring->bd_wr_idx+NUM_TX_BD-ring->bd_rd_idx); - ring_len = ((ring->bd_wr_idx-ring->bd_rd_idx)&(NUM_TX_BD-1)); - ring_room_left = NUM_TX_BD - ring_len; - if (ring_room_left < RING_ROOM_THRESHOLD) - printk("%s openwifi_tx: WARNING ring len %d\n", sdr_compatible_str,ring_len); -// printk("%s openwifi_tx: WARNING ring len %d HW fifo %d q %d\n", sdr_compatible_str,ring_len,tx_intf_api->TX_INTF_REG_S_AXIS_FIFO_DATA_COUNT_read()&0xFFFF, ((tx_intf_api->TX_INTF_REG_PHY_QUEUE_TX_SN_read())>>16)&0xFF ); - - if (ring_room_left <= RING_ROOM_THRESHOLD && priv->tx_queue_stopped == false) { - ieee80211_stop_queue(dev, prio); - printk("%s openwifi_tx: WARNING ieee80211_stop_queue. ring_room_left %d!\n", sdr_compatible_str,ring_room_left); - priv->tx_queue_stopped = true; - spin_unlock_irqrestore(&priv->lock, flags); - goto openwifi_tx_early_out; - } + dma_reg = ( (( ((prio<<(NUM_BIT_MAX_NUM_HW_QUEUE+NUM_BIT_MAX_PHY_TX_SN))|(ring->bd_wr_idx<queue, skb); + spin_lock_irqsave(&priv->lock, flags); // from now on, we'd better avoid interrupt because ring->stop_flag is shared with interrupt + + // -------------check whether FPGA dma fifo and queue (queue_idx) has enough room------------- + dma_fifo_no_room_flag = tx_intf_api->TX_INTF_REG_S_AXIS_FIFO_NO_ROOM_read(); + hw_queue_len = tx_intf_api->TX_INTF_REG_QUEUE_FIFO_DATA_COUNT_read(); + if ( ((dma_fifo_no_room_flag>>queue_idx)&1) || ((NUM_TX_BD-((hw_queue_len>>(queue_idx*8))&0xFF))stop_flag==1 ) { + ieee80211_stop_queue(dev, prio); // here we should stop those prio related to the queue idx flag set in TX_INTF_REG_S_AXIS_FIFO_NO_ROOM_read + printk("%s openwifi_tx: WARNING ieee80211_stop_queue prio %d queue %d no room flag %x hw queue len %08x request %d wr %d rd %d\n", sdr_compatible_str, + prio, queue_idx, dma_fifo_no_room_flag, hw_queue_len, num_dma_symbol, ring->bd_wr_idx, ring->bd_rd_idx); + ring->stop_flag = 1; + goto openwifi_tx_early_out_after_lock; + } + // --------end of check whether FPGA fifo (queue_idx) has enough room------------ + + status = dma_async_is_tx_complete(priv->tx_chan, priv->tx_cookie, NULL, NULL); + if (status!=DMA_COMPLETE) { + printk("%s openwifi_tx: WARNING status!=DMA_COMPLETE\n", sdr_compatible_str); + goto openwifi_tx_early_out_after_lock; + } + + if ( ((*(u32*)(&(skb->data[0])))&0xFF000000) || (*(u32*)(&(skb->data[12]))) || (*(u32*)(&(skb->data[8]))) || (*(u32*)(&(skb->data[4]))) ) { + printk("%s openwifi_tx: WARNING 1 %d %08x %08x %08x %08x\n", sdr_compatible_str, num_byte_pad, *(u32*)(&(skb->data[12])), *(u32*)(&(skb->data[8])), *(u32*)(&(skb->data[4])), *(u32*)(&(skb->data[0]))); + goto openwifi_tx_early_out_after_lock; + } //-------------------------fire skb DMA to hardware---------------------------------- dma_mapping_addr = dma_map_single(priv->tx_chan->device->dev, dma_buf, num_dma_byte, DMA_MEM_TO_DEV); if (dma_mapping_error(priv->tx_chan->device->dev,dma_mapping_addr)) { - dev_err(priv->tx_chan->device->dev, "WARNING TX DMA mapping error\n"); - goto openwifi_tx_skb_drop_out; + // dev_err(priv->tx_chan->device->dev, "sdr,sdr openwifi_tx: WARNING TX DMA mapping error\n"); + printk("%s openwifi_tx: WARNING sn %d TX DMA mapping error\n", sdr_compatible_str, ring->bd_wr_idx); + goto openwifi_tx_early_out_after_lock; } - sg_init_table(&(priv->tx_sg), 1); - + // sg_init_table(&tx_sg, 1); // only need to be initialized once in openwifi_start sg_dma_address( &(priv->tx_sg) ) = dma_mapping_addr; sg_dma_len( &(priv->tx_sg) ) = num_dma_byte; @@ -823,50 +815,45 @@ static void openwifi_tx(struct ieee80211_hw *dev, tx_intf_api->TX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write(dma_reg); priv->txd = priv->tx_chan->device->device_prep_slave_sg(priv->tx_chan, &(priv->tx_sg),1,DMA_MEM_TO_DEV, DMA_CTRL_ACK | DMA_PREP_INTERRUPT, NULL); if (!(priv->txd)) { - printk("%s openwifi_tx: WARNING device_prep_slave_sg %p\n", sdr_compatible_str, (void*)(priv->txd)); + printk("%s openwifi_tx: WARNING sn %d device_prep_slave_sg %p\n", sdr_compatible_str, ring->bd_wr_idx, (void*)(priv->txd)); goto openwifi_tx_after_dma_mapping; } - //we use interrupt instead of dma callback - priv->txd->callback = 0; - priv->txd->callback_param = 0; priv->tx_cookie = priv->txd->tx_submit(priv->txd); if (dma_submit_error(priv->tx_cookie)) { - printk("%s openwifi_tx: WARNING dma_submit_error(tx_cookie) %d\n", sdr_compatible_str, (u32)(priv->tx_cookie)); + printk("%s openwifi_tx: WARNING sn %d dma_submit_error(tx_cookie) %d\n", sdr_compatible_str, ring->bd_wr_idx, (u32)(priv->tx_cookie)); goto openwifi_tx_after_dma_mapping; } // seems everything ok. let's mark this pkt in bd descriptor ring - ring->bds[ring->bd_wr_idx].num_dma_byte=num_dma_byte; - ring->bds[ring->bd_wr_idx].sn=priv->phy_tx_sn; - // ring->bds[ring->bd_wr_idx].hw_queue_idx=queue_idx; - // ring->bds[ring->bd_wr_idx].retry_limit=retry_limit_hw_value; - // ring->bds[ring->bd_wr_idx].need_ack=pkt_need_ack; ring->bds[ring->bd_wr_idx].skb_linked = skb; ring->bds[ring->bd_wr_idx].dma_mapping_addr = dma_mapping_addr; ring->bd_wr_idx = ((ring->bd_wr_idx+1)&(NUM_TX_BD-1)); - priv->phy_tx_sn = ( (priv->phy_tx_sn+1)&MAX_PHY_TX_SN ); dma_async_issue_pending(priv->tx_chan); + if ( ((*(u32*)(&(skb->data[0])))&0xFF000000) || (*(u32*)(&(skb->data[12]))) || (*(u32*)(&(skb->data[8]))) || (*(u32*)(&(skb->data[4]))) ) + printk("%s openwifi_tx: WARNING 2 %08x %08x %08x %08x\n", sdr_compatible_str, *(u32*)(&(skb->data[12])), *(u32*)(&(skb->data[8])), *(u32*)(&(skb->data[4])), *(u32*)(&(skb->data[0]))); + spin_unlock_irqrestore(&priv->lock, flags); return; openwifi_tx_after_dma_mapping: - printk("%s openwifi_tx: WARNING openwifi_tx_after_dma_mapping phy_tx_sn %d queue %d\n", sdr_compatible_str,priv->phy_tx_sn,queue_idx); dma_unmap_single(priv->tx_chan->device->dev, dma_mapping_addr, num_dma_byte, DMA_MEM_TO_DEV); - spin_unlock_irqrestore(&priv->lock, flags); -openwifi_tx_skb_drop_out: - printk("%s openwifi_tx: WARNING openwifi_tx_skb_drop_out phy_tx_sn %d queue %d\n", sdr_compatible_str,priv->phy_tx_sn,queue_idx); +openwifi_tx_early_out_after_lock: + // skb_pull(skb, LEN_PHY_HEADER); + dev_kfree_skb(skb); spin_unlock_irqrestore(&priv->lock, flags); + // printk("%s openwifi_tx: WARNING openwifi_tx_after_dma_mapping phy_tx_sn %d queue %d\n", sdr_compatible_str,priv->phy_tx_sn,queue_idx); + return; openwifi_tx_early_out: dev_kfree_skb(skb); - printk("%s openwifi_tx: WARNING openwifi_tx_early_out phy_tx_sn %d queue %d\n", sdr_compatible_str,priv->phy_tx_sn,queue_idx); + // printk("%s openwifi_tx: WARNING openwifi_tx_early_out phy_tx_sn %d queue %d\n", sdr_compatible_str,priv->phy_tx_sn,queue_idx); } static int openwifi_start(struct ieee80211_hw *dev) @@ -879,6 +866,10 @@ static int openwifi_start(struct ieee80211_hw *dev) priv->vif[i] = NULL; } + memset(priv->drv_tx_reg_val, 0, sizeof(priv->drv_tx_reg_val)); + memset(priv->drv_rx_reg_val, 0, sizeof(priv->drv_rx_reg_val)); + memset(priv->drv_xpu_reg_val, 0, sizeof(priv->drv_xpu_reg_val)); + //turn on radio if (priv->tx_intf_cfg == TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT1) { ad9361_set_tx_atten(priv->ad9361_phy, AD9361_RADIO_ON_TX_ATT, false, true, true); // AD9361_RADIO_ON_TX_ATT 3000 means 3dB, 0 means 0dB @@ -940,18 +931,41 @@ static int openwifi_start(struct ieee80211_hw *dev) xpu_api->XPU_REG_BB_RF_DELAY_write(49);//add .5us for slightly longer fir xpu_api->XPU_REG_MAC_ADDR_write(priv->mac_addr); - xpu_api->XPU_REG_SLICE_COUNT_TOTAL0_write(50000-1); // total 50ms. - xpu_api->XPU_REG_SLICE_COUNT_START0_write(0); //start 0ms - xpu_api->XPU_REG_SLICE_COUNT_END0_write(50000-1); //end 50ms - xpu_api->XPU_REG_SLICE_COUNT_TOTAL1_write(50000-1); // total 50ms - xpu_api->XPU_REG_SLICE_COUNT_START1_write(49000); //start 49ms - xpu_api->XPU_REG_SLICE_COUNT_END1_write(50000-1); //end 50ms + // setup time schedule of 4 slices + // slice 0 + xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write(50000-1); // total 50ms + xpu_api->XPU_REG_SLICE_COUNT_START_write(0); //start 0ms + xpu_api->XPU_REG_SLICE_COUNT_END_write(50000-1); //end 50ms + + // slice 1 + xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((1<<20)|(50000-1)); // total 50ms + xpu_api->XPU_REG_SLICE_COUNT_START_write((1<<20)|(0)); //start 0ms + //xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(20000-1)); //end 20ms + xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(50000-1)); //end 20ms + + // slice 2 + xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((2<<20)|(50000-1)); // total 50ms + //xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(20000)); //start 20ms + xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(0)); //start 20ms + //xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(40000-1)); //end 20ms + xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(50000-1)); //end 20ms + + // slice 3 + xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((3<<20)|(50000-1)); // total 50ms + //xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(40000)); //start 40ms + xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(0)); //start 40ms + //xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms + xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms + + // all slice sync rest + xpu_api->XPU_REG_MULTI_RST_write(1<<7); //bit7 reset the counter for all queues at the same time + xpu_api->XPU_REG_MULTI_RST_write(0<<7); //xpu_api->XPU_REG_MAC_ADDR_HIGH_write( (*( (u16*)(priv->mac_addr + 4) )) ); printk("%s openwifi_start: rx_intf_cfg %d openofdm_rx_cfg %d tx_intf_cfg %d openofdm_tx_cfg %d\n",sdr_compatible_str, priv->rx_intf_cfg, priv->openofdm_rx_cfg, priv->tx_intf_cfg, priv->openofdm_tx_cfg); printk("%s openwifi_start: rx_freq_offset_to_lo_MHz %d tx_freq_offset_to_lo_MHz %d\n",sdr_compatible_str, priv->rx_freq_offset_to_lo_MHz, priv->tx_freq_offset_to_lo_MHz); - tx_intf_api->TX_INTF_REG_INTERRUPT_SEL_write(0x30040); //disable tx interrupt + tx_intf_api->TX_INTF_REG_INTERRUPT_SEL_write(0x3004F); //disable tx interrupt rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_write(0x100); // disable rx interrupt by interrupt test mode rx_intf_api->RX_INTF_REG_M_AXIS_RST_write(1); // hold M AXIS in reset status @@ -965,8 +979,6 @@ static int openwifi_start(struct ieee80211_hw *dev) ret = PTR_ERR(priv->rx_chan); pr_err("%s openwifi_start: No Rx channel %d\n",sdr_compatible_str,ret); goto err_dma; - //goto err_free_reg; - //goto err_free_dev; } priv->tx_chan = dma_request_slave_channel(&(priv->pdev->dev), "tx_dma_mm2s"); @@ -974,8 +986,6 @@ static int openwifi_start(struct ieee80211_hw *dev) ret = PTR_ERR(priv->tx_chan); pr_err("%s openwifi_start: No Tx channel %d\n",sdr_compatible_str,ret); goto err_dma; - //goto err_free_reg; - //goto err_free_dev; } printk("%s openwifi_start: DMA channel setup successfully.\n",sdr_compatible_str); @@ -986,10 +996,11 @@ static int openwifi_start(struct ieee80211_hw *dev) } priv->seqno=0; - priv->phy_tx_sn=0; - if ((ret = openwifi_init_tx_ring(priv))) { - printk("%s openwifi_start: openwifi_init_tx_ring ret %d\n", sdr_compatible_str,ret); - goto err_free_rings; + for (i=0; iRX_INTF_REG_INTERRUPT_TEST_write(0x000); // enable rx interrupt get normal fcs valid pass through ddc to ARM - tx_intf_api->TX_INTF_REG_INTERRUPT_SEL_write(0x40); //enable tx interrupt + tx_intf_api->TX_INTF_REG_INTERRUPT_SEL_write(0x4F); //enable tx interrupt rx_intf_api->RX_INTF_REG_M_AXIS_RST_write(0); // release M AXIS xpu_api->XPU_REG_TSF_LOAD_VAL_write(0,0); // reset tsf timer @@ -1030,7 +1041,8 @@ normal_out: err_free_rings: openwifi_free_rx_ring(priv); - openwifi_free_tx_ring(priv); + for (i=0; iTX_INTF_REG_INTERRUPT_SEL_write(0x30040); //disable tx interrupt + tx_intf_api->TX_INTF_REG_INTERRUPT_SEL_write(0x3004F); //disable tx interrupt rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_write(0x100); // disable fcs_valid by interrupt test mode rx_intf_api->RX_INTF_REG_M_AXIS_RST_write(1); // hold M AXIS in reset status @@ -1073,7 +1085,8 @@ static void openwifi_stop(struct ieee80211_hw *dev) } openwifi_free_rx_ring(priv); - openwifi_free_tx_ring(priv); + for (i=0; irx_chan)); dmaengine_terminate_all(priv->rx_chan); @@ -1372,134 +1385,163 @@ static int openwifi_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif * if (nla_put_u32(skb, OPENWIFI_ATTR_GAP, tmp)) goto nla_put_failure; return cfg80211_testmode_reply(skb); - case OPENWIFI_CMD_SET_ADDR0: - if (!tb[OPENWIFI_ATTR_ADDR0]) + case OPENWIFI_CMD_SET_SLICE_IDX: + if (!tb[OPENWIFI_ATTR_SLICE_IDX]) return -EINVAL; - tmp = nla_get_u32(tb[OPENWIFI_ATTR_ADDR0]); - printk("%s set openwifi slice0_target_mac_addr(low32) in hex: %08x\n", sdr_compatible_str, tmp); - priv->dest_mac_addr_queue_map[0] = reverse32(tmp); + tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_IDX]); + printk("%s set openwifi slice_idx in hex: %08x\n", sdr_compatible_str, tmp); + if (tmp == MAX_NUM_HW_QUEUE) { + printk("%s set openwifi slice_idx reset all queue counter.\n", sdr_compatible_str); + xpu_api->XPU_REG_MULTI_RST_write(1<<7); //bit7 reset the counter for all queues at the same time + xpu_api->XPU_REG_MULTI_RST_write(0<<7); + } else { + priv->slice_idx = tmp; + } return 0; - case OPENWIFI_CMD_GET_ADDR0: + case OPENWIFI_CMD_GET_SLICE_IDX: skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); if (!skb) return -ENOMEM; - tmp = reverse32(priv->dest_mac_addr_queue_map[0]); - if (nla_put_u32(skb, OPENWIFI_ATTR_ADDR0, tmp)) + tmp = priv->slice_idx; + if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_IDX, tmp)) goto nla_put_failure; - printk("%s get openwifi slice0_target_mac_addr(low32) in hex: %08x\n", sdr_compatible_str, tmp); + printk("%s get openwifi slice_idx in hex: %08x\n", sdr_compatible_str, tmp); return cfg80211_testmode_reply(skb); - case OPENWIFI_CMD_SET_ADDR1: - if (!tb[OPENWIFI_ATTR_ADDR1]) + case OPENWIFI_CMD_SET_ADDR: + if (!tb[OPENWIFI_ATTR_ADDR]) return -EINVAL; - tmp = nla_get_u32(tb[OPENWIFI_ATTR_ADDR1]); - printk("%s set openwifi slice1_target_mac_addr(low32) in hex: %08x\n", sdr_compatible_str, tmp); - priv->dest_mac_addr_queue_map[1] = reverse32(tmp); + tmp = nla_get_u32(tb[OPENWIFI_ATTR_ADDR]); + if (priv->slice_idx>=MAX_NUM_HW_QUEUE) { + printk("%s set openwifi slice_target_mac_addr(low32) WARNING: current slice idx %d is invalid!\n", sdr_compatible_str, priv->slice_idx); + } else { + printk("%s set openwifi slice_target_mac_addr(low32) in hex: %08x to slice %d\n", sdr_compatible_str, tmp, priv->slice_idx); + priv->dest_mac_addr_queue_map[priv->slice_idx] = reverse32(tmp); + } return 0; - case OPENWIFI_CMD_GET_ADDR1: + case OPENWIFI_CMD_GET_ADDR: skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); if (!skb) return -ENOMEM; - tmp = reverse32(priv->dest_mac_addr_queue_map[1]); - if (nla_put_u32(skb, OPENWIFI_ATTR_ADDR1, tmp)) + if (priv->slice_idx>=MAX_NUM_HW_QUEUE) { + tmp = -1; + } else { + tmp = reverse32(priv->dest_mac_addr_queue_map[priv->slice_idx]); + } + if (nla_put_u32(skb, OPENWIFI_ATTR_ADDR, tmp)) goto nla_put_failure; - printk("%s get openwifi slice1_target_mac_addr(low32) in hex: %08x\n", sdr_compatible_str, tmp); + printk("%s get openwifi slice_target_mac_addr(low32) in hex: %08x of slice %d\n", sdr_compatible_str, tmp, priv->slice_idx); return cfg80211_testmode_reply(skb); - case OPENWIFI_CMD_SET_SLICE_TOTAL0: - if (!tb[OPENWIFI_ATTR_SLICE_TOTAL0]) + case OPENWIFI_CMD_SET_SLICE_TOTAL: + if (!tb[OPENWIFI_ATTR_SLICE_TOTAL]) return -EINVAL; - tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_TOTAL0]); - printk("%s set SLICE_TOTAL0(duration) to %d usec\n", sdr_compatible_str, tmp); - xpu_api->XPU_REG_SLICE_COUNT_TOTAL0_write(tmp); + tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_TOTAL]); + if (priv->slice_idx>=MAX_NUM_HW_QUEUE) { + printk("%s set SLICE_TOTAL(duration) WARNING: current slice idx %d is invalid!\n", sdr_compatible_str, priv->slice_idx); + } else { + printk("%s set SLICE_TOTAL(duration) %d usec to slice %d\n", sdr_compatible_str, tmp, priv->slice_idx); + xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((priv->slice_idx<<20)|tmp); + } return 0; - case OPENWIFI_CMD_GET_SLICE_TOTAL0: + case OPENWIFI_CMD_GET_SLICE_TOTAL: skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); if (!skb) return -ENOMEM; - tmp = (xpu_api->XPU_REG_SLICE_COUNT_TOTAL0_read()); - if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_TOTAL0, tmp)) + tmp = (xpu_api->XPU_REG_SLICE_COUNT_TOTAL_read()); + printk("%s get SLICE_TOTAL(duration) %d usec of slice %d\n", sdr_compatible_str, tmp&0xFFFFF, tmp>>20); + if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_TOTAL, tmp)) goto nla_put_failure; return cfg80211_testmode_reply(skb); - case OPENWIFI_CMD_SET_SLICE_START0: - if (!tb[OPENWIFI_ATTR_SLICE_START0]) + case OPENWIFI_CMD_SET_SLICE_START: + if (!tb[OPENWIFI_ATTR_SLICE_START]) return -EINVAL; - tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_START0]); - printk("%s set SLICE_START0(duration) to %d usec\n", sdr_compatible_str, tmp); - xpu_api->XPU_REG_SLICE_COUNT_START0_write(tmp); + tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_START]); + if (priv->slice_idx>=MAX_NUM_HW_QUEUE) { + printk("%s set SLICE_START(duration) WARNING: current slice idx %d is invalid!\n", sdr_compatible_str, priv->slice_idx); + } else { + printk("%s set SLICE_START(duration) %d usec to slice %d\n", sdr_compatible_str, tmp, priv->slice_idx); + xpu_api->XPU_REG_SLICE_COUNT_START_write((priv->slice_idx<<20)|tmp); + } return 0; - case OPENWIFI_CMD_GET_SLICE_START0: + case OPENWIFI_CMD_GET_SLICE_START: skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); if (!skb) return -ENOMEM; - tmp = (xpu_api->XPU_REG_SLICE_COUNT_START0_read()); - if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_START0, tmp)) + tmp = (xpu_api->XPU_REG_SLICE_COUNT_START_read()); + printk("%s get SLICE_START(duration) %d usec of slice %d\n", sdr_compatible_str, tmp&0xFFFFF, tmp>>20); + if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_START, tmp)) goto nla_put_failure; return cfg80211_testmode_reply(skb); - case OPENWIFI_CMD_SET_SLICE_END0: - if (!tb[OPENWIFI_ATTR_SLICE_END0]) + case OPENWIFI_CMD_SET_SLICE_END: + if (!tb[OPENWIFI_ATTR_SLICE_END]) return -EINVAL; - tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_END0]); - printk("%s set SLICE_END0(duration) to %d usec\n", sdr_compatible_str, tmp); - xpu_api->XPU_REG_SLICE_COUNT_END0_write(tmp); + tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_END]); + if (priv->slice_idx>=MAX_NUM_HW_QUEUE) { + printk("%s set SLICE_END(duration) WARNING: current slice idx %d is invalid!\n", sdr_compatible_str, priv->slice_idx); + } else { + printk("%s set SLICE_END(duration) %d usec to slice %d\n", sdr_compatible_str, tmp, priv->slice_idx); + xpu_api->XPU_REG_SLICE_COUNT_END_write((priv->slice_idx<<20)|tmp); + } return 0; - case OPENWIFI_CMD_GET_SLICE_END0: + case OPENWIFI_CMD_GET_SLICE_END: skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); if (!skb) return -ENOMEM; - tmp = (xpu_api->XPU_REG_SLICE_COUNT_END0_read()); - if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_END0, tmp)) + tmp = (xpu_api->XPU_REG_SLICE_COUNT_END_read()); + printk("%s get SLICE_END(duration) %d usec of slice %d\n", sdr_compatible_str, tmp&0xFFFFF, tmp>>20); + if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_END, tmp)) goto nla_put_failure; return cfg80211_testmode_reply(skb); - case OPENWIFI_CMD_SET_SLICE_TOTAL1: - if (!tb[OPENWIFI_ATTR_SLICE_TOTAL1]) - return -EINVAL; - tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_TOTAL1]); - printk("%s set SLICE_TOTAL1(duration) to %d usec\n", sdr_compatible_str, tmp); - xpu_api->XPU_REG_SLICE_COUNT_TOTAL1_write(tmp); - return 0; - case OPENWIFI_CMD_GET_SLICE_TOTAL1: - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); - if (!skb) - return -ENOMEM; - tmp = (xpu_api->XPU_REG_SLICE_COUNT_TOTAL1_read()); - if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_TOTAL1, tmp)) - goto nla_put_failure; - return cfg80211_testmode_reply(skb); + // case OPENWIFI_CMD_SET_SLICE_TOTAL1: + // if (!tb[OPENWIFI_ATTR_SLICE_TOTAL1]) + // return -EINVAL; + // tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_TOTAL1]); + // printk("%s set SLICE_TOTAL1(duration) to %d usec\n", sdr_compatible_str, tmp); + // // xpu_api->XPU_REG_SLICE_COUNT_TOTAL1_write(tmp); + // return 0; + // case OPENWIFI_CMD_GET_SLICE_TOTAL1: + // skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); + // if (!skb) + // return -ENOMEM; + // // tmp = (xpu_api->XPU_REG_SLICE_COUNT_TOTAL1_read()); + // if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_TOTAL1, tmp)) + // goto nla_put_failure; + // return cfg80211_testmode_reply(skb); - case OPENWIFI_CMD_SET_SLICE_START1: - if (!tb[OPENWIFI_ATTR_SLICE_START1]) - return -EINVAL; - tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_START1]); - printk("%s set SLICE_START1(duration) to %d usec\n", sdr_compatible_str, tmp); - xpu_api->XPU_REG_SLICE_COUNT_START1_write(tmp); - return 0; - case OPENWIFI_CMD_GET_SLICE_START1: - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); - if (!skb) - return -ENOMEM; - tmp = (xpu_api->XPU_REG_SLICE_COUNT_START1_read()); - if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_START1, tmp)) - goto nla_put_failure; - return cfg80211_testmode_reply(skb); + // case OPENWIFI_CMD_SET_SLICE_START1: + // if (!tb[OPENWIFI_ATTR_SLICE_START1]) + // return -EINVAL; + // tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_START1]); + // printk("%s set SLICE_START1(duration) to %d usec\n", sdr_compatible_str, tmp); + // // xpu_api->XPU_REG_SLICE_COUNT_START1_write(tmp); + // return 0; + // case OPENWIFI_CMD_GET_SLICE_START1: + // skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); + // if (!skb) + // return -ENOMEM; + // // tmp = (xpu_api->XPU_REG_SLICE_COUNT_START1_read()); + // if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_START1, tmp)) + // goto nla_put_failure; + // return cfg80211_testmode_reply(skb); - case OPENWIFI_CMD_SET_SLICE_END1: - if (!tb[OPENWIFI_ATTR_SLICE_END1]) - return -EINVAL; - tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_END1]); - printk("%s set SLICE_END1(duration) to %d usec\n", sdr_compatible_str, tmp); - xpu_api->XPU_REG_SLICE_COUNT_END1_write(tmp); - return 0; - case OPENWIFI_CMD_GET_SLICE_END1: - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); - if (!skb) - return -ENOMEM; - tmp = (xpu_api->XPU_REG_SLICE_COUNT_END1_read()); - if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_END1, tmp)) - goto nla_put_failure; - return cfg80211_testmode_reply(skb); + // case OPENWIFI_CMD_SET_SLICE_END1: + // if (!tb[OPENWIFI_ATTR_SLICE_END1]) + // return -EINVAL; + // tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_END1]); + // printk("%s set SLICE_END1(duration) to %d usec\n", sdr_compatible_str, tmp); + // // xpu_api->XPU_REG_SLICE_COUNT_END1_write(tmp); + // return 0; + // case OPENWIFI_CMD_GET_SLICE_END1: + // skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, nla_total_size(sizeof(u32))); + // if (!skb) + // return -ENOMEM; + // // tmp = (xpu_api->XPU_REG_SLICE_COUNT_END1_read()); + // if (nla_put_u32(skb, OPENWIFI_ATTR_SLICE_END1, tmp)) + // goto nla_put_failure; + // return cfg80211_testmode_reply(skb); case OPENWIFI_CMD_SET_RSSI_TH: if (!tb[OPENWIFI_ATTR_RSSI_TH]) @@ -1516,16 +1558,17 @@ static int openwifi_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif * if (nla_put_u32(skb, OPENWIFI_ATTR_RSSI_TH, tmp)) goto nla_put_failure; return cfg80211_testmode_reply(skb); - case OPENWIFI_CMD_SET_TSF: - printk("openwifi_set_tsf_1"); - if ( (!tb[OPENWIFI_ATTR_HIGH_TSF]) || (!tb[OPENWIFI_ATTR_LOW_TSF]) ) - return -EINVAL; - printk("openwifi_set_tsf_2"); - tsft_high = nla_get_u32(tb[OPENWIFI_ATTR_HIGH_TSF]); - tsft_low = nla_get_u32(tb[OPENWIFI_ATTR_LOW_TSF]); - xpu_api->XPU_REG_TSF_LOAD_VAL_write(tsft_high,tsft_low); - printk("%s openwifi_set_tsf: %08x%08x\n", sdr_compatible_str,tsft_high,tsft_low); - return 0; + + case OPENWIFI_CMD_SET_TSF: + printk("openwifi_set_tsf_1"); + if ( (!tb[OPENWIFI_ATTR_HIGH_TSF]) || (!tb[OPENWIFI_ATTR_LOW_TSF]) ) + return -EINVAL; + printk("openwifi_set_tsf_2"); + tsft_high = nla_get_u32(tb[OPENWIFI_ATTR_HIGH_TSF]); + tsft_low = nla_get_u32(tb[OPENWIFI_ATTR_LOW_TSF]); + xpu_api->XPU_REG_TSF_LOAD_VAL_write(tsft_high,tsft_low); + printk("%s openwifi_set_tsf: %08x%08x\n", sdr_compatible_str,tsft_high,tsft_low); + return 0; case REG_CMD_SET: if ( (!tb[REG_ATTR_ADDR]) || (!tb[REG_ATTR_VAL]) ) @@ -1549,34 +1592,43 @@ static int openwifi_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif * else if (reg_cat==6) xpu_api->reg_write(reg_addr,reg_val); else if (reg_cat==7) { - priv->drv_rx_reg_val[reg_addr_idx]=reg_val; - if (reg_addr_idx==1) { - if (reg_val==0) - priv->rx_intf_cfg = RX_INTF_BW_20MHZ_AT_0MHZ_ANT0; - else - priv->rx_intf_cfg = RX_INTF_BW_20MHZ_AT_0MHZ_ANT1; + if (reg_addr_idx>=0 && reg_addr_idxdrv_rx_reg_val[reg_addr_idx]=reg_val; + if (reg_addr_idx==DRV_RX_REG_IDX_FREQ_BW_CFG) { + if (reg_val==0) + priv->rx_intf_cfg = RX_INTF_BW_20MHZ_AT_0MHZ_ANT0; + else + priv->rx_intf_cfg = RX_INTF_BW_20MHZ_AT_0MHZ_ANT1; - priv->rx_freq_offset_to_lo_MHz = rx_intf_fo_mapping[priv->rx_intf_cfg]; - //priv->tx_freq_offset_to_lo_MHz = tx_intf_fo_mapping[priv->tx_intf_cfg]; - } + priv->rx_freq_offset_to_lo_MHz = rx_intf_fo_mapping[priv->rx_intf_cfg]; + //priv->tx_freq_offset_to_lo_MHz = tx_intf_fo_mapping[priv->tx_intf_cfg]; + } + } else + printk("%s reg_addr_idx %d is out of range!\n", sdr_compatible_str, reg_addr_idx); } else if (reg_cat==8) { - priv->drv_tx_reg_val[reg_addr_idx]=reg_val; - if (reg_addr_idx==1) { - if (reg_val==0) { - priv->tx_intf_cfg = TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT0; - ad9361_set_tx_atten(priv->ad9361_phy, AD9361_RADIO_ON_TX_ATT, true, false, true); - } else { - priv->tx_intf_cfg = TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT1; - ad9361_set_tx_atten(priv->ad9361_phy, AD9361_RADIO_ON_TX_ATT, false, true, true); + if (reg_addr_idx>=0 && reg_addr_idxdrv_tx_reg_val[reg_addr_idx]=reg_val; + if (reg_addr_idx==DRV_TX_REG_IDX_FREQ_BW_CFG) { + if (reg_val==0) { + priv->tx_intf_cfg = TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT0; + ad9361_set_tx_atten(priv->ad9361_phy, AD9361_RADIO_ON_TX_ATT, true, false, true); + } else { + priv->tx_intf_cfg = TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT1; + ad9361_set_tx_atten(priv->ad9361_phy, AD9361_RADIO_ON_TX_ATT, false, true, true); + } + + //priv->rx_freq_offset_to_lo_MHz = rx_intf_fo_mapping[priv->rx_intf_cfg]; + priv->tx_freq_offset_to_lo_MHz = tx_intf_fo_mapping[priv->tx_intf_cfg]; } - - //priv->rx_freq_offset_to_lo_MHz = rx_intf_fo_mapping[priv->rx_intf_cfg]; - priv->tx_freq_offset_to_lo_MHz = tx_intf_fo_mapping[priv->tx_intf_cfg]; - } + } else + printk("%s reg_addr_idx %d is out of range!\n", sdr_compatible_str, reg_addr_idx); } else if (reg_cat==9) { - priv->drv_xpu_reg_val[reg_addr_idx]=reg_val; + if (reg_addr_idx>=0 && reg_addr_idxdrv_xpu_reg_val[reg_addr_idx]=reg_val; + else + printk("%s reg_addr_idx %d is out of range!\n", sdr_compatible_str, reg_addr_idx); } else printk("%s reg cat %d is not supported yet!\n", sdr_compatible_str, reg_cat); @@ -1606,30 +1658,39 @@ static int openwifi_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif * else if (reg_cat==6) tmp = xpu_api->reg_read(reg_addr); else if (reg_cat==7) { - if (reg_addr_idx==1) { - priv->rx_freq_offset_to_lo_MHz = rx_intf_fo_mapping[priv->rx_intf_cfg]; - //priv->tx_freq_offset_to_lo_MHz = tx_intf_fo_mapping[priv->tx_intf_cfg]; + if (reg_addr_idx>=0 && reg_addr_idxrx_freq_offset_to_lo_MHz = rx_intf_fo_mapping[priv->rx_intf_cfg]; + //priv->tx_freq_offset_to_lo_MHz = tx_intf_fo_mapping[priv->tx_intf_cfg]; - if (priv->rx_intf_cfg == RX_INTF_BW_20MHZ_AT_0MHZ_ANT0) - priv->drv_rx_reg_val[reg_addr_idx]=0; - else if (priv->rx_intf_cfg == RX_INTF_BW_20MHZ_AT_0MHZ_ANT1) - priv->drv_rx_reg_val[reg_addr_idx]=1; - } - tmp = priv->drv_rx_reg_val[reg_addr_idx]; + if (priv->rx_intf_cfg == RX_INTF_BW_20MHZ_AT_0MHZ_ANT0) + priv->drv_rx_reg_val[reg_addr_idx]=0; + else if (priv->rx_intf_cfg == RX_INTF_BW_20MHZ_AT_0MHZ_ANT1) + priv->drv_rx_reg_val[reg_addr_idx]=1; + } + tmp = priv->drv_rx_reg_val[reg_addr_idx]; + } else + printk("%s reg_addr_idx %d is out of range!\n", sdr_compatible_str, reg_addr_idx); } else if (reg_cat==8) { - if (reg_addr_idx==1) { - //priv->rx_freq_offset_to_lo_MHz = rx_intf_fo_mapping[priv->rx_intf_cfg]; - priv->tx_freq_offset_to_lo_MHz = tx_intf_fo_mapping[priv->tx_intf_cfg]; - if (priv->tx_intf_cfg == TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT0) - priv->drv_tx_reg_val[reg_addr_idx]=0; - else if (priv->tx_intf_cfg == TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT1) - priv->drv_tx_reg_val[reg_addr_idx]=1; - } - tmp = priv->drv_tx_reg_val[reg_addr_idx]; + if (reg_addr_idx>=0 && reg_addr_idxrx_freq_offset_to_lo_MHz = rx_intf_fo_mapping[priv->rx_intf_cfg]; + priv->tx_freq_offset_to_lo_MHz = tx_intf_fo_mapping[priv->tx_intf_cfg]; + if (priv->tx_intf_cfg == TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT0) + priv->drv_tx_reg_val[reg_addr_idx]=0; + else if (priv->tx_intf_cfg == TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT1) + priv->drv_tx_reg_val[reg_addr_idx]=1; + } + tmp = priv->drv_tx_reg_val[reg_addr_idx]; + } else + printk("%s reg_addr_idx %d is out of range!\n", sdr_compatible_str, reg_addr_idx); } else if (reg_cat==9) { - tmp = priv->drv_xpu_reg_val[reg_addr_idx]; + if (reg_addr_idx>=0 && reg_addr_idxdrv_xpu_reg_val[reg_addr_idx]; + else + printk("%s reg_addr_idx %d is out of range!\n", sdr_compatible_str, reg_addr_idx); } else printk("%s reg cat %d is not supported yet!\n", sdr_compatible_str, reg_cat); @@ -1960,7 +2021,8 @@ static int openwifi_dev_probe(struct platform_device *pdev) * with mac80211, however the beacon queue is an exception and it * is mapped on the highst tx ring IDX. */ - dev->queues = 1; + dev->queues = MAX_NUM_HW_QUEUE; + //dev->queues = 1; ieee80211_hw_set(dev, SIGNAL_DBM); @@ -1969,6 +2031,9 @@ static int openwifi_dev_probe(struct platform_device *pdev) priv->rf = &ad9361_rf_ops; memset(priv->dest_mac_addr_queue_map,0,sizeof(priv->dest_mac_addr_queue_map)); + priv->slice_idx = 0xFFFFFFFF; + + sg_init_table(&(priv->tx_sg), 1); get_random_bytes(&rand_val, sizeof(rand_val)); rand_val%=250; diff --git a/driver/sdr.h b/driver/sdr.h index fa9abb1..9adbe70 100644 --- a/driver/sdr.h +++ b/driver/sdr.h @@ -26,21 +26,23 @@ struct openwifi_rf_ops { }; struct openwifi_buffer_descriptor { - u32 num_dma_byte; - u32 sn; - u32 hw_queue_idx; - u32 retry_limit; - u32 need_ack; + // u32 num_dma_byte; + // u32 sn; + // u32 hw_queue_idx; + // u32 retry_limit; + // u32 need_ack; struct sk_buff *skb_linked; dma_addr_t dma_mapping_addr; - u32 reserved; + // u32 reserved; } __packed; struct openwifi_ring { struct openwifi_buffer_descriptor *bds; u32 bd_wr_idx; u32 bd_rd_idx; - u32 reserved; + u32 stop_flag; // track the stop/wake status between tx interrupt and openwifi_tx + // u32 num_dma_symbol_request; + // u32 reserved; } __packed; struct openwifi_vif { @@ -62,24 +64,35 @@ union u16_byte2 { u8 c[2]; }; -#define MAX_NUM_DRV_REG 32 #define MAX_NUM_LED 4 #define OPENWIFI_LED_MAX_NAME_LEN 32 +// ------------ software reg definition ------------ +#define MAX_NUM_DRV_REG 8 +#define DRV_TX_REG_IDX_RATE 0 +#define DRV_TX_REG_IDX_FREQ_BW_CFG 1 +#define DRV_TX_REG_IDX_PRINT_CFG (MAX_NUM_DRV_REG-1) + +#define DRV_RX_REG_IDX_FREQ_BW_CFG 1 +#define DRV_RX_REG_IDX_PRINT_CFG (MAX_NUM_DRV_REG-1) + +// ------end of software reg definition ------------ + #define MAX_NUM_VIF 4 #define LEN_PHY_HEADER 16 #define LEN_PHY_CRC 4 #define RING_ROOM_THRESHOLD 4 -#define NUM_TX_BD 32 +#define NUM_TX_BD 64 // !!! should align to the fifo size in tx_bit_intf.v #define NUM_RX_BD 16 #define TX_BD_BUF_SIZE (8192) #define RX_BD_BUF_SIZE (8192) #define NUM_BIT_MAX_NUM_HW_QUEUE 2 -#define MAX_NUM_HW_QUEUE 2 -#define NUM_BIT_MAX_PHY_TX_SN 12 +#define MAX_NUM_HW_QUEUE 4 // number of queue in FPGA +#define MAX_NUM_SW_QUEUE 4 // number of queue in Linux, depends on the number we report by dev->queues in openwifi_dev_probe +#define NUM_BIT_MAX_PHY_TX_SN 10 // decrease 12 to 10 to reserve 2 bits storing related linux prio idx #define MAX_PHY_TX_SN ((1<TX_INTF_REG_MULTI_RST_write(0); + for (i=0;i<32;i++) tx_intf_api->TX_INTF_REG_MULTI_RST_write(0xFFFFFFFF); - tx_intf_api->TX_INTF_REG_MULTI_RST_write(0); + for (i=0;i<8;i++) + tx_intf_api->TX_INTF_REG_MULTI_RST_write(0); + tx_intf_api->TX_INTF_REG_S_AXIS_FIFO_TH_write(4096-200); // when only 200 DMA symbol room left in fifo, stop Linux queue switch(mode) { case TX_INTF_AXIS_LOOP_BACK: @@ -271,8 +283,8 @@ static inline u32 hw_init(enum tx_intf_mode mode, u32 num_dma_symbol_to_pl, u32 tx_intf_api->TX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write(num_dma_symbol_to_ps); tx_intf_api->TX_INTF_REG_CFG_DATA_TO_ANT_write(0); tx_intf_api->TX_INTF_REG_TX_HOLD_THRESHOLD_write(420); - tx_intf_api->TX_INTF_REG_INTERRUPT_SEL_write(0x40); //.src_sel0(slv_reg14[2:0]), .src_sel1(slv_reg14[6:4]), 0-s00_axis_tlast,1-ap_start,2-tx_start_from_acc,3-tx_end_from_acc,4-xpu signal - tx_intf_api->TX_INTF_REG_INTERRUPT_SEL_write(0x30040); //disable interrupt + tx_intf_api->TX_INTF_REG_INTERRUPT_SEL_write(0x4F); //.src_sel0(slv_reg14[2:0]), .src_sel1(slv_reg14[6:4]), 0-s00_axis_tlast,1-ap_start,2-tx_start_from_acc,3-tx_end_from_acc,4-xpu signal + tx_intf_api->TX_INTF_REG_INTERRUPT_SEL_write(0x3004F); //disable interrupt tx_intf_api->TX_INTF_REG_BB_GAIN_write(100); tx_intf_api->TX_INTF_REG_ANT_SEL_write(ant_sel); tx_intf_api->TX_INTF_REG_WIFI_TX_MODE_write((1<<3)|(2<<4)); @@ -325,11 +337,12 @@ static int dev_probe(struct platform_device *pdev) tx_intf_api->TX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_read=TX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_read; tx_intf_api->TX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_read=TX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_read; tx_intf_api->TX_INTF_REG_CFG_DATA_TO_ANT_read=TX_INTF_REG_CFG_DATA_TO_ANT_read; + tx_intf_api->TX_INTF_REG_S_AXIS_FIFO_TH_read=TX_INTF_REG_S_AXIS_FIFO_TH_read; tx_intf_api->TX_INTF_REG_TX_HOLD_THRESHOLD_read=TX_INTF_REG_TX_HOLD_THRESHOLD_read; tx_intf_api->TX_INTF_REG_INTERRUPT_SEL_read=TX_INTF_REG_INTERRUPT_SEL_read; tx_intf_api->TX_INTF_REG_BB_GAIN_read=TX_INTF_REG_BB_GAIN_read; tx_intf_api->TX_INTF_REG_ANT_SEL_read=TX_INTF_REG_ANT_SEL_read; - tx_intf_api->TX_INTF_REG_S_AXIS_FIFO_DATA_COUNT_read=TX_INTF_REG_S_AXIS_FIFO_DATA_COUNT_read; + tx_intf_api->TX_INTF_REG_S_AXIS_FIFO_NO_ROOM_read=TX_INTF_REG_S_AXIS_FIFO_NO_ROOM_read; tx_intf_api->TX_INTF_REG_PKT_INFO_read=TX_INTF_REG_PKT_INFO_read; tx_intf_api->TX_INTF_REG_QUEUE_FIFO_DATA_COUNT_read=TX_INTF_REG_QUEUE_FIFO_DATA_COUNT_read; @@ -344,11 +357,12 @@ static int dev_probe(struct platform_device *pdev) tx_intf_api->TX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write=TX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write; tx_intf_api->TX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write=TX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write; tx_intf_api->TX_INTF_REG_CFG_DATA_TO_ANT_write=TX_INTF_REG_CFG_DATA_TO_ANT_write; + tx_intf_api->TX_INTF_REG_S_AXIS_FIFO_TH_write=TX_INTF_REG_S_AXIS_FIFO_TH_write; tx_intf_api->TX_INTF_REG_TX_HOLD_THRESHOLD_write=TX_INTF_REG_TX_HOLD_THRESHOLD_write; tx_intf_api->TX_INTF_REG_INTERRUPT_SEL_write=TX_INTF_REG_INTERRUPT_SEL_write; tx_intf_api->TX_INTF_REG_BB_GAIN_write=TX_INTF_REG_BB_GAIN_write; tx_intf_api->TX_INTF_REG_ANT_SEL_write=TX_INTF_REG_ANT_SEL_write; - tx_intf_api->TX_INTF_REG_S_AXIS_FIFO_DATA_COUNT_write=TX_INTF_REG_S_AXIS_FIFO_DATA_COUNT_write; + tx_intf_api->TX_INTF_REG_S_AXIS_FIFO_NO_ROOM_write=TX_INTF_REG_S_AXIS_FIFO_NO_ROOM_write; tx_intf_api->TX_INTF_REG_PKT_INFO_write=TX_INTF_REG_PKT_INFO_write; /* Request and map I/O memory */ diff --git a/driver/xpu/xpu.c b/driver/xpu/xpu.c index 8f7d893..1eb53ed 100644 --- a/driver/xpu/xpu.c +++ b/driver/xpu/xpu.c @@ -222,44 +222,28 @@ static inline u32 XPU_REG_CSMA_CFG_read(void){ return reg_read(XPU_REG_CSMA_CFG_ADDR); } -static inline void XPU_REG_SLICE_COUNT_TOTAL0_write(u32 value){ - reg_write(XPU_REG_SLICE_COUNT_TOTAL0_ADDR, value); +static inline void XPU_REG_SLICE_COUNT_TOTAL_write(u32 value){ + reg_write(XPU_REG_SLICE_COUNT_TOTAL_ADDR, value); } -static inline void XPU_REG_SLICE_COUNT_START0_write(u32 value){ - reg_write(XPU_REG_SLICE_COUNT_START0_ADDR, value); +static inline void XPU_REG_SLICE_COUNT_START_write(u32 value){ + reg_write(XPU_REG_SLICE_COUNT_START_ADDR, value); } -static inline void XPU_REG_SLICE_COUNT_END0_write(u32 value){ - reg_write(XPU_REG_SLICE_COUNT_END0_ADDR, value); -} -static inline void XPU_REG_SLICE_COUNT_TOTAL1_write(u32 value){ - reg_write(XPU_REG_SLICE_COUNT_TOTAL1_ADDR, value); -} -static inline void XPU_REG_SLICE_COUNT_START1_write(u32 value){ - reg_write(XPU_REG_SLICE_COUNT_START1_ADDR, value); -} -static inline void XPU_REG_SLICE_COUNT_END1_write(u32 value){ - reg_write(XPU_REG_SLICE_COUNT_END1_ADDR, value); +static inline void XPU_REG_SLICE_COUNT_END_write(u32 value){ + reg_write(XPU_REG_SLICE_COUNT_END_ADDR, value); } -static inline u32 XPU_REG_SLICE_COUNT_TOTAL0_read(void){ - return reg_read(XPU_REG_SLICE_COUNT_TOTAL0_ADDR); + +static inline u32 XPU_REG_SLICE_COUNT_TOTAL_read(void){ + return reg_read(XPU_REG_SLICE_COUNT_TOTAL_ADDR); } -static inline u32 XPU_REG_SLICE_COUNT_START0_read(void){ - return reg_read(XPU_REG_SLICE_COUNT_START0_ADDR); +static inline u32 XPU_REG_SLICE_COUNT_START_read(void){ + return reg_read(XPU_REG_SLICE_COUNT_START_ADDR); } -static inline u32 XPU_REG_SLICE_COUNT_END0_read(void){ - return reg_read(XPU_REG_SLICE_COUNT_END0_ADDR); -} -static inline u32 XPU_REG_SLICE_COUNT_TOTAL1_read(void){ - return reg_read(XPU_REG_SLICE_COUNT_TOTAL1_ADDR); -} -static inline u32 XPU_REG_SLICE_COUNT_START1_read(void){ - return reg_read(XPU_REG_SLICE_COUNT_START1_ADDR); -} -static inline u32 XPU_REG_SLICE_COUNT_END1_read(void){ - return reg_read(XPU_REG_SLICE_COUNT_END1_ADDR); +static inline u32 XPU_REG_SLICE_COUNT_END_read(void){ + return reg_read(XPU_REG_SLICE_COUNT_END_ADDR); } + static inline void XPU_REG_BB_RF_DELAY_write(u32 value){ reg_write(XPU_REG_BB_RF_DELAY_ADDR, value); } @@ -291,16 +275,18 @@ static struct xpu_driver_api *xpu_api = &xpu_driver_api_inst; EXPORT_SYMBOL(xpu_api); static inline u32 hw_init(enum xpu_mode mode){ - int err=0, rssi_half_db_th, rssi_half_db_offset, agc_gain_delay; - u32 reg_val; + int err=0, i, rssi_half_db_th, rssi_half_db_offset, agc_gain_delay; u32 filter_flag = 0; printk("%s hw_init mode %d\n", xpu_compatible_str, mode); - //rst internal module - for (reg_val=0;reg_val<32;reg_val++) + //rst + for (i=0;i<8;i++) + xpu_api->XPU_REG_MULTI_RST_write(0); + for (i=0;i<32;i++) xpu_api->XPU_REG_MULTI_RST_write(0xFFFFFFFF); - xpu_api->XPU_REG_MULTI_RST_write(0); + for (i=0;i<8;i++) + xpu_api->XPU_REG_MULTI_RST_write(0); // http://www.studioreti.it/slide/802-11-Frame_E_C.pdf // https://mrncciew.com/2014/10/14/cwap-802-11-phy-ppdu/ @@ -339,9 +325,6 @@ static inline u32 hw_init(enum xpu_mode mode){ xpu_api->XPU_REG_FILTER_FLAG_write(filter_flag); xpu_api->XPU_REG_CTS_TO_RTS_CONFIG_write(0xB<<16);//6M 1011:0xB - ////set up FC type filter for packet needs ACK -- no use, FPGA handle by itself - //xpu_api->XPU_REG_ACK_FC_FILTER_write((3<<(2+16))|(2<<2)); // low 16 bits target FC 16 bits; high 16 bits -- mask - // after send data frame wait for ACK, this will be set in real time in function ad9361_rf_set_channel // xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_write( (((51+2)*10)<<16) | 10 ); // high 16 bits to cover sig valid of ACK packet, low 16 bits is adjustment of fcs valid waiting time. let's add 2us for those device that is really "slow"! // xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( 6*10 ); // +6 = 16us for 5GHz @@ -350,13 +333,36 @@ static inline u32 hw_init(enum xpu_mode mode){ xpu_api->XPU_REG_BB_RF_DELAY_write(49); - xpu_api->XPU_REG_SLICE_COUNT_TOTAL0_write(50000-1); // total 50ms - xpu_api->XPU_REG_SLICE_COUNT_START0_write(0); //start 0ms - xpu_api->XPU_REG_SLICE_COUNT_END0_write(50000-1); //end 10ms - xpu_api->XPU_REG_SLICE_COUNT_TOTAL1_write(50000-1); // total 50ms - xpu_api->XPU_REG_SLICE_COUNT_START1_write(0000); //start 0ms - xpu_api->XPU_REG_SLICE_COUNT_END1_write(1000-1); //end 1ms + // setup time schedule of 4 slices + // slice 0 + xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write(50000-1); // total 50ms + xpu_api->XPU_REG_SLICE_COUNT_START_write(0); //start 0ms + xpu_api->XPU_REG_SLICE_COUNT_END_write(50000-1); //end 50ms + // slice 1 + xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((1<<20)|(50000-1)); // total 50ms + xpu_api->XPU_REG_SLICE_COUNT_START_write((1<<20)|(0)); //start 0ms + //xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(20000-1)); //end 20ms + xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(50000-1)); //end 20ms + + // slice 2 + xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((2<<20)|(50000-1)); // total 50ms + //xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(20000)); //start 20ms + xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(0)); //start 20ms + //xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(40000-1)); //end 20ms + xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(50000-1)); //end 20ms + + // slice 3 + xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((3<<20)|(50000-1)); // total 50ms + //xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(40000)); //start 40ms + xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(0)); //start 40ms + //xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms + xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms + + // all slice sync rest + xpu_api->XPU_REG_MULTI_RST_write(1<<7); //bit7 reset the counter for all queues at the same time + xpu_api->XPU_REG_MULTI_RST_write(0<<7); + switch(mode) { case XPU_TEST: @@ -388,7 +394,6 @@ static inline u32 hw_init(enum xpu_mode mode){ //xpu_api->XPU_REG_CSMA_CFG_write(3); //normal CSMA xpu_api->XPU_REG_CSMA_CFG_write(0xe0000000); //high priority - // xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( ((40)<<16)|0 );//high 16bit 5GHz; low 16 bit 2.4GHz (Attention, current tx core has around 1.19us starting delay that makes the ack fall behind 10us SIFS in 2.4GHz! Need to improve TX in 2.4GHz!) xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( ((51)<<16)|0 );//now our tx send out I/Q immediately xpu_api->XPU_REG_RECV_ACK_COUNT_TOP0_write( (((45+2+2)*10 + 15)<<16) | 10 );//2.4GHz. extra 300 clocks are needed when rx core fall into fake ht detection phase (rx mcs 6M) @@ -480,19 +485,13 @@ static int dev_probe(struct platform_device *pdev) xpu_api->XPU_REG_CSMA_CFG_write=XPU_REG_CSMA_CFG_write; xpu_api->XPU_REG_CSMA_CFG_read=XPU_REG_CSMA_CFG_read; - xpu_api->XPU_REG_SLICE_COUNT_TOTAL0_write=XPU_REG_SLICE_COUNT_TOTAL0_write; - xpu_api->XPU_REG_SLICE_COUNT_START0_write=XPU_REG_SLICE_COUNT_START0_write; - xpu_api->XPU_REG_SLICE_COUNT_END0_write=XPU_REG_SLICE_COUNT_END0_write; - xpu_api->XPU_REG_SLICE_COUNT_TOTAL1_write=XPU_REG_SLICE_COUNT_TOTAL1_write; - xpu_api->XPU_REG_SLICE_COUNT_START1_write=XPU_REG_SLICE_COUNT_START1_write; - xpu_api->XPU_REG_SLICE_COUNT_END1_write=XPU_REG_SLICE_COUNT_END1_write; + xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write=XPU_REG_SLICE_COUNT_TOTAL_write; + xpu_api->XPU_REG_SLICE_COUNT_START_write=XPU_REG_SLICE_COUNT_START_write; + xpu_api->XPU_REG_SLICE_COUNT_END_write=XPU_REG_SLICE_COUNT_END_write; - xpu_api->XPU_REG_SLICE_COUNT_TOTAL0_read=XPU_REG_SLICE_COUNT_TOTAL0_read; - xpu_api->XPU_REG_SLICE_COUNT_START0_read=XPU_REG_SLICE_COUNT_START0_read; - xpu_api->XPU_REG_SLICE_COUNT_END0_read=XPU_REG_SLICE_COUNT_END0_read; - xpu_api->XPU_REG_SLICE_COUNT_TOTAL1_read=XPU_REG_SLICE_COUNT_TOTAL1_read; - xpu_api->XPU_REG_SLICE_COUNT_START1_read=XPU_REG_SLICE_COUNT_START1_read; - xpu_api->XPU_REG_SLICE_COUNT_END1_read=XPU_REG_SLICE_COUNT_END1_read; + xpu_api->XPU_REG_SLICE_COUNT_TOTAL_read=XPU_REG_SLICE_COUNT_TOTAL_read; + xpu_api->XPU_REG_SLICE_COUNT_START_read=XPU_REG_SLICE_COUNT_START_read; + xpu_api->XPU_REG_SLICE_COUNT_END_read=XPU_REG_SLICE_COUNT_END_read; xpu_api->XPU_REG_BB_RF_DELAY_write=XPU_REG_BB_RF_DELAY_write; xpu_api->XPU_REG_MAX_NUM_RETRANS_write=XPU_REG_MAX_NUM_RETRANS_write; diff --git a/user_space/sdrctl_src/cmd.c b/user_space/sdrctl_src/cmd.c index 287e42c..7398e95 100644 --- a/user_space/sdrctl_src/cmd.c +++ b/user_space/sdrctl_src/cmd.c @@ -305,11 +305,12 @@ static int handle_get_rssi_th(struct nl80211_state *state, } COMMAND(get, rssi_th, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_rssi_th, "get rssi_th"); -static int cb_openwifi_slice_total0_handler(struct nl_msg *msg, void *arg) +static int cb_openwifi_slice_total_handler(struct nl_msg *msg, void *arg) { struct nlattr *attrs[NL80211_ATTR_MAX + 1]; struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + unsigned int tmp; nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); @@ -318,12 +319,13 @@ static int cb_openwifi_slice_total0_handler(struct nl_msg *msg, void *arg) nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); - printf("openwifi slice_total0 (duration): %dus\n", nla_get_u32(tb[OPENWIFI_ATTR_SLICE_TOTAL0])); + tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_TOTAL]); + printf("openwifi slice_total (duration) %dus of slice %d\n", tmp&0xFFFFF, tmp>>20); return NL_SKIP; } -static int handle_set_slice_total0(struct nl80211_state *state, +static int handle_set_slice_total(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, @@ -344,21 +346,21 @@ static int handle_set_slice_total0(struct nl80211_state *state, return 1; } - NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_TOTAL0); - NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_TOTAL0, tmp); + NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_TOTAL); + NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_TOTAL, tmp); nla_nest_end(msg, tmdata); - printf("openwifi slice_total0 (duration): %dus\n", tmp); + printf("openwifi slice_total (duration): %dus\n", tmp); return 0; nla_put_failure: return -ENOBUFS; } -COMMAND(set, slice_total0, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_total0, "set slice_total0"); +COMMAND(set, slice_total, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_total, "set slice_total"); -static int handle_get_slice_total0(struct nl80211_state *state, +static int handle_get_slice_total(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, @@ -370,24 +372,102 @@ static int handle_get_slice_total0(struct nl80211_state *state, if (!tmdata) return 1; - NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_TOTAL0); + NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_TOTAL); nla_nest_end(msg, tmdata); - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_total0_handler, NULL); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_total_handler, NULL); return 0; nla_put_failure: return -ENOBUFS; } -COMMAND(get, slice_total0, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_total0, "get slice_total0"); +COMMAND(get, slice_total, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_total, "get slice_total"); -static int cb_openwifi_slice_total1_handler(struct nl_msg *msg, void *arg) +// static int cb_openwifi_slice_total1_handler(struct nl_msg *msg, void *arg) +// { +// struct nlattr *attrs[NL80211_ATTR_MAX + 1]; +// struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; +// struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + +// nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); + +// if (!attrs[NL80211_ATTR_TESTDATA]) +// return NL_SKIP; + +// nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); + +// printf("openwifi slice_total1 (duration): %dus\n", nla_get_u32(tb[OPENWIFI_ATTR_SLICE_TOTAL1])); + +// return NL_SKIP; +// } + +// static int handle_set_slice_total1(struct nl80211_state *state, +// struct nl_cb *cb, +// struct nl_msg *msg, +// int argc, char **argv, +// enum id_input id) +// { +// struct nlattr *tmdata; +// char *end; +// unsigned int tmp; + +// tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); +// if (!tmdata) { +// return 1; +// } + +// tmp = strtoul(argv[0], &end, 10); + +// if (*end) { +// return 1; +// } + +// NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_TOTAL1); +// NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_TOTAL1, tmp); + +// nla_nest_end(msg, tmdata); + +// printf("openwifi slice_total1 (duration): %dus\n", tmp); + +// return 0; + +// nla_put_failure: +// return -ENOBUFS; +// } +// COMMAND(set, slice_total1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_total1, "set slice_total1"); + +// static int handle_get_slice_total1(struct nl80211_state *state, +// struct nl_cb *cb, +// struct nl_msg *msg, +// int argc, char **argv, +// enum id_input id) +// { +// struct nlattr *tmdata; + +// tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); +// if (!tmdata) +// return 1; + +// NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_TOTAL1); + +// nla_nest_end(msg, tmdata); + +// nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_total1_handler, NULL); +// return 0; + +// nla_put_failure: +// return -ENOBUFS; +// } +// COMMAND(get, slice_total1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_total1, "get slice_total1"); + +static int cb_openwifi_slice_start_handler(struct nl_msg *msg, void *arg) { struct nlattr *attrs[NL80211_ATTR_MAX + 1]; struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + unsigned int tmp; nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); @@ -396,12 +476,13 @@ static int cb_openwifi_slice_total1_handler(struct nl_msg *msg, void *arg) nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); - printf("openwifi slice_total1 (duration): %dus\n", nla_get_u32(tb[OPENWIFI_ATTR_SLICE_TOTAL1])); + tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_START]); + printf("openwifi slice_start (duration) %dus of slice %d\n", tmp&0xFFFFF, tmp>>20); return NL_SKIP; } -static int handle_set_slice_total1(struct nl80211_state *state, +static int handle_set_slice_start(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, @@ -422,21 +503,21 @@ static int handle_set_slice_total1(struct nl80211_state *state, return 1; } - NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_TOTAL1); - NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_TOTAL1, tmp); + NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_START); + NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_START, tmp); nla_nest_end(msg, tmdata); - printf("openwifi slice_total1 (duration): %dus\n", tmp); + printf("openwifi slice_start (duration): %dus\n", tmp); return 0; nla_put_failure: return -ENOBUFS; } -COMMAND(set, slice_total1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_total1, "set slice_total1"); +COMMAND(set, slice_start, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_start, "set slice_start"); -static int handle_get_slice_total1(struct nl80211_state *state, +static int handle_get_slice_start(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, @@ -448,24 +529,103 @@ static int handle_get_slice_total1(struct nl80211_state *state, if (!tmdata) return 1; - NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_TOTAL1); + NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_START); nla_nest_end(msg, tmdata); - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_total1_handler, NULL); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_start_handler, NULL); return 0; nla_put_failure: return -ENOBUFS; } -COMMAND(get, slice_total1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_total1, "get slice_total1"); +COMMAND(get, slice_start, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_start, "get slice_start"); -static int cb_openwifi_slice_start0_handler(struct nl_msg *msg, void *arg) +// static int cb_openwifi_slice_start1_handler(struct nl_msg *msg, void *arg) +// { +// struct nlattr *attrs[NL80211_ATTR_MAX + 1]; +// struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; +// struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + +// nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); + +// if (!attrs[NL80211_ATTR_TESTDATA]) +// return NL_SKIP; + +// nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); + +// printf("openwifi slice_start1 (duration): %dus\n", nla_get_u32(tb[OPENWIFI_ATTR_SLICE_START1])); + +// return NL_SKIP; +// } + +// static int handle_set_slice_start1(struct nl80211_state *state, +// struct nl_cb *cb, +// struct nl_msg *msg, +// int argc, char **argv, +// enum id_input id) +// { +// struct nlattr *tmdata; +// char *end; +// unsigned int tmp; + +// tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); +// if (!tmdata) { +// return 1; +// } + +// tmp = strtoul(argv[0], &end, 10); + +// if (*end) { +// return 1; +// } + +// NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_START1); +// NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_START1, tmp); + +// nla_nest_end(msg, tmdata); + +// printf("openwifi slice_start1 (duration): %dus\n", tmp); + +// return 0; + +// nla_put_failure: +// return -ENOBUFS; +// } +// COMMAND(set, slice_start1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_start1, "set slice_start1"); + +// static int handle_get_slice_start1(struct nl80211_state *state, +// struct nl_cb *cb, +// struct nl_msg *msg, +// int argc, char **argv, +// enum id_input id) +// { +// struct nlattr *tmdata; + +// tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); +// if (!tmdata) +// return 1; + +// NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_START1); + +// nla_nest_end(msg, tmdata); + +// nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_start1_handler, NULL); +// return 0; + +// nla_put_failure: +// return -ENOBUFS; +// } +// COMMAND(get, slice_start1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_start1, "get slice_start1"); + + +static int cb_openwifi_slice_end_handler(struct nl_msg *msg, void *arg) { struct nlattr *attrs[NL80211_ATTR_MAX + 1]; struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + unsigned int tmp; nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); @@ -474,12 +634,13 @@ static int cb_openwifi_slice_start0_handler(struct nl_msg *msg, void *arg) nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); - printf("openwifi slice_start0 (duration): %dus\n", nla_get_u32(tb[OPENWIFI_ATTR_SLICE_START0])); + tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_END]); + printf("openwifi slice_end (duration) %dus of slice %d\n", tmp&0xFFFFF, tmp>>20); return NL_SKIP; } -static int handle_set_slice_start0(struct nl80211_state *state, +static int handle_set_slice_end(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, @@ -500,21 +661,21 @@ static int handle_set_slice_start0(struct nl80211_state *state, return 1; } - NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_START0); - NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_START0, tmp); + NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_END); + NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_END, tmp); nla_nest_end(msg, tmdata); - printf("openwifi slice_start0 (duration): %dus\n", tmp); + printf("openwifi slice_end (duration): %dus\n", tmp); return 0; nla_put_failure: return -ENOBUFS; } -COMMAND(set, slice_start0, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_start0, "set slice_start0"); +COMMAND(set, slice_end, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_end, "set slice_end"); -static int handle_get_slice_start0(struct nl80211_state *state, +static int handle_get_slice_end(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, @@ -526,20 +687,98 @@ static int handle_get_slice_start0(struct nl80211_state *state, if (!tmdata) return 1; - NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_START0); + NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_END); nla_nest_end(msg, tmdata); - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_start0_handler, NULL); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_end_handler, NULL); return 0; nla_put_failure: return -ENOBUFS; } -COMMAND(get, slice_start0, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_start0, "get slice_start0"); +COMMAND(get, slice_end, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_end, "get slice_end"); -static int cb_openwifi_slice_start1_handler(struct nl_msg *msg, void *arg) +// static int cb_openwifi_slice_end1_handler(struct nl_msg *msg, void *arg) +// { +// struct nlattr *attrs[NL80211_ATTR_MAX + 1]; +// struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; +// struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + +// nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); + +// if (!attrs[NL80211_ATTR_TESTDATA]) +// return NL_SKIP; + +// nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); + +// printf("openwifi slice_end1 (duration): %dus\n", nla_get_u32(tb[OPENWIFI_ATTR_SLICE_END1])); + +// return NL_SKIP; +// } + +// static int handle_set_slice_end1(struct nl80211_state *state, +// struct nl_cb *cb, +// struct nl_msg *msg, +// int argc, char **argv, +// enum id_input id) +// { +// struct nlattr *tmdata; +// char *end; +// unsigned int tmp; + +// tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); +// if (!tmdata) { +// return 1; +// } + +// tmp = strtoul(argv[0], &end, 10); + +// if (*end) { +// return 1; +// } + +// NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_END1); +// NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_END1, tmp); + +// nla_nest_end(msg, tmdata); + +// printf("openwifi slice_end1 (duration): %dus\n", tmp); + +// return 0; + +// nla_put_failure: +// return -ENOBUFS; +// } +// COMMAND(set, slice_end1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_end1, "set slice_end1"); + +// static int handle_get_slice_end1(struct nl80211_state *state, +// struct nl_cb *cb, +// struct nl_msg *msg, +// int argc, char **argv, +// enum id_input id) +// { +// struct nlattr *tmdata; + +// tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); +// if (!tmdata) +// return 1; + +// NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_END1); + +// nla_nest_end(msg, tmdata); + +// nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_end1_handler, NULL); +// return 0; + +// nla_put_failure: +// return -ENOBUFS; +// } +// COMMAND(get, slice_end1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_end1, "get slice_end1"); + + +static int cb_openwifi_slice_idx_handler(struct nl_msg *msg, void *arg) { struct nlattr *attrs[NL80211_ATTR_MAX + 1]; struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; @@ -552,12 +791,12 @@ static int cb_openwifi_slice_start1_handler(struct nl_msg *msg, void *arg) nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); - printf("openwifi slice_start1 (duration): %dus\n", nla_get_u32(tb[OPENWIFI_ATTR_SLICE_START1])); + printf("openwifi slice_idx in hex: %08x\n", nla_get_u32(tb[OPENWIFI_ATTR_SLICE_IDX])); return NL_SKIP; } -static int handle_set_slice_start1(struct nl80211_state *state, +static int handle_set_slice_idx(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, @@ -565,272 +804,38 @@ static int handle_set_slice_start1(struct nl80211_state *state, { struct nlattr *tmdata; char *end; - unsigned int tmp; + unsigned int slice_idx; - tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); - if (!tmdata) { - return 1; - } - - tmp = strtoul(argv[0], &end, 10); - - if (*end) { - return 1; - } - - NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_START1); - NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_START1, tmp); - - nla_nest_end(msg, tmdata); - - printf("openwifi slice_start1 (duration): %dus\n", tmp); - - return 0; - - nla_put_failure: - return -ENOBUFS; -} -COMMAND(set, slice_start1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_start1, "set slice_start1"); - -static int handle_get_slice_start1(struct nl80211_state *state, - struct nl_cb *cb, - struct nl_msg *msg, - int argc, char **argv, - enum id_input id) -{ - struct nlattr *tmdata; - - tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); - if (!tmdata) - return 1; - - NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_START1); - - nla_nest_end(msg, tmdata); - - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_start1_handler, NULL); - return 0; - - nla_put_failure: - return -ENOBUFS; -} -COMMAND(get, slice_start1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_start1, "get slice_start1"); - - -static int cb_openwifi_slice_end0_handler(struct nl_msg *msg, void *arg) -{ - struct nlattr *attrs[NL80211_ATTR_MAX + 1]; - struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; - struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); - - nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); - - if (!attrs[NL80211_ATTR_TESTDATA]) - return NL_SKIP; - - nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); - - printf("openwifi slice_end0 (duration): %dus\n", nla_get_u32(tb[OPENWIFI_ATTR_SLICE_END0])); - - return NL_SKIP; -} - -static int handle_set_slice_end0(struct nl80211_state *state, - struct nl_cb *cb, - struct nl_msg *msg, - int argc, char **argv, - enum id_input id) -{ - struct nlattr *tmdata; - char *end; - unsigned int tmp; - - tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); - if (!tmdata) { - return 1; - } - - tmp = strtoul(argv[0], &end, 10); - - if (*end) { - return 1; - } - - NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_END0); - NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_END0, tmp); - - nla_nest_end(msg, tmdata); - - printf("openwifi slice_end0 (duration): %dus\n", tmp); - - return 0; - - nla_put_failure: - return -ENOBUFS; -} -COMMAND(set, slice_end0, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_end0, "set slice_end0"); - -static int handle_get_slice_end0(struct nl80211_state *state, - struct nl_cb *cb, - struct nl_msg *msg, - int argc, char **argv, - enum id_input id) -{ - struct nlattr *tmdata; - - tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); - if (!tmdata) - return 1; - - NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_END0); - - nla_nest_end(msg, tmdata); - - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_end0_handler, NULL); - return 0; - - nla_put_failure: - return -ENOBUFS; -} -COMMAND(get, slice_end0, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_end0, "get slice_end0"); - - -static int cb_openwifi_slice_end1_handler(struct nl_msg *msg, void *arg) -{ - struct nlattr *attrs[NL80211_ATTR_MAX + 1]; - struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; - struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); - - nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); - - if (!attrs[NL80211_ATTR_TESTDATA]) - return NL_SKIP; - - nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); - - printf("openwifi slice_end1 (duration): %dus\n", nla_get_u32(tb[OPENWIFI_ATTR_SLICE_END1])); - - return NL_SKIP; -} - -static int handle_set_slice_end1(struct nl80211_state *state, - struct nl_cb *cb, - struct nl_msg *msg, - int argc, char **argv, - enum id_input id) -{ - struct nlattr *tmdata; - char *end; - unsigned int tmp; - - tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); - if (!tmdata) { - return 1; - } - - tmp = strtoul(argv[0], &end, 10); - - if (*end) { - return 1; - } - - NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_END1); - NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_END1, tmp); - - nla_nest_end(msg, tmdata); - - printf("openwifi slice_end1 (duration): %dus\n", tmp); - - return 0; - - nla_put_failure: - return -ENOBUFS; -} -COMMAND(set, slice_end1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_end1, "set slice_end1"); - -static int handle_get_slice_end1(struct nl80211_state *state, - struct nl_cb *cb, - struct nl_msg *msg, - int argc, char **argv, - enum id_input id) -{ - struct nlattr *tmdata; - - tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); - if (!tmdata) - return 1; - - NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_END1); - - nla_nest_end(msg, tmdata); - - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_end1_handler, NULL); - return 0; - - nla_put_failure: - return -ENOBUFS; -} -COMMAND(get, slice_end1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_end1, "get slice_end1"); - - -static int cb_openwifi_slice0_target_mac_addr_handler(struct nl_msg *msg, void *arg) -{ - struct nlattr *attrs[NL80211_ATTR_MAX + 1]; - struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; - struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); - - nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); - - if (!attrs[NL80211_ATTR_TESTDATA]) - return NL_SKIP; - - nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); - - printf("openwifi slice0_target_mac_addr(low32) in hex: %08x\n", nla_get_u32(tb[OPENWIFI_ATTR_ADDR0])); - - return NL_SKIP; -} - -static int handle_set_addr0(struct nl80211_state *state, - struct nl_cb *cb, - struct nl_msg *msg, - int argc, char **argv, - enum id_input id) -{ - struct nlattr *tmdata; - char *end; - unsigned int slice0_target_mac_addr; - - //printf("handle_set_slice0_target_mac_addr\n"); + //printf("handle_set_slice_idx\n"); tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) { - //printf("handle_set_slice0_target_mac_addr 1\n"); + //printf("handle_set_slice_idx 1\n"); return 1; } - slice0_target_mac_addr = strtoul(argv[0], &end, 16); + slice_idx = strtoul(argv[0], &end, 16); if (*end) { - //printf("handle_set_slice0_target_mac_addr 2 %d\n", slice0_target_mac_addr); + //printf("handle_set_slice_idx 2 %d\n", slice_idx); return 1; } - NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_ADDR0); - NLA_PUT_U32(msg, OPENWIFI_ATTR_ADDR0, slice0_target_mac_addr); + NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_IDX); + NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_IDX, slice_idx); nla_nest_end(msg, tmdata); - printf("openwifi slice0_target_mac_addr(low32) in hex: %08x\n", slice0_target_mac_addr); + printf("openwifi slice_idx in hex: %08x\n", slice_idx); return 0; nla_put_failure: return -ENOBUFS; } -COMMAND(set, addr0, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_addr0, "set addr0"); +COMMAND(set, slice_idx, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_idx, "set slice_idx"); -static int handle_get_slice0_target_mac_addr(struct nl80211_state *state, +static int handle_get_slice_idx(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, @@ -842,19 +847,19 @@ static int handle_get_slice0_target_mac_addr(struct nl80211_state *state, if (!tmdata) return 1; - NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_ADDR0); + NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_IDX); nla_nest_end(msg, tmdata); - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice0_target_mac_addr_handler, NULL); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_idx_handler, NULL); return 0; nla_put_failure: return -ENOBUFS; } -COMMAND(get, addr0, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice0_target_mac_addr, "get addr0"); +COMMAND(get, slice_idx, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_idx, "get slice_idx"); -static int cb_openwifi_slice1_target_mac_addr_handler(struct nl_msg *msg, void *arg) +static int cb_openwifi_slice_target_mac_addr_handler(struct nl_msg *msg, void *arg) { struct nlattr *attrs[NL80211_ATTR_MAX + 1]; struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; @@ -867,12 +872,12 @@ static int cb_openwifi_slice1_target_mac_addr_handler(struct nl_msg *msg, void * nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); - printf("openwifi slice1_target_mac_addr(low32) in hex: %08x\n", nla_get_u32(tb[OPENWIFI_ATTR_ADDR1])); + printf("openwifi slice_target_mac_addr(low32) in hex: %08x\n", nla_get_u32(tb[OPENWIFI_ATTR_ADDR])); return NL_SKIP; } -static int handle_set_slice1_target_mac_addr(struct nl80211_state *state, +static int handle_set_slice_target_mac_addr(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, @@ -880,32 +885,32 @@ static int handle_set_slice1_target_mac_addr(struct nl80211_state *state, { struct nlattr *tmdata; char *end; - unsigned int slice1_target_mac_addr; + unsigned int slice_target_mac_addr; tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) return 1; - slice1_target_mac_addr = strtoul(argv[0], &end, 16); + slice_target_mac_addr = strtoul(argv[0], &end, 16); if (*end) return 1; - NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_ADDR1); - NLA_PUT_U32(msg, OPENWIFI_ATTR_ADDR1, slice1_target_mac_addr); + NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_ADDR); + NLA_PUT_U32(msg, OPENWIFI_ATTR_ADDR, slice_target_mac_addr); nla_nest_end(msg, tmdata); - printf("openwifi slice1_target_mac_addr(low32) in hex: %08x\n", slice1_target_mac_addr); + printf("openwifi slice_target_mac_addr(low32) in hex: %08x\n", slice_target_mac_addr); return 0; nla_put_failure: return -ENOBUFS; } -COMMAND(set, addr1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice1_target_mac_addr, "set addr1"); +COMMAND(set, addr, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_target_mac_addr, "set addr"); -static int handle_get_slice1_target_mac_addr(struct nl80211_state *state, +static int handle_get_slice_target_mac_addr(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, @@ -917,17 +922,17 @@ static int handle_get_slice1_target_mac_addr(struct nl80211_state *state, if (!tmdata) return 1; - NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_ADDR1); + NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_ADDR); nla_nest_end(msg, tmdata); - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice1_target_mac_addr_handler, NULL); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_target_mac_addr_handler, NULL); return 0; nla_put_failure: return -ENOBUFS; } -COMMAND(get, addr1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice1_target_mac_addr, "get addr1"); +COMMAND(get, addr, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_target_mac_addr, "get addr"); static int cb_openwifi_gap_handler(struct nl_msg *msg, void *arg) { diff --git a/user_space/sdrctl_src/ieee80211.h b/user_space/sdrctl_src/ieee80211.h deleted file mode 100644 index 8745608..0000000 --- a/user_space/sdrctl_src/ieee80211.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef __IEEE80211 -#define __IEEE80211 - -/* 802.11n HT capability AMPDU settings (for ampdu_params_info) */ -#define IEEE80211_HT_AMPDU_PARM_FACTOR 0x03 -#define IEEE80211_HT_AMPDU_PARM_DENSITY 0x1C - -#define IEEE80211_HT_CAP_SUP_WIDTH_20_40 0x0002 -#define IEEE80211_HT_CAP_SGI_40 0x0040 -#define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 - -#define IEEE80211_HT_MCS_MASK_LEN 10 - -/** - * struct ieee80211_mcs_info - MCS information - * @rx_mask: RX mask - * @rx_highest: highest supported RX rate. If set represents - * the highest supported RX data rate in units of 1 Mbps. - * If this field is 0 this value should not be used to - * consider the highest RX data rate supported. - * @tx_params: TX parameters - */ -struct ieee80211_mcs_info { - __u8 rx_mask[IEEE80211_HT_MCS_MASK_LEN]; - __u16 rx_highest; - __u8 tx_params; - __u8 reserved[3]; -} __attribute__ ((packed)); - - -/** - * struct ieee80211_ht_cap - HT capabilities - * - * This structure is the "HT capabilities element" as - * described in 802.11n D5.0 7.3.2.57 - */ -struct ieee80211_ht_cap { - __u16 cap_info; - __u8 ampdu_params_info; - - /* 16 bytes MCS information */ - struct ieee80211_mcs_info mcs; - - __u16 extended_ht_cap_info; - __u32 tx_BF_cap_info; - __u8 antenna_selection_info; -} __attribute__ ((packed)); - -struct ieee80211_vht_mcs_info { - __u16 rx_vht_mcs; - __u16 rx_highest; - __u16 tx_vht_mcs; - __u16 tx_highest; -} __attribute__ ((packed)); - -struct ieee80211_vht_cap { - __u32 cap_info; - struct ieee80211_vht_mcs_info mcs; -} __attribute__ ((packed)); - -#endif /* __IEEE80211 */ diff --git a/user_space/sdrctl_src/nl80211.h b/user_space/sdrctl_src/nl80211.h index 4b28dc0..51626b4 100644 --- a/user_space/sdrctl_src/nl80211.h +++ b/user_space/sdrctl_src/nl80211.h @@ -10,6 +10,7 @@ * Copyright 2008, 2009 Luis R. Rodriguez * Copyright 2008 Jouni Malinen * Copyright 2008 Colin McCabe + * Copyright 2015-2017 Intel Deutschland GmbH * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -25,10 +26,31 @@ * */ +/* + * This header file defines the userspace API to the wireless stack. Please + * be careful not to break things - i.e. don't move anything around or so + * unless you can demonstrate that it breaks neither API nor ABI. + * + * Additions to the API should be accompanied by actual implementations in + * an upstream driver, so that example implementations exist in case there + * are ever concerns about the precise semantics of the API or changes are + * needed, and to ensure that code for dead (no longer implemented) API + * can actually be identified and removed. + * Nonetheless, semantics should also be documented carefully in this file. + */ + #include #define NL80211_GENL_NAME "nl80211" +#define NL80211_MULTICAST_GROUP_CONFIG "config" +#define NL80211_MULTICAST_GROUP_SCAN "scan" +#define NL80211_MULTICAST_GROUP_REG "regulatory" +#define NL80211_MULTICAST_GROUP_MLME "mlme" +#define NL80211_MULTICAST_GROUP_VENDOR "vendor" +#define NL80211_MULTICAST_GROUP_NAN "nan" +#define NL80211_MULTICAST_GROUP_TESTMODE "testmode" + /** * DOC: Station handling * @@ -150,6 +172,65 @@ * Multiple such rules can be created. */ +/** + * DOC: WPA/WPA2 EAPOL handshake offload + * + * By setting @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK flag drivers + * can indicate they support offloading EAPOL handshakes for WPA/WPA2 + * preshared key authentication. In %NL80211_CMD_CONNECT the preshared + * key should be specified using %NL80211_ATTR_PMK. Drivers supporting + * this offload may reject the %NL80211_CMD_CONNECT when no preshared + * key material is provided, for example when that driver does not + * support setting the temporal keys through %CMD_NEW_KEY. + * + * Similarly @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X flag can be + * set by drivers indicating offload support of the PTK/GTK EAPOL + * handshakes during 802.1X authentication. In order to use the offload + * the %NL80211_CMD_CONNECT should have %NL80211_ATTR_WANT_1X_4WAY_HS + * attribute flag. Drivers supporting this offload may reject the + * %NL80211_CMD_CONNECT when the attribute flag is not present. + * + * For 802.1X the PMK or PMK-R0 are set by providing %NL80211_ATTR_PMK + * using %NL80211_CMD_SET_PMK. For offloaded FT support also + * %NL80211_ATTR_PMKR0_NAME must be provided. + */ + +/** + * DOC: FILS shared key authentication offload + * + * FILS shared key authentication offload can be advertized by drivers by + * setting @NL80211_EXT_FEATURE_FILS_SK_OFFLOAD flag. The drivers that support + * FILS shared key authentication offload should be able to construct the + * authentication and association frames for FILS shared key authentication and + * eventually do a key derivation as per IEEE 802.11ai. The below additional + * parameters should be given to driver in %NL80211_CMD_CONNECT. + * %NL80211_ATTR_FILS_ERP_USERNAME - used to construct keyname_nai + * %NL80211_ATTR_FILS_ERP_REALM - used to construct keyname_nai + * %NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM - used to construct erp message + * %NL80211_ATTR_FILS_ERP_RRK - used to generate the rIK and rMSK + * rIK should be used to generate an authentication tag on the ERP message and + * rMSK should be used to derive a PMKSA. + * rIK, rMSK should be generated and keyname_nai, sequence number should be used + * as specified in IETF RFC 6696. + * + * When FILS shared key authentication is completed, driver needs to provide the + * below additional parameters to userspace. + * %NL80211_ATTR_FILS_KEK - used for key renewal + * %NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM - used in further EAP-RP exchanges + * %NL80211_ATTR_PMKID - used to identify the PMKSA used/generated + * %Nl80211_ATTR_PMK - used to update PMKSA cache in userspace + * The PMKSA can be maintained in userspace persistently so that it can be used + * later after reboots or wifi turn off/on also. + * + * %NL80211_ATTR_FILS_CACHE_ID is the cache identifier advertized by a FILS + * capable AP supporting PMK caching. It specifies the scope within which the + * PMKSAs are cached in an ESS. %NL80211_CMD_SET_PMKSA and + * %NL80211_CMD_DEL_PMKSA are enhanced to allow support for PMKSA caching based + * on FILS cache identifier. Additionally %NL80211_ATTR_PMK is used with + * %NL80211_SET_PMKSA to specify the PMK corresponding to a PMKSA for driver to + * use in a FILS shared key connection with PMKSA caching. + */ + /** * enum nl80211_commands - supported nl80211 commands * @@ -173,8 +254,8 @@ * %NL80211_ATTR_WIPHY and %NL80211_ATTR_WIPHY_NAME. * * @NL80211_CMD_GET_INTERFACE: Request an interface's configuration; - * either a dump request on a %NL80211_ATTR_WIPHY or a specific get - * on an %NL80211_ATTR_IFINDEX is supported. + * either a dump request for all interfaces or a specific get with a + * single %NL80211_ATTR_IFINDEX is supported. * @NL80211_CMD_SET_INTERFACE: Set type of a virtual interface, requires * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_IFTYPE. * @NL80211_CMD_NEW_INTERFACE: Newly created virtual interface or response @@ -227,7 +308,11 @@ * the interface identified by %NL80211_ATTR_IFINDEX. * @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC * or, if no MAC address given, all stations, on the interface identified - * by %NL80211_ATTR_IFINDEX. + * by %NL80211_ATTR_IFINDEX. %NL80211_ATTR_MGMT_SUBTYPE and + * %NL80211_ATTR_REASON_CODE can optionally be used to specify which type + * of disconnection indication should be sent to the station + * (Deauthentication or Disassociation frame and reason code for that + * frame). * * @NL80211_CMD_GET_MPATH: Get mesh path attributes for mesh path to * destination %NL80211_ATTR_MAC on the interface identified by @@ -248,7 +333,18 @@ * %NL80211_ATTR_IFINDEX. * * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set - * regulatory domain. + * regulatory domain. If %NL80211_ATTR_WIPHY is specified and the device + * has a private regulatory domain, it will be returned. Otherwise, the + * global regdomain will be returned. + * A device will have a private regulatory domain if it uses the + * regulatory_hint() API. Even when a private regdomain is used the channel + * information will still be mended according to further hints from + * the regulatory core to help with compliance. A dump version of this API + * is now available which will returns the global regdomain as well as + * all private regdomains of present wiphys (for those that have it). + * If a wiphy is self-managed (%NL80211_ATTR_WIPHY_SELF_MANAGED_REG), then + * its private regdomain is the only valid one for it. The regulatory + * core is not used to help with compliance in this case. * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command * after being queried by the kernel. CRDA replies by sending a regulatory * domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our @@ -286,14 +382,24 @@ * @NL80211_CMD_GET_SCAN: get scan results * @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters * %NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the - * probe requests at CCK rate or not. + * probe requests at CCK rate or not. %NL80211_ATTR_BSSID can be used to + * specify a BSSID to scan for; if not included, the wildcard BSSID will + * be used. * @NL80211_CMD_NEW_SCAN_RESULTS: scan notification (as a reply to * NL80211_CMD_GET_SCAN and on the "scan" multicast group) * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons, * partial scan results may be available * * @NL80211_CMD_START_SCHED_SCAN: start a scheduled scan at certain - * intervals, as specified by %NL80211_ATTR_SCHED_SCAN_INTERVAL. + * intervals and certain number of cycles, as specified by + * %NL80211_ATTR_SCHED_SCAN_PLANS. If %NL80211_ATTR_SCHED_SCAN_PLANS is + * not specified and only %NL80211_ATTR_SCHED_SCAN_INTERVAL is specified, + * scheduled scan will run in an infinite loop with the specified interval. + * These attributes are mutually exculsive, + * i.e. NL80211_ATTR_SCHED_SCAN_INTERVAL must not be passed if + * NL80211_ATTR_SCHED_SCAN_PLANS is defined. + * If for some reason scheduled scan is aborted by the driver, all scan + * plans are canceled (including scan plans that did not start yet). * Like with normal scans, if SSIDs (%NL80211_ATTR_SCAN_SSIDS) * are passed, they are used in the probe requests. For * broadcast, a broadcast SSID must be passed (ie. an empty @@ -302,7 +408,11 @@ * if passed, define which channels should be scanned; if not * passed, all channels allowed for the current regulatory domain * are used. Extra IEs can also be passed from the userspace by - * using the %NL80211_ATTR_IE attribute. + * using the %NL80211_ATTR_IE attribute. The first cycle of the + * scheduled scan can be delayed by %NL80211_ATTR_SCHED_SCAN_DELAY + * is supplied. If the device supports multiple concurrent scheduled + * scans, it will allow such when the caller provides the flag attribute + * %NL80211_ATTR_SCHED_SCAN_MULTI to indicate user-space support for it. * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT if * scheduled scan is not running. The caller may assume that as soon * as the call returns, it is safe to start a new scheduled scan again. @@ -321,10 +431,18 @@ * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to * NL80211_CMD_GET_SURVEY and on the "scan" multicast group) * - * @NL80211_CMD_SET_PMKSA: Add a PMKSA cache entry, using %NL80211_ATTR_MAC - * (for the BSSID) and %NL80211_ATTR_PMKID. + * @NL80211_CMD_SET_PMKSA: Add a PMKSA cache entry using %NL80211_ATTR_MAC + * (for the BSSID), %NL80211_ATTR_PMKID, and optionally %NL80211_ATTR_PMK + * (PMK is used for PTKSA derivation in case of FILS shared key offload) or + * using %NL80211_ATTR_SSID, %NL80211_ATTR_FILS_CACHE_ID, + * %NL80211_ATTR_PMKID, and %NL80211_ATTR_PMK in case of FILS + * authentication where %NL80211_ATTR_FILS_CACHE_ID is the identifier + * advertized by a FILS capable AP identifying the scope of PMKSA in an + * ESS. * @NL80211_CMD_DEL_PMKSA: Delete a PMKSA cache entry, using %NL80211_ATTR_MAC - * (for the BSSID) and %NL80211_ATTR_PMKID. + * (for the BSSID) and %NL80211_ATTR_PMKID or using %NL80211_ATTR_SSID, + * %NL80211_ATTR_FILS_CACHE_ID, and %NL80211_ATTR_PMKID in case of FILS + * authentication. * @NL80211_CMD_FLUSH_PMKSA: Flush all PMKSA cache entries. * * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain @@ -381,7 +499,11 @@ * @NL80211_CMD_ASSOCIATE: association request and notification; like * NL80211_CMD_AUTHENTICATE but for Association and Reassociation * (similar to MLME-ASSOCIATE.request, MLME-REASSOCIATE.request, - * MLME-ASSOCIATE.confirm or MLME-REASSOCIATE.confirm primitives). + * MLME-ASSOCIATE.confirm or MLME-REASSOCIATE.confirm primitives). The + * %NL80211_ATTR_PREV_BSSID attribute is used to specify whether the + * request is for the initial association to an ESS (that attribute not + * included) or for reassociation within the ESS (that attribute is + * included). * @NL80211_CMD_DEAUTHENTICATE: deauthentication request and notification; like * NL80211_CMD_AUTHENTICATE but for Deauthentication frames (similar to * MLME-DEAUTHENTICATION.request and MLME-DEAUTHENTICATE.indication @@ -431,6 +553,9 @@ * set of BSSID,frequency parameters is used (i.e., either the enforcing * %NL80211_ATTR_MAC,%NL80211_ATTR_WIPHY_FREQ or the less strict * %NL80211_ATTR_MAC_HINT and %NL80211_ATTR_WIPHY_FREQ_HINT). + * %NL80211_ATTR_PREV_BSSID can be used to request a reassociation within + * the ESS in case the device is already associated and an association with + * a different BSS is desired. * Background scan period can optionally be * specified in %NL80211_ATTR_BG_SCAN_PERIOD, * if not specified default background scan configuration @@ -438,9 +563,19 @@ * This attribute is ignored if driver does not support roam scan. * It is also sent as an event, with the BSSID and response IEs when the * connection is established or failed to be established. This can be - * determined by the STATUS_CODE attribute. - * @NL80211_CMD_ROAM: request that the card roam (currently not implemented), - * sent as an event when the card/driver roamed by itself. + * determined by the %NL80211_ATTR_STATUS_CODE attribute (0 = success, + * non-zero = failure). If %NL80211_ATTR_TIMED_OUT is included in the + * event, the connection attempt failed due to not being able to initiate + * authentication/association or not receiving a response from the AP. + * Non-zero %NL80211_ATTR_STATUS_CODE value is indicated in that case as + * well to remain backwards compatible. + * @NL80211_CMD_ROAM: notifcation indicating the card/driver roamed by itself. + * When the driver roamed in a network that requires 802.1X authentication, + * %NL80211_ATTR_PORT_AUTHORIZED should be set if the 802.1X authentication + * was done by the driver or if roaming was done using Fast Transition + * protocol (in which case 802.1X authentication is not needed). If + * %NL80211_ATTR_PORT_AUTHORIZED is not set, user space is responsible for + * the 802.1X authentication. * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify * userspace that a connection was dropped by the AP or due to other * reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and @@ -539,6 +674,20 @@ * * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface. * + * @NL80211_CMD_SET_MULTICAST_TO_UNICAST: Configure if this AP should perform + * multicast to unicast conversion. When enabled, all multicast packets + * with ethertype ARP, IPv4 or IPv6 (possibly within an 802.1Q header) + * will be sent out to each station once with the destination (multicast) + * MAC address replaced by the station's MAC address. Note that this may + * break certain expectations of the receiver, e.g. the ability to drop + * unicast IP packets encapsulated in multicast L2 frames, or the ability + * to not send destination unreachable messages in such cases. + * This can only be toggled per BSS. Configure this on an interface of + * type %NL80211_IFTYPE_AP. It applies to all its VLAN interfaces + * (%NL80211_IFTYPE_AP_VLAN), except for those in 4addr (WDS) mode. + * If %NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED is not present with this + * command, the feature is disabled. + * * @NL80211_CMD_JOIN_MESH: Join a mesh. The mesh ID must be given, and initial * mesh config parameters may be given. * @NL80211_CMD_LEAVE_MESH: Leave the mesh network -- no special arguments, the @@ -639,7 +788,18 @@ * @NL80211_CMD_CH_SWITCH_NOTIFY: An AP or GO may decide to switch channels * independently of the userspace SME, send this event indicating * %NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ and the - * attributes determining channel width. + * attributes determining channel width. This indication may also be + * sent when a remotely-initiated switch (e.g., when a STA receives a CSA + * from the remote AP) is completed; + * + * @NL80211_CMD_CH_SWITCH_STARTED_NOTIFY: Notify that a channel switch + * has been started on an interface, regardless of the initiator + * (ie. whether it was requested from a remote device or + * initiated on our own). It indicates that + * %NL80211_ATTR_IFINDEX will be on %NL80211_ATTR_WIPHY_FREQ + * after %NL80211_ATTR_CH_SWITCH_COUNT TBTT's. The userspace may + * decide to react to this indication by requesting other + * interfaces to change channel as well. * * @NL80211_CMD_START_P2P_DEVICE: Start the given P2P Device, identified by * its %NL80211_ATTR_WDEV identifier. It must have been created with @@ -738,6 +898,91 @@ * before removing a station entry entirely, or before disassociating * or similar, cleanup will happen in the driver/device in this case. * + * @NL80211_CMD_GET_MPP: Get mesh path attributes for mesh proxy path to + * destination %NL80211_ATTR_MAC on the interface identified by + * %NL80211_ATTR_IFINDEX. + * + * @NL80211_CMD_JOIN_OCB: Join the OCB network. The center frequency and + * bandwidth of a channel must be given. + * @NL80211_CMD_LEAVE_OCB: Leave the OCB network -- no special arguments, the + * network is determined by the network interface. + * + * @NL80211_CMD_TDLS_CHANNEL_SWITCH: Start channel-switching with a TDLS peer, + * identified by the %NL80211_ATTR_MAC parameter. A target channel is + * provided via %NL80211_ATTR_WIPHY_FREQ and other attributes determining + * channel width/type. The target operating class is given via + * %NL80211_ATTR_OPER_CLASS. + * The driver is responsible for continually initiating channel-switching + * operations and returning to the base channel for communication with the + * AP. + * @NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH: Stop channel-switching with a TDLS + * peer given by %NL80211_ATTR_MAC. Both peers must be on the base channel + * when this command completes. + * + * @NL80211_CMD_WIPHY_REG_CHANGE: Similar to %NL80211_CMD_REG_CHANGE, but used + * as an event to indicate changes for devices with wiphy-specific regdom + * management. + * + * @NL80211_CMD_ABORT_SCAN: Stop an ongoing scan. Returns -ENOENT if a scan is + * not running. The driver indicates the status of the scan through + * cfg80211_scan_done(). + * + * @NL80211_CMD_START_NAN: Start NAN operation, identified by its + * %NL80211_ATTR_WDEV interface. This interface must have been + * previously created with %NL80211_CMD_NEW_INTERFACE. After it + * has been started, the NAN interface will create or join a + * cluster. This command must have a valid + * %NL80211_ATTR_NAN_MASTER_PREF attribute and optional + * %NL80211_ATTR_BANDS attributes. If %NL80211_ATTR_BANDS is + * omitted or set to 0, it means don't-care and the device will + * decide what to use. After this command NAN functions can be + * added. + * @NL80211_CMD_STOP_NAN: Stop the NAN operation, identified by + * its %NL80211_ATTR_WDEV interface. + * @NL80211_CMD_ADD_NAN_FUNCTION: Add a NAN function. The function is defined + * with %NL80211_ATTR_NAN_FUNC nested attribute. When called, this + * operation returns the strictly positive and unique instance id + * (%NL80211_ATTR_NAN_FUNC_INST_ID) and a cookie (%NL80211_ATTR_COOKIE) + * of the function upon success. + * Since instance ID's can be re-used, this cookie is the right + * way to identify the function. This will avoid races when a termination + * event is handled by the user space after it has already added a new + * function that got the same instance id from the kernel as the one + * which just terminated. + * This cookie may be used in NAN events even before the command + * returns, so userspace shouldn't process NAN events until it processes + * the response to this command. + * Look at %NL80211_ATTR_SOCKET_OWNER as well. + * @NL80211_CMD_DEL_NAN_FUNCTION: Delete a NAN function by cookie. + * This command is also used as a notification sent when a NAN function is + * terminated. This will contain a %NL80211_ATTR_NAN_FUNC_INST_ID + * and %NL80211_ATTR_COOKIE attributes. + * @NL80211_CMD_CHANGE_NAN_CONFIG: Change current NAN + * configuration. NAN must be operational (%NL80211_CMD_START_NAN + * was executed). It must contain at least one of the following + * attributes: %NL80211_ATTR_NAN_MASTER_PREF, + * %NL80211_ATTR_BANDS. If %NL80211_ATTR_BANDS is omitted, the + * current configuration is not changed. If it is present but + * set to zero, the configuration is changed to don't-care + * (i.e. the device can decide what to do). + * @NL80211_CMD_NAN_FUNC_MATCH: Notification sent when a match is reported. + * This will contain a %NL80211_ATTR_NAN_MATCH nested attribute and + * %NL80211_ATTR_COOKIE. + * + * @NL80211_CMD_UPDATE_CONNECT_PARAMS: Update one or more connect parameters + * for subsequent roaming cases if the driver or firmware uses internal + * BSS selection. This command can be issued only while connected and it + * does not result in a change for the current association. Currently, + * only the %NL80211_ATTR_IE data is used and updated with this command. + * + * @NL80211_CMD_SET_PMK: For offloaded 4-Way handshake, set the PMK or PMK-R0 + * for the given authenticator address (specified with &NL80211_ATTR_MAC). + * When &NL80211_ATTR_PMKR0_NAME is set, &NL80211_ATTR_PMK specifies the + * PMK-R0, otherwise it specifies the PMK. + * @NL80211_CMD_DEL_PMK: For offloaded 4-Way handshake, delete the previously + * configured PMK for the authenticator address identified by + * &NL80211_ATTR_MAC. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -912,6 +1157,34 @@ enum nl80211_commands { NL80211_CMD_ADD_TX_TS, NL80211_CMD_DEL_TX_TS, + NL80211_CMD_GET_MPP, + + NL80211_CMD_JOIN_OCB, + NL80211_CMD_LEAVE_OCB, + + NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, + + NL80211_CMD_TDLS_CHANNEL_SWITCH, + NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH, + + NL80211_CMD_WIPHY_REG_CHANGE, + + NL80211_CMD_ABORT_SCAN, + + NL80211_CMD_START_NAN, + NL80211_CMD_STOP_NAN, + NL80211_CMD_ADD_NAN_FUNCTION, + NL80211_CMD_DEL_NAN_FUNCTION, + NL80211_CMD_CHANGE_NAN_CONFIG, + NL80211_CMD_NAN_MATCH, + + NL80211_CMD_SET_MULTICAST_TO_UNICAST, + + NL80211_CMD_UPDATE_CONNECT_PARAMS, + + NL80211_CMD_SET_PMK, + NL80211_CMD_DEL_PMK, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -1185,8 +1458,11 @@ enum nl80211_commands { * @NL80211_ATTR_RESP_IE: (Re)association response information elements as * sent by peer, for ROAM and successful CONNECT events. * - * @NL80211_ATTR_PREV_BSSID: previous BSSID, to be used by in ASSOCIATE - * commands to specify using a reassociate frame + * @NL80211_ATTR_PREV_BSSID: previous BSSID, to be used in ASSOCIATE and CONNECT + * commands to specify a request to reassociate within an ESS, i.e., to use + * Reassociate Request frame (with the value of this attribute in the + * Current AP address field) instead of Association Request frame which is + * used for the initial association to an ESS. * * @NL80211_ATTR_KEY: key information in a nested attribute with * %NL80211_KEY_* sub-attributes @@ -1226,7 +1502,13 @@ enum nl80211_commands { * enum nl80211_band value is used as the index (nla_type() of the nested * data. If a band is not included, it will be configured to allow all * rates based on negotiated supported rates information. This attribute - * is used with %NL80211_CMD_SET_TX_BITRATE_MASK. + * is used with %NL80211_CMD_SET_TX_BITRATE_MASK and with starting AP, + * and joining mesh networks (not IBSS yet). In the later case, it must + * specify just a single bitrate, which is to be used for the beacon. + * The driver must also specify support for this with the extended + * features NL80211_EXT_FEATURE_BEACON_RATE_LEGACY, + * NL80211_EXT_FEATURE_BEACON_RATE_HT and + * NL80211_EXT_FEATURE_BEACON_RATE_VHT. * * @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain * at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME. @@ -1472,8 +1754,16 @@ enum nl80211_commands { * the connection request from a station. nl80211_connect_failed_reason * enum has different reasons of connection failure. * - * @NL80211_ATTR_SAE_DATA: SAE elements in Authentication frames. This starts - * with the Authentication transaction sequence number field. + * @NL80211_ATTR_AUTH_DATA: Fields and elements in Authentication frames. + * This contains the authentication frame body (non-IE and IE data), + * excluding the Authentication algorithm number, i.e., starting at the + * Authentication transaction sequence number field. It is used with + * authentication algorithms that need special fields to be added into + * the frames (SAE and FILS). Currently, only the SAE cases use the + * initial two fields (Authentication transaction sequence number and + * Status code). However, those fields are included in the attribute data + * for all authentication algorithms to keep the attribute definition + * consistent. * * @NL80211_ATTR_VHT_CAPABILITY: VHT Capability information element (from * association request when used with NL80211_CMD_NEW_STATION) @@ -1574,7 +1864,9 @@ enum nl80211_commands { * * @NL80211_ATTR_OPMODE_NOTIF: Operating mode field from Operating Mode * Notification Element based on association request when used with - * %NL80211_CMD_NEW_STATION; u8 attribute. + * %NL80211_CMD_NEW_STATION or %NL80211_CMD_SET_STATION (only when + * %NL80211_FEATURE_FULL_AP_CLIENT_STATE is supported, or with TDLS); + * u8 attribute. * * @NL80211_ATTR_VENDOR_ID: The vendor ID, either a 24-bit OUI or, if * %NL80211_VENDOR_ID_IS_LINUX is set, a special Linux ID (not used yet) @@ -1606,9 +1898,23 @@ enum nl80211_commands { * @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32. * As specified in the &enum nl80211_tdls_peer_capability. * - * @NL80211_ATTR_IFACE_SOCKET_OWNER: flag attribute, if set during interface + * @NL80211_ATTR_SOCKET_OWNER: Flag attribute, if set during interface * creation then the new interface will be owned by the netlink socket - * that created it and will be destroyed when the socket is closed + * that created it and will be destroyed when the socket is closed. + * If set during scheduled scan start then the new scan req will be + * owned by the netlink socket that created it and the scheduled scan will + * be stopped when the socket is closed. + * If set during configuration of regulatory indoor operation then the + * regulatory indoor configuration would be owned by the netlink socket + * that configured the indoor setting, and the indoor operation would be + * cleared when the socket is closed. + * If set during NAN interface creation, the interface will be destroyed + * if the socket is closed just like any other interface. Moreover, NAN + * notifications will be sent in unicast to that socket. Without this + * attribute, the notifications will be sent to the %NL80211_MCGRP_NAN + * multicast group. + * If set during %NL80211_CMD_ASSOCIATE or %NL80211_CMD_CONNECT the + * station will deauthenticate when the socket is closed. * * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is * the TDLS link initiator. @@ -1620,6 +1926,8 @@ enum nl80211_commands { * underlying device supports these minimal RRM features: * %NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES, * %NL80211_FEATURE_QUIET, + * Or, if global RRM is supported, see: + * %NL80211_EXT_FEATURE_RRM * If this flag is used, driver must add the Power Capabilities IE to the * association request. In addition, it must also set the RRM capability * flag in the association request's Capability Info field. @@ -1638,6 +1946,200 @@ enum nl80211_commands { * @NL80211_ATTR_SMPS_MODE: SMPS mode to use (ap mode). see * &enum nl80211_smps_mode. * + * @NL80211_ATTR_OPER_CLASS: operating class + * + * @NL80211_ATTR_MAC_MASK: MAC address mask + * + * @NL80211_ATTR_WIPHY_SELF_MANAGED_REG: flag attribute indicating this device + * is self-managing its regulatory information and any regulatory domain + * obtained from it is coming from the device's wiphy and not the global + * cfg80211 regdomain. + * + * @NL80211_ATTR_EXT_FEATURES: extended feature flags contained in a byte + * array. The feature flags are identified by their bit index (see &enum + * nl80211_ext_feature_index). The bit index is ordered starting at the + * least-significant bit of the first byte in the array, ie. bit index 0 + * is located at bit 0 of byte 0. bit index 25 would be located at bit 1 + * of byte 3 (u8 array). + * + * @NL80211_ATTR_SURVEY_RADIO_STATS: Request overall radio statistics to be + * returned along with other survey data. If set, @NL80211_CMD_GET_SURVEY + * may return a survey entry without a channel indicating global radio + * statistics (only some values are valid and make sense.) + * For devices that don't return such an entry even then, the information + * should be contained in the result as the sum of the respective counters + * over all channels. + * + * @NL80211_ATTR_SCHED_SCAN_DELAY: delay before the first cycle of a + * scheduled scan is started. Or the delay before a WoWLAN + * net-detect scan is started, counting from the moment the + * system is suspended. This value is a u32, in seconds. + + * @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device + * is operating in an indoor environment. + * + * @NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS: maximum number of scan plans for + * scheduled scan supported by the device (u32), a wiphy attribute. + * @NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL: maximum interval (in seconds) for + * a scan plan (u32), a wiphy attribute. + * @NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS: maximum number of iterations in + * a scan plan (u32), a wiphy attribute. + * @NL80211_ATTR_SCHED_SCAN_PLANS: a list of scan plans for scheduled scan. + * Each scan plan defines the number of scan iterations and the interval + * between scans. The last scan plan will always run infinitely, + * thus it must not specify the number of iterations, only the interval + * between scans. The scan plans are executed sequentially. + * Each scan plan is a nested attribute of &enum nl80211_sched_scan_plan. + * @NL80211_ATTR_PBSS: flag attribute. If set it means operate + * in a PBSS. Specified in %NL80211_CMD_CONNECT to request + * connecting to a PCP, and in %NL80211_CMD_START_AP to start + * a PCP instead of AP. Relevant for DMG networks only. + * @NL80211_ATTR_BSS_SELECT: nested attribute for driver supporting the + * BSS selection feature. When used with %NL80211_CMD_GET_WIPHY it contains + * attributes according &enum nl80211_bss_select_attr to indicate what + * BSS selection behaviours are supported. When used with %NL80211_CMD_CONNECT + * it contains the behaviour-specific attribute containing the parameters for + * BSS selection to be done by driver and/or firmware. + * + * @NL80211_ATTR_STA_SUPPORT_P2P_PS: whether P2P PS mechanism supported + * or not. u8, one of the values of &enum nl80211_sta_p2p_ps_status + * + * @NL80211_ATTR_PAD: attribute used for padding for 64-bit alignment + * + * @NL80211_ATTR_IFTYPE_EXT_CAPA: Nested attribute of the following attributes: + * %NL80211_ATTR_IFTYPE, %NL80211_ATTR_EXT_CAPA, + * %NL80211_ATTR_EXT_CAPA_MASK, to specify the extended capabilities per + * interface type. + * + * @NL80211_ATTR_MU_MIMO_GROUP_DATA: array of 24 bytes that defines a MU-MIMO + * groupID for monitor mode. + * The first 8 bytes are a mask that defines the membership in each + * group (there are 64 groups, group 0 and 63 are reserved), + * each bit represents a group and set to 1 for being a member in + * that group and 0 for not being a member. + * The remaining 16 bytes define the position in each group: 2 bits for + * each group. + * (smaller group numbers represented on most significant bits and bigger + * group numbers on least significant bits.) + * This attribute is used only if all interfaces are in monitor mode. + * Set this attribute in order to monitor packets using the given MU-MIMO + * groupID data. + * to turn off that feature set all the bits of the groupID to zero. + * @NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR: mac address for the sniffer to follow + * when using MU-MIMO air sniffer. + * to turn that feature off set an invalid mac address + * (e.g. FF:FF:FF:FF:FF:FF) + * + * @NL80211_ATTR_SCAN_START_TIME_TSF: The time at which the scan was actually + * started (u64). The time is the TSF of the BSS the interface that + * requested the scan is connected to (if available, otherwise this + * attribute must not be included). + * @NL80211_ATTR_SCAN_START_TIME_TSF_BSSID: The BSS according to which + * %NL80211_ATTR_SCAN_START_TIME_TSF is set. + * @NL80211_ATTR_MEASUREMENT_DURATION: measurement duration in TUs (u16). If + * %NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY is not set, this is the + * maximum measurement duration allowed. This attribute is used with + * measurement requests. It can also be used with %NL80211_CMD_TRIGGER_SCAN + * if the scan is used for beacon report radio measurement. + * @NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY: flag attribute that indicates + * that the duration specified with %NL80211_ATTR_MEASUREMENT_DURATION is + * mandatory. If this flag is not set, the duration is the maximum duration + * and the actual measurement duration may be shorter. + * + * @NL80211_ATTR_MESH_PEER_AID: Association ID for the mesh peer (u16). This is + * used to pull the stored data for mesh peer in power save state. + * + * @NL80211_ATTR_NAN_MASTER_PREF: the master preference to be used by + * %NL80211_CMD_START_NAN and optionally with + * %NL80211_CMD_CHANGE_NAN_CONFIG. Its type is u8 and it can't be 0. + * Also, values 1 and 255 are reserved for certification purposes and + * should not be used during a normal device operation. + * @NL80211_ATTR_BANDS: operating bands configuration. This is a u32 + * bitmask of BIT(NL80211_BAND_*) as described in %enum + * nl80211_band. For instance, for NL80211_BAND_2GHZ, bit 0 + * would be set. This attribute is used with + * %NL80211_CMD_START_NAN and %NL80211_CMD_CHANGE_NAN_CONFIG, and + * it is optional. If no bands are set, it means don't-care and + * the device will decide what to use. + * @NL80211_ATTR_NAN_FUNC: a function that can be added to NAN. See + * &enum nl80211_nan_func_attributes for description of this nested + * attribute. + * @NL80211_ATTR_NAN_MATCH: used to report a match. This is a nested attribute. + * See &enum nl80211_nan_match_attributes. + * @NL80211_ATTR_FILS_KEK: KEK for FILS (Re)Association Request/Response frame + * protection. + * @NL80211_ATTR_FILS_NONCES: Nonces (part of AAD) for FILS (Re)Association + * Request/Response frame protection. This attribute contains the 16 octet + * STA Nonce followed by 16 octets of AP Nonce. + * + * @NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED: Indicates whether or not multicast + * packets should be send out as unicast to all stations (flag attribute). + * + * @NL80211_ATTR_BSSID: The BSSID of the AP. Note that %NL80211_ATTR_MAC is also + * used in various commands/events for specifying the BSSID. + * + * @NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI: Relative RSSI threshold by which + * other BSSs has to be better or slightly worse than the current + * connected BSS so that they get reported to user space. + * This will give an opportunity to userspace to consider connecting to + * other matching BSSs which have better or slightly worse RSSI than + * the current connected BSS by using an offloaded operation to avoid + * unnecessary wakeups. + * + * @NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST: When present the RSSI level for BSSs in + * the specified band is to be adjusted before doing + * %NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI based comparision to figure out + * better BSSs. The attribute value is a packed structure + * value as specified by &struct nl80211_bss_select_rssi_adjust. + * + * @NL80211_ATTR_TIMEOUT_REASON: The reason for which an operation timed out. + * u32 attribute with an &enum nl80211_timeout_reason value. This is used, + * e.g., with %NL80211_CMD_CONNECT event. + * + * @NL80211_ATTR_FILS_ERP_USERNAME: EAP Re-authentication Protocol (ERP) + * username part of NAI used to refer keys rRK and rIK. This is used with + * %NL80211_CMD_CONNECT. + * + * @NL80211_ATTR_FILS_ERP_REALM: EAP Re-authentication Protocol (ERP) realm part + * of NAI specifying the domain name of the ER server. This is used with + * %NL80211_CMD_CONNECT. + * + * @NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM: Unsigned 16-bit ERP next sequence number + * to use in ERP messages. This is used in generating the FILS wrapped data + * for FILS authentication and is used with %NL80211_CMD_CONNECT. + * + * @NL80211_ATTR_FILS_ERP_RRK: ERP re-authentication Root Key (rRK) for the + * NAI specified by %NL80211_ATTR_FILS_ERP_USERNAME and + * %NL80211_ATTR_FILS_ERP_REALM. This is used for generating rIK and rMSK + * from successful FILS authentication and is used with + * %NL80211_CMD_CONNECT. + * + * @NL80211_ATTR_FILS_CACHE_ID: A 2-octet identifier advertized by a FILS AP + * identifying the scope of PMKSAs. This is used with + * @NL80211_CMD_SET_PMKSA and @NL80211_CMD_DEL_PMKSA. + * + * @NL80211_ATTR_PMK: attribute for passing PMK key material. Used with + * %NL80211_CMD_SET_PMKSA for the PMKSA identified by %NL80211_ATTR_PMKID. + * For %NL80211_CMD_CONNECT it is used to provide PSK for offloading 4-way + * handshake for WPA/WPA2-PSK networks. For 802.1X authentication it is + * used with %NL80211_CMD_SET_PMK. For offloaded FT support this attribute + * specifies the PMK-R0 if NL80211_ATTR_PMKR0_NAME is included as well. + * + * @NL80211_ATTR_SCHED_SCAN_MULTI: flag attribute which user-space shall use to + * indicate that it supports multiple active scheduled scan requests. + * @NL80211_ATTR_SCHED_SCAN_MAX_REQS: indicates maximum number of scheduled + * scan request that may be active for the device (u32). + * + * @NL80211_ATTR_WANT_1X_4WAY_HS: flag attribute which user-space can include + * in %NL80211_CMD_CONNECT to indicate that for 802.1X authentication it + * wants to use the supported offload of the 4-way handshake. + * @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT. + * @NL80211_ATTR_PORT_AUTHORIZED: flag attribute used in %NL80211_CMD_ROAMED + * notification indicating that that 802.1X authentication was done by + * the driver or is not needed (because roaming used the Fast Transition + * protocol). + * + * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1895,7 +2397,7 @@ enum nl80211_attrs { NL80211_ATTR_CONN_FAILED_REASON, - NL80211_ATTR_SAE_DATA, + NL80211_ATTR_AUTH_DATA, NL80211_ATTR_VHT_CAPABILITY, @@ -1973,7 +2475,7 @@ enum nl80211_attrs { NL80211_ATTR_TDLS_PEER_CAPABILITY, - NL80211_ATTR_IFACE_SOCKET_OWNER, + NL80211_ATTR_SOCKET_OWNER, NL80211_ATTR_CSA_C_OFFSETS_TX, NL80211_ATTR_MAX_CSA_COUNTERS, @@ -1990,15 +2492,91 @@ enum nl80211_attrs { NL80211_ATTR_SMPS_MODE, + NL80211_ATTR_OPER_CLASS, + + NL80211_ATTR_MAC_MASK, + + NL80211_ATTR_WIPHY_SELF_MANAGED_REG, + + NL80211_ATTR_EXT_FEATURES, + + NL80211_ATTR_SURVEY_RADIO_STATS, + + NL80211_ATTR_NETNS_FD, + + NL80211_ATTR_SCHED_SCAN_DELAY, + + NL80211_ATTR_REG_INDOOR, + + NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS, + NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL, + NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS, + NL80211_ATTR_SCHED_SCAN_PLANS, + + NL80211_ATTR_PBSS, + + NL80211_ATTR_BSS_SELECT, + + NL80211_ATTR_STA_SUPPORT_P2P_PS, + + NL80211_ATTR_PAD, + + NL80211_ATTR_IFTYPE_EXT_CAPA, + + NL80211_ATTR_MU_MIMO_GROUP_DATA, + NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR, + + NL80211_ATTR_SCAN_START_TIME_TSF, + NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, + NL80211_ATTR_MEASUREMENT_DURATION, + NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY, + + NL80211_ATTR_MESH_PEER_AID, + + NL80211_ATTR_NAN_MASTER_PREF, + NL80211_ATTR_BANDS, + NL80211_ATTR_NAN_FUNC, + NL80211_ATTR_NAN_MATCH, + + NL80211_ATTR_FILS_KEK, + NL80211_ATTR_FILS_NONCES, + + NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED, + + NL80211_ATTR_BSSID, + + NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI, + NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST, + + NL80211_ATTR_TIMEOUT_REASON, + + NL80211_ATTR_FILS_ERP_USERNAME, + NL80211_ATTR_FILS_ERP_REALM, + NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM, + NL80211_ATTR_FILS_ERP_RRK, + NL80211_ATTR_FILS_CACHE_ID, + + NL80211_ATTR_PMK, + + NL80211_ATTR_SCHED_SCAN_MULTI, + NL80211_ATTR_SCHED_SCAN_MAX_REQS, + + NL80211_ATTR_WANT_1X_4WAY_HS, + NL80211_ATTR_PMKR0_NAME, + NL80211_ATTR_PORT_AUTHORIZED, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, + NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST, NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1 }; /* source-level API compatibility */ #define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION #define NL80211_ATTR_MESH_PARAMS NL80211_ATTR_MESH_CONFIG +#define NL80211_ATTR_IFACE_SOCKET_OWNER NL80211_ATTR_SOCKET_OWNER +#define NL80211_ATTR_SAE_DATA NL80211_ATTR_AUTH_DATA /* * Allow user space programs to use #ifdef on new attributes by defining them @@ -2028,7 +2606,7 @@ enum nl80211_attrs { #define NL80211_MAX_SUPP_RATES 32 #define NL80211_MAX_SUPP_HT_RATES 77 -#define NL80211_MAX_SUPP_REG_RULES 32 +#define NL80211_MAX_SUPP_REG_RULES 64 #define NL80211_TKIP_DATA_OFFSET_ENCR_KEY 0 #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16 #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24 @@ -2064,6 +2642,9 @@ enum nl80211_attrs { * and therefore can't be created in the normal ways, use the * %NL80211_CMD_START_P2P_DEVICE and %NL80211_CMD_STOP_P2P_DEVICE * commands to create and destroy one + * @NL80211_IF_TYPE_OCB: Outside Context of a BSS + * This mode corresponds to the MIB variable dot11OCBActivated=true + * @NL80211_IFTYPE_NAN: NAN device interface type (not a netdev) * @NL80211_IFTYPE_MAX: highest interface type number currently defined * @NUM_NL80211_IFTYPES: number of defined interface types * @@ -2083,6 +2664,8 @@ enum nl80211_iftype { NL80211_IFTYPE_P2P_CLIENT, NL80211_IFTYPE_P2P_GO, NL80211_IFTYPE_P2P_DEVICE, + NL80211_IFTYPE_OCB, + NL80211_IFTYPE_NAN, /* keep last */ NUM_NL80211_IFTYPES, @@ -2128,6 +2711,20 @@ enum nl80211_sta_flags { NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1 }; +/** + * enum nl80211_sta_p2p_ps_status - station support of P2P PS + * + * @NL80211_P2P_PS_UNSUPPORTED: station doesn't support P2P PS mechanism + * @@NL80211_P2P_PS_SUPPORTED: station supports P2P PS mechanism + * @NUM_NL80211_P2P_PS_STATUS: number of values + */ +enum nl80211_sta_p2p_ps_status { + NL80211_P2P_PS_UNSUPPORTED = 0, + NL80211_P2P_PS_SUPPORTED, + + NUM_NL80211_P2P_PS_STATUS, +}; + #define NL80211_STA_FLAG_MAX_OLD_API NL80211_STA_FLAG_TDLS_PEER /** @@ -2165,8 +2762,15 @@ struct nl80211_sta_flag_update { * @NL80211_RATE_INFO_VHT_MCS: MCS index for VHT (u8) * @NL80211_RATE_INFO_VHT_NSS: number of streams in VHT (u8) * @NL80211_RATE_INFO_80_MHZ_WIDTH: 80 MHz VHT rate - * @NL80211_RATE_INFO_80P80_MHZ_WIDTH: 80+80 MHz VHT rate + * @NL80211_RATE_INFO_80P80_MHZ_WIDTH: unused - 80+80 is treated the + * same as 160 for purposes of the bitrates * @NL80211_RATE_INFO_160_MHZ_WIDTH: 160 MHz VHT rate + * @NL80211_RATE_INFO_10_MHZ_WIDTH: 10 MHz width - note that this is + * a legacy rate and will be reported as the actual bitrate, i.e. + * half the base (20 MHz) rate + * @NL80211_RATE_INFO_5_MHZ_WIDTH: 5 MHz width - note that this is + * a legacy rate and will be reported as the actual bitrate, i.e. + * a quarter of the base (20 MHz) rate * @__NL80211_RATE_INFO_AFTER_LAST: internal use */ enum nl80211_rate_info { @@ -2181,6 +2785,8 @@ enum nl80211_rate_info { NL80211_RATE_INFO_80_MHZ_WIDTH, NL80211_RATE_INFO_80P80_MHZ_WIDTH, NL80211_RATE_INFO_160_MHZ_WIDTH, + NL80211_RATE_INFO_10_MHZ_WIDTH, + NL80211_RATE_INFO_5_MHZ_WIDTH, /* keep last */ __NL80211_RATE_INFO_AFTER_LAST, @@ -2225,18 +2831,24 @@ enum nl80211_sta_bss_param { * * @__NL80211_STA_INFO_INVALID: attribute number 0 is reserved * @NL80211_STA_INFO_INACTIVE_TIME: time since last activity (u32, msecs) - * @NL80211_STA_INFO_RX_BYTES: total received bytes (u32, from this station) - * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) - * @NL80211_STA_INFO_RX_BYTES64: total received bytes (u64, from this station) - * @NL80211_STA_INFO_TX_BYTES64: total transmitted bytes (u64, to this station) + * @NL80211_STA_INFO_RX_BYTES: total received bytes (MPDU length) + * (u32, from this station) + * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (MPDU length) + * (u32, to this station) + * @NL80211_STA_INFO_RX_BYTES64: total received bytes (MPDU length) + * (u64, from this station) + * @NL80211_STA_INFO_TX_BYTES64: total transmitted bytes (MPDU length) + * (u64, to this station) * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute * containing info as possible, see &enum nl80211_rate_info - * @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station) - * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this - * station) - * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station) - * @NL80211_STA_INFO_TX_FAILED: total failed packets (u32, to this station) + * @NL80211_STA_INFO_RX_PACKETS: total received packet (MSDUs and MMPDUs) + * (u32, from this station) + * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (MSDUs and MMPDUs) + * (u32, to this station) + * @NL80211_STA_INFO_TX_RETRIES: total retries (MPDUs) (u32, to this station) + * @NL80211_STA_INFO_TX_FAILED: total failed packets (MPDUs) + * (u32, to this station) * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm) * @NL80211_STA_INFO_LLID: the station's mesh LLID * @NL80211_STA_INFO_PLID: the station's mesh PLID @@ -2260,6 +2872,19 @@ enum nl80211_sta_bss_param { * Same format as NL80211_STA_INFO_CHAIN_SIGNAL. * @NL80211_STA_EXPECTED_THROUGHPUT: expected throughput considering also the * 802.11 header (u32, kbps) + * @NL80211_STA_INFO_RX_DROP_MISC: RX packets dropped for unspecified reasons + * (u64) + * @NL80211_STA_INFO_BEACON_RX: number of beacons received from this peer (u64) + * @NL80211_STA_INFO_BEACON_SIGNAL_AVG: signal strength average + * for beacons only (u8, dBm) + * @NL80211_STA_INFO_TID_STATS: per-TID statistics (see &enum nl80211_tid_stats) + * This is a nested attribute where each the inner attribute number is the + * TID+1 and the special TID 16 (i.e. value 17) is used for non-QoS frames; + * each one of those is again nested with &enum nl80211_tid_stats + * attributes carrying the actual values. + * @NL80211_STA_INFO_RX_DURATION: aggregate PPDU duration for all frames + * received from the station (u64, usec) + * @NL80211_STA_INFO_PAD: attribute used for padding for 64-bit alignment * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute */ @@ -2292,12 +2917,45 @@ enum nl80211_sta_info { NL80211_STA_INFO_CHAIN_SIGNAL, NL80211_STA_INFO_CHAIN_SIGNAL_AVG, NL80211_STA_INFO_EXPECTED_THROUGHPUT, + NL80211_STA_INFO_RX_DROP_MISC, + NL80211_STA_INFO_BEACON_RX, + NL80211_STA_INFO_BEACON_SIGNAL_AVG, + NL80211_STA_INFO_TID_STATS, + NL80211_STA_INFO_RX_DURATION, + NL80211_STA_INFO_PAD, /* keep last */ __NL80211_STA_INFO_AFTER_LAST, NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 1 }; +/** + * enum nl80211_tid_stats - per TID statistics attributes + * @__NL80211_TID_STATS_INVALID: attribute number 0 is reserved + * @NL80211_TID_STATS_RX_MSDU: number of MSDUs received (u64) + * @NL80211_TID_STATS_TX_MSDU: number of MSDUs transmitted (or + * attempted to transmit; u64) + * @NL80211_TID_STATS_TX_MSDU_RETRIES: number of retries for + * transmitted MSDUs (not counting the first attempt; u64) + * @NL80211_TID_STATS_TX_MSDU_FAILED: number of failed transmitted + * MSDUs (u64) + * @NL80211_TID_STATS_PAD: attribute used for padding for 64-bit alignment + * @NUM_NL80211_TID_STATS: number of attributes here + * @NL80211_TID_STATS_MAX: highest numbered attribute here + */ +enum nl80211_tid_stats { + __NL80211_TID_STATS_INVALID, + NL80211_TID_STATS_RX_MSDU, + NL80211_TID_STATS_TX_MSDU, + NL80211_TID_STATS_TX_MSDU_RETRIES, + NL80211_TID_STATS_TX_MSDU_FAILED, + NL80211_TID_STATS_PAD, + + /* keep last */ + NUM_NL80211_TID_STATS, + NL80211_TID_STATS_MAX = NUM_NL80211_TID_STATS - 1 +}; + /** * enum nl80211_mpath_flags - nl80211 mesh path flags * @@ -2421,16 +3079,17 @@ enum nl80211_band_attr { * an indoor surroundings, i.e., it is connected to AC power (and not * through portable DC inverters) or is under the control of a master * that is acting as an AP and is connected to AC power. - * @NL80211_FREQUENCY_ATTR_GO_CONCURRENT: GO operation is allowed on this + * @NL80211_FREQUENCY_ATTR_IR_CONCURRENT: IR operation is allowed on this * channel if it's connected concurrently to a BSS on the same channel on * the 2 GHz band or to a channel in the same UNII band (on the 5 GHz - * band), and IEEE80211_CHAN_RADAR is not set. Instantiating a GO on a - * channel that has the GO_CONCURRENT attribute set can be done when there - * is a clear assessment that the device is operating under the guidance of - * an authorized master, i.e., setting up a GO while the device is also - * connected to an AP with DFS and radar detection on the UNII band (it is - * up to user-space, i.e., wpa_supplicant to perform the required - * verifications) + * band), and IEEE80211_CHAN_RADAR is not set. Instantiating a GO or TDLS + * off-channel on a channel that has the IR_CONCURRENT attribute set can be + * done when there is a clear assessment that the device is operating under + * the guidance of an authorized master, i.e., setting up a GO or TDLS + * off-channel while the device is also connected to an AP with DFS and + * radar detection on the UNII band (it is up to user-space, i.e., + * wpa_supplicant to perform the required verifications). Using this + * attribute for IR is disallowed for master interfaces (IBSS, AP). * @NL80211_FREQUENCY_ATTR_NO_20MHZ: 20 MHz operation is not allowed * on this channel in current regulatory domain. * @NL80211_FREQUENCY_ATTR_NO_10MHZ: 10 MHz operation is not allowed @@ -2442,7 +3101,7 @@ enum nl80211_band_attr { * See https://apps.fcc.gov/eas/comments/GetPublishedDocument.html?id=327&tn=528122 * for more information on the FCC description of the relaxations allowed * by NL80211_FREQUENCY_ATTR_INDOOR_ONLY and - * NL80211_FREQUENCY_ATTR_GO_CONCURRENT. + * NL80211_FREQUENCY_ATTR_IR_CONCURRENT. */ enum nl80211_frequency_attr { __NL80211_FREQUENCY_ATTR_INVALID, @@ -2460,7 +3119,7 @@ enum nl80211_frequency_attr { NL80211_FREQUENCY_ATTR_NO_160MHZ, NL80211_FREQUENCY_ATTR_DFS_CAC_TIME, NL80211_FREQUENCY_ATTR_INDOOR_ONLY, - NL80211_FREQUENCY_ATTR_GO_CONCURRENT, + NL80211_FREQUENCY_ATTR_IR_CONCURRENT, NL80211_FREQUENCY_ATTR_NO_20MHZ, NL80211_FREQUENCY_ATTR_NO_10MHZ, @@ -2473,6 +3132,8 @@ enum nl80211_frequency_attr { #define NL80211_FREQUENCY_ATTR_PASSIVE_SCAN NL80211_FREQUENCY_ATTR_NO_IR #define NL80211_FREQUENCY_ATTR_NO_IBSS NL80211_FREQUENCY_ATTR_NO_IR #define NL80211_FREQUENCY_ATTR_NO_IR NL80211_FREQUENCY_ATTR_NO_IR +#define NL80211_FREQUENCY_ATTR_GO_CONCURRENT \ + NL80211_FREQUENCY_ATTR_IR_CONCURRENT /** * enum nl80211_bitrate_attr - bitrate attributes @@ -2588,6 +3249,7 @@ enum nl80211_reg_rule_attr { * @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved * @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching, * only report BSS with matching SSID. + * (This cannot be used together with BSSID.) * @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI: RSSI threshold (in dBm) for reporting a * BSS in scan results. Filtering is turned off if not specified. Note that * if this attribute is in a match set of its own, then it is treated as @@ -2596,6 +3258,15 @@ enum nl80211_reg_rule_attr { * how this API was implemented in the past. Also, due to the same problem, * the only way to create a matchset with only an RSSI filter (with this * attribute) is if there's only a single matchset with the RSSI attribute. + * @NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI: Flag indicating whether + * %NL80211_SCHED_SCAN_MATCH_ATTR_RSSI to be used as absolute RSSI or + * relative to current bss's RSSI. + * @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST: When present the RSSI level for + * BSS-es in the specified band is to be adjusted before doing + * RSSI-based BSS selection. The attribute value is a packed structure + * value as specified by &struct nl80211_bss_select_rssi_adjust. + * @NL80211_SCHED_SCAN_MATCH_ATTR_BSSID: BSSID to be used for matching + * (this cannot be used together with SSID). * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter * attribute number currently defined * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use @@ -2605,6 +3276,9 @@ enum nl80211_sched_scan_match_attr { NL80211_SCHED_SCAN_MATCH_ATTR_SSID, NL80211_SCHED_SCAN_MATCH_ATTR_RSSI, + NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI, + NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST, + NL80211_SCHED_SCAN_MATCH_ATTR_BSSID, /* keep last */ __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST, @@ -2631,6 +3305,11 @@ enum nl80211_sched_scan_match_attr { * @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated * base on contiguous rules and wider channels will be allowed to cross * multiple contiguous/overlapping frequency ranges. + * @NL80211_RRF_IR_CONCURRENT: See &NL80211_FREQUENCY_ATTR_IR_CONCURRENT + * @NL80211_RRF_NO_HT40MINUS: channels can't be used in HT40- operation + * @NL80211_RRF_NO_HT40PLUS: channels can't be used in HT40+ operation + * @NL80211_RRF_NO_80MHZ: 80MHz operation not allowed + * @NL80211_RRF_NO_160MHZ: 160MHz operation not allowed */ enum nl80211_reg_rule_flags { NL80211_RRF_NO_OFDM = 1<<0, @@ -2643,11 +3322,19 @@ enum nl80211_reg_rule_flags { NL80211_RRF_NO_IR = 1<<7, __NL80211_RRF_NO_IBSS = 1<<8, NL80211_RRF_AUTO_BW = 1<<11, + NL80211_RRF_IR_CONCURRENT = 1<<12, + NL80211_RRF_NO_HT40MINUS = 1<<13, + NL80211_RRF_NO_HT40PLUS = 1<<14, + NL80211_RRF_NO_80MHZ = 1<<15, + NL80211_RRF_NO_160MHZ = 1<<16, }; #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR #define NL80211_RRF_NO_IBSS NL80211_RRF_NO_IR #define NL80211_RRF_NO_IR NL80211_RRF_NO_IR +#define NL80211_RRF_NO_HT40 (NL80211_RRF_NO_HT40MINUS |\ + NL80211_RRF_NO_HT40PLUS) +#define NL80211_RRF_GO_CONCURRENT NL80211_RRF_IR_CONCURRENT /* For backport compatibility with older userspace */ #define NL80211_RRF_NO_IR_ALL (NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS) @@ -2700,16 +3387,19 @@ enum nl80211_user_reg_hint_type { * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm) * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used - * @NL80211_SURVEY_INFO_CHANNEL_TIME: amount of time (in ms) that the radio - * spent on this channel - * @NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY: amount of the time the primary + * @NL80211_SURVEY_INFO_TIME: amount of time (in ms) that the radio + * was turned on (on channel or globally) + * @NL80211_SURVEY_INFO_TIME_BUSY: amount of the time the primary * channel was sensed busy (either due to activity or energy detect) - * @NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: amount of time the extension + * @NL80211_SURVEY_INFO_TIME_EXT_BUSY: amount of time the extension * channel was sensed busy - * @NL80211_SURVEY_INFO_CHANNEL_TIME_RX: amount of time the radio spent - * receiving data - * @NL80211_SURVEY_INFO_CHANNEL_TIME_TX: amount of time the radio spent - * transmitting data + * @NL80211_SURVEY_INFO_TIME_RX: amount of time the radio spent + * receiving data (on channel or globally) + * @NL80211_SURVEY_INFO_TIME_TX: amount of time the radio spent + * transmitting data (on channel or globally) + * @NL80211_SURVEY_INFO_TIME_SCAN: time the radio spent for scan + * (on this channel or globally) + * @NL80211_SURVEY_INFO_PAD: attribute used for padding for 64-bit alignment * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number * currently defined * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use @@ -2719,17 +3409,26 @@ enum nl80211_survey_info { NL80211_SURVEY_INFO_FREQUENCY, NL80211_SURVEY_INFO_NOISE, NL80211_SURVEY_INFO_IN_USE, - NL80211_SURVEY_INFO_CHANNEL_TIME, - NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, - NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, - NL80211_SURVEY_INFO_CHANNEL_TIME_RX, - NL80211_SURVEY_INFO_CHANNEL_TIME_TX, + NL80211_SURVEY_INFO_TIME, + NL80211_SURVEY_INFO_TIME_BUSY, + NL80211_SURVEY_INFO_TIME_EXT_BUSY, + NL80211_SURVEY_INFO_TIME_RX, + NL80211_SURVEY_INFO_TIME_TX, + NL80211_SURVEY_INFO_TIME_SCAN, + NL80211_SURVEY_INFO_PAD, /* keep last */ __NL80211_SURVEY_INFO_AFTER_LAST, NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1 }; +/* keep old names for compatibility */ +#define NL80211_SURVEY_INFO_CHANNEL_TIME NL80211_SURVEY_INFO_TIME +#define NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY NL80211_SURVEY_INFO_TIME_BUSY +#define NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY NL80211_SURVEY_INFO_TIME_EXT_BUSY +#define NL80211_SURVEY_INFO_CHANNEL_TIME_RX NL80211_SURVEY_INFO_TIME_RX +#define NL80211_SURVEY_INFO_CHANNEL_TIME_TX NL80211_SURVEY_INFO_TIME_TX + /** * enum nl80211_mntr_flags - monitor configuration flags * @@ -2894,7 +3593,8 @@ enum nl80211_mesh_power_mode { * * @NL80211_MESHCONF_PLINK_TIMEOUT: If no tx activity is seen from a STA we've * established peering with for longer than this time (in seconds), then - * remove it from the STA's list of peers. Default is 30 minutes. + * remove it from the STA's list of peers. You may set this to 0 to disable + * the removal of the STA. Default is 30 minutes. * * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use */ @@ -3138,6 +3838,16 @@ enum nl80211_bss_scan_width { * (not present if no beacon frame has been received yet) * @NL80211_BSS_PRESP_DATA: the data in @NL80211_BSS_INFORMATION_ELEMENTS and * @NL80211_BSS_TSF is known to be from a probe response (flag attribute) + * @NL80211_BSS_LAST_SEEN_BOOTTIME: CLOCK_BOOTTIME timestamp when this entry + * was last updated by a received frame. The value is expected to be + * accurate to about 10ms. (u64, nanoseconds) + * @NL80211_BSS_PAD: attribute used for padding for 64-bit alignment + * @NL80211_BSS_PARENT_TSF: the time at the start of reception of the first + * octet of the timestamp field of the last beacon/probe received for + * this BSS. The time is the TSF of the BSS specified by + * @NL80211_BSS_PARENT_BSSID. (u64). + * @NL80211_BSS_PARENT_BSSID: the BSS according to which @NL80211_BSS_PARENT_TSF + * is set. * @__NL80211_BSS_AFTER_LAST: internal * @NL80211_BSS_MAX: highest BSS attribute */ @@ -3157,6 +3867,10 @@ enum nl80211_bss { NL80211_BSS_CHAN_WIDTH, NL80211_BSS_BEACON_TSF, NL80211_BSS_PRESP_DATA, + NL80211_BSS_LAST_SEEN_BOOTTIME, + NL80211_BSS_PAD, + NL80211_BSS_PARENT_TSF, + NL80211_BSS_PARENT_BSSID, /* keep last */ __NL80211_BSS_AFTER_LAST, @@ -3166,6 +3880,9 @@ enum nl80211_bss { /** * enum nl80211_bss_status - BSS "status" * @NL80211_BSS_STATUS_AUTHENTICATED: Authenticated with this BSS. + * Note that this is no longer used since cfg80211 no longer + * keeps track of whether or not authentication was done with + * a given BSS. * @NL80211_BSS_STATUS_ASSOCIATED: Associated with this BSS. * @NL80211_BSS_STATUS_IBSS_JOINED: Joined to this IBSS. * @@ -3186,6 +3903,9 @@ enum nl80211_bss_status { * @NL80211_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r) * @NL80211_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP) * @NL80211_AUTHTYPE_SAE: Simultaneous authentication of equals + * @NL80211_AUTHTYPE_FILS_SK: Fast Initial Link Setup shared key + * @NL80211_AUTHTYPE_FILS_SK_PFS: Fast Initial Link Setup shared key with PFS + * @NL80211_AUTHTYPE_FILS_PK: Fast Initial Link Setup public key * @__NL80211_AUTHTYPE_NUM: internal * @NL80211_AUTHTYPE_MAX: maximum valid auth algorithm * @NL80211_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by @@ -3198,6 +3918,9 @@ enum nl80211_auth_type { NL80211_AUTHTYPE_FT, NL80211_AUTHTYPE_NETWORK_EAP, NL80211_AUTHTYPE_SAE, + NL80211_AUTHTYPE_FILS_SK, + NL80211_AUTHTYPE_FILS_SK_PFS, + NL80211_AUTHTYPE_FILS_PK, /* keep last */ __NL80211_AUTHTYPE_NUM, @@ -3339,11 +4062,15 @@ enum nl80211_txrate_gi { * @NL80211_BAND_2GHZ: 2.4 GHz ISM band * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) * @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 64.80 GHz) + * @NUM_NL80211_BANDS: number of bands, avoid using this in userspace + * since newer kernel versions may support more bands */ enum nl80211_band { NL80211_BAND_2GHZ, NL80211_BAND_5GHZ, NL80211_BAND_60GHZ, + + NUM_NL80211_BANDS, }; /** @@ -3361,7 +4088,10 @@ enum nl80211_ps_state { * @__NL80211_ATTR_CQM_INVALID: invalid * @NL80211_ATTR_CQM_RSSI_THOLD: RSSI threshold in dBm. This value specifies * the threshold for the RSSI level at which an event will be sent. Zero - * to disable. + * to disable. Alternatively, if %NL80211_EXT_FEATURE_CQM_RSSI_LIST is + * set, multiple values can be supplied as a low-to-high sorted array of + * threshold values in dBm. Events will be sent when the RSSI value + * crosses any of the thresholds. * @NL80211_ATTR_CQM_RSSI_HYST: RSSI hysteresis in dBm. This value specifies * the minimum amount the RSSI level must change after an event before a * new event may be issued (to reduce effects of RSSI oscillation). @@ -3379,6 +4109,10 @@ enum nl80211_ps_state { * interval in which %NL80211_ATTR_CQM_TXE_PKTS and * %NL80211_ATTR_CQM_TXE_RATE must be satisfied before generating an * %NL80211_CMD_NOTIFY_CQM. Set to 0 to turn off TX error reporting. + * @NL80211_ATTR_CQM_BEACON_LOSS_EVENT: flag attribute that's set in a beacon + * loss event + * @NL80211_ATTR_CQM_RSSI_LEVEL: the RSSI value in dBm that triggered the + * RSSI threshold event. * @__NL80211_ATTR_CQM_AFTER_LAST: internal * @NL80211_ATTR_CQM_MAX: highest key attribute */ @@ -3391,6 +4125,8 @@ enum nl80211_attr_cqm { NL80211_ATTR_CQM_TXE_RATE, NL80211_ATTR_CQM_TXE_PKTS, NL80211_ATTR_CQM_TXE_INTVL, + NL80211_ATTR_CQM_BEACON_LOSS_EVENT, + NL80211_ATTR_CQM_RSSI_LEVEL, /* keep last */ __NL80211_ATTR_CQM_AFTER_LAST, @@ -3403,9 +4139,7 @@ enum nl80211_attr_cqm { * configured threshold * @NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH: The RSSI is higher than the * configured threshold - * @NL80211_CQM_RSSI_BEACON_LOSS_EVENT: The device experienced beacon loss. - * (Note that deauth/disassoc will still follow if the AP is not - * available. This event might get used as roaming event, etc.) + * @NL80211_CQM_RSSI_BEACON_LOSS_EVENT: (reserved, never sent) */ enum nl80211_cqm_rssi_threshold_event { NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, @@ -3492,6 +4226,8 @@ struct nl80211_pattern_support { * @NL80211_WOWLAN_TRIG_ANY: wake up on any activity, do not really put * the chip into a special state -- works best with chips that have * support for low-power operation already (flag) + * Note that this mode is incompatible with all of the others, if + * any others are even supported by the device. * @NL80211_WOWLAN_TRIG_DISCONNECT: wake up on disconnect, the way disconnect * is detected is implementation-specific (flag) * @NL80211_WOWLAN_TRIG_MAGIC_PKT: wake up on magic packet (6x 0xff, followed @@ -3545,6 +4281,28 @@ struct nl80211_pattern_support { * @NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS: For wakeup reporting only, * the TCP connection ran out of tokens to use for data to send to the * service + * @NL80211_WOWLAN_TRIG_NET_DETECT: wake up when a configured network + * is detected. This is a nested attribute that contains the + * same attributes used with @NL80211_CMD_START_SCHED_SCAN. It + * specifies how the scan is performed (e.g. the interval, the + * channels to scan and the initial delay) as well as the scan + * results that will trigger a wake (i.e. the matchsets). This + * attribute is also sent in a response to + * @NL80211_CMD_GET_WIPHY, indicating the number of match sets + * supported by the driver (u32). + * @NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS: nested attribute + * containing an array with information about what triggered the + * wake up. If no elements are present in the array, it means + * that the information is not available. If more than one + * element is present, it means that more than one match + * occurred. + * Each element in the array is a nested attribute that contains + * one optional %NL80211_ATTR_SSID attribute and one optional + * %NL80211_ATTR_SCAN_FREQUENCIES attribute. At least one of + * these attributes must be present. If + * %NL80211_ATTR_SCAN_FREQUENCIES contains more than one + * frequency, it means that the match occurred in more than one + * channel. * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number * @@ -3570,6 +4328,8 @@ enum nl80211_wowlan_triggers { NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST, NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS, + NL80211_WOWLAN_TRIG_NET_DETECT, + NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS, /* keep last */ NUM_NL80211_WOWLAN_TRIG, @@ -3775,6 +4535,9 @@ enum nl80211_iface_limit_attrs { * of supported channel widths for radar detection. * @NL80211_IFACE_COMB_RADAR_DETECT_REGIONS: u32 attribute containing the bitmap * of supported regulatory regions for radar detection. + * @NL80211_IFACE_COMB_BI_MIN_GCD: u32 attribute specifying the minimum GCD of + * different beacon intervals supported by all the interface combinations + * in this group (if not present, all beacon intervals be identical). * @NUM_NL80211_IFACE_COMB: number of attributes * @MAX_NL80211_IFACE_COMB: highest attribute number * @@ -3782,8 +4545,8 @@ enum nl80211_iface_limit_attrs { * limits = [ #{STA} <= 1, #{AP} <= 1 ], matching BI, channels = 1, max = 2 * => allows an AP and a STA that must match BIs * - * numbers = [ #{AP, P2P-GO} <= 8 ], channels = 1, max = 8 - * => allows 8 of AP/GO + * numbers = [ #{AP, P2P-GO} <= 8 ], BI min gcd, channels = 1, max = 8, + * => allows 8 of AP/GO that can have BI gcd >= min gcd * * numbers = [ #{STA} <= 2 ], channels = 2, max = 2 * => allows two STAs on different channels @@ -3809,6 +4572,7 @@ enum nl80211_if_combination_attrs { NL80211_IFACE_COMB_NUM_CHANNELS, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS, + NL80211_IFACE_COMB_BI_MIN_GCD, /* keep last */ NUM_NL80211_IFACE_COMB, @@ -4042,6 +4806,27 @@ enum nl80211_ap_sme_features { * multiplexing powersave, ie. can turn off all but one chain * and then wake the rest up as required after, for example, * rts/cts handshake. + * @NL80211_FEATURE_SUPPORTS_WMM_ADMISSION: the device supports setting up WMM + * TSPEC sessions (TID aka TSID 0-7) with the %NL80211_CMD_ADD_TX_TS + * command. Standard IEEE 802.11 TSPEC setup is not yet supported, it + * needs to be able to handle Block-Ack agreements and other things. + * @NL80211_FEATURE_MAC_ON_CREATE: Device supports configuring + * the vif's MAC address upon creation. + * See 'macaddr' field in the vif_params (cfg80211.h). + * @NL80211_FEATURE_TDLS_CHANNEL_SWITCH: Driver supports channel switching when + * operating as a TDLS peer. + * @NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR: This device/driver supports using a + * random MAC address during scan (if the device is unassociated); the + * %NL80211_SCAN_FLAG_RANDOM_ADDR flag may be set for scans and the MAC + * address mask/value will be used. + * @NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR: This device/driver supports + * using a random MAC address for every scan iteration during scheduled + * scan (while not associated), the %NL80211_SCAN_FLAG_RANDOM_ADDR may + * be set for scheduled scan and the MAC address mask/value will be used. + * @NL80211_FEATURE_ND_RANDOM_MAC_ADDR: This device/driver supports using a + * random MAC address for every scan iteration during "net detect", i.e. + * scan in unassociated WoWLAN, the %NL80211_SCAN_FLAG_RANDOM_ADDR may + * be set for scheduled scan and the MAC address mask/value will be used. */ enum nl80211_feature_flags { NL80211_FEATURE_SK_TX_STATUS = 1 << 0, @@ -4070,6 +4855,91 @@ enum nl80211_feature_flags { NL80211_FEATURE_ACKTO_ESTIMATION = 1 << 23, NL80211_FEATURE_STATIC_SMPS = 1 << 24, NL80211_FEATURE_DYNAMIC_SMPS = 1 << 25, + NL80211_FEATURE_SUPPORTS_WMM_ADMISSION = 1 << 26, + NL80211_FEATURE_MAC_ON_CREATE = 1 << 27, + NL80211_FEATURE_TDLS_CHANNEL_SWITCH = 1 << 28, + NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR = 1 << 29, + NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR = 1 << 30, + NL80211_FEATURE_ND_RANDOM_MAC_ADDR = 1 << 31, +}; + +/** + * enum nl80211_ext_feature_index - bit index of extended features. + * @NL80211_EXT_FEATURE_VHT_IBSS: This driver supports IBSS with VHT datarates. + * @NL80211_EXT_FEATURE_RRM: This driver supports RRM. When featured, user can + * can request to use RRM (see %NL80211_ATTR_USE_RRM) with + * %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests, which will set + * the ASSOC_REQ_USE_RRM flag in the association request even if + * NL80211_FEATURE_QUIET is not advertized. + * @NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER: This device supports MU-MIMO air + * sniffer which means that it can be configured to hear packets from + * certain groups which can be configured by the + * %NL80211_ATTR_MU_MIMO_GROUP_DATA attribute, + * or can be configured to follow a station by configuring the + * %NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR attribute. + * @NL80211_EXT_FEATURE_SCAN_START_TIME: This driver includes the actual + * time the scan started in scan results event. The time is the TSF of + * the BSS that the interface that requested the scan is connected to + * (if available). + * @NL80211_EXT_FEATURE_BSS_PARENT_TSF: Per BSS, this driver reports the + * time the last beacon/probe was received. The time is the TSF of the + * BSS that the interface that requested the scan is connected to + * (if available). + * @NL80211_EXT_FEATURE_SET_SCAN_DWELL: This driver supports configuration of + * channel dwell time. + * @NL80211_EXT_FEATURE_BEACON_RATE_LEGACY: Driver supports beacon rate + * configuration (AP/mesh), supporting a legacy (non HT/VHT) rate. + * @NL80211_EXT_FEATURE_BEACON_RATE_HT: Driver supports beacon rate + * configuration (AP/mesh) with HT rates. + * @NL80211_EXT_FEATURE_BEACON_RATE_VHT: Driver supports beacon rate + * configuration (AP/mesh) with VHT rates. + * @NL80211_EXT_FEATURE_FILS_STA: This driver supports Fast Initial Link Setup + * with user space SME (NL80211_CMD_AUTHENTICATE) in station mode. + * @NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA: This driver supports randomized TA + * in @NL80211_CMD_FRAME while not associated. + * @NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED: This driver supports + * randomized TA in @NL80211_CMD_FRAME while associated. + * @NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI: The driver supports sched_scan + * for reporting BSSs with better RSSI than the current connected BSS + * (%NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI). + * @NL80211_EXT_FEATURE_CQM_RSSI_LIST: With this driver the + * %NL80211_ATTR_CQM_RSSI_THOLD attribute accepts a list of zero or more + * RSSI threshold values to monitor rather than exactly one threshold. + * @NL80211_EXT_FEATURE_FILS_SK_OFFLOAD: Driver SME supports FILS shared key + * authentication with %NL80211_CMD_CONNECT. + * @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK: Device wants to do 4-way + * handshake with PSK in station mode (PSK is passed as part of the connect + * and associate commands), doing it in the host might not be supported. + * @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X: Device wants to do doing 4-way + * handshake with 802.1X in station mode (will pass EAP frames to the host + * and accept the set_pmk/del_pmk commands), doing it in the host might not + * be supported. + * + * @NUM_NL80211_EXT_FEATURES: number of extended features. + * @MAX_NL80211_EXT_FEATURES: highest extended feature index. + */ +enum nl80211_ext_feature_index { + NL80211_EXT_FEATURE_VHT_IBSS, + NL80211_EXT_FEATURE_RRM, + NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER, + NL80211_EXT_FEATURE_SCAN_START_TIME, + NL80211_EXT_FEATURE_BSS_PARENT_TSF, + NL80211_EXT_FEATURE_SET_SCAN_DWELL, + NL80211_EXT_FEATURE_BEACON_RATE_LEGACY, + NL80211_EXT_FEATURE_BEACON_RATE_HT, + NL80211_EXT_FEATURE_BEACON_RATE_VHT, + NL80211_EXT_FEATURE_FILS_STA, + NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA, + NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED, + NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI, + NL80211_EXT_FEATURE_CQM_RSSI_LIST, + NL80211_EXT_FEATURE_FILS_SK_OFFLOAD, + NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK, + NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X, + + /* add new features before the definition below */ + NUM_NL80211_EXT_FEATURES, + MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1 }; /** @@ -4104,6 +4974,21 @@ enum nl80211_connect_failed_reason { NL80211_CONN_FAIL_BLOCKED_CLIENT, }; +/** + * enum nl80211_timeout_reason - timeout reasons + * + * @NL80211_TIMEOUT_UNSPECIFIED: Timeout reason unspecified. + * @NL80211_TIMEOUT_SCAN: Scan (AP discovery) timed out. + * @NL80211_TIMEOUT_AUTH: Authentication timed out. + * @NL80211_TIMEOUT_ASSOC: Association timed out. + */ +enum nl80211_timeout_reason { + NL80211_TIMEOUT_UNSPECIFIED, + NL80211_TIMEOUT_SCAN, + NL80211_TIMEOUT_AUTH, + NL80211_TIMEOUT_ASSOC, +}; + /** * enum nl80211_scan_flags - scan request control flags * @@ -4118,11 +5003,21 @@ enum nl80211_connect_failed_reason { * dangerous because will destroy stations performance as a lot of frames * will be lost while scanning off-channel, therefore it must be used only * when really needed + * @NL80211_SCAN_FLAG_RANDOM_ADDR: use a random MAC address for this scan (or + * for scheduled scan: a different one for every scan iteration). When the + * flag is set, depending on device capabilities the @NL80211_ATTR_MAC and + * @NL80211_ATTR_MAC_MASK attributes may also be given in which case only + * the masked bits will be preserved from the MAC address and the remainder + * randomised. If the attributes are not given full randomisation (46 bits, + * locally administered 1, multicast 0) is assumed. + * This flag must not be requested when the feature isn't supported, check + * the nl80211 feature flags for the device. */ enum nl80211_scan_flags { NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0, NL80211_SCAN_FLAG_FLUSH = 1<<1, NL80211_SCAN_FLAG_AP = 1<<2, + NL80211_SCAN_FLAG_RANDOM_ADDR = 1<<3, }; /** @@ -4176,12 +5071,17 @@ enum nl80211_smps_mode { * change to the channel status. * @NL80211_RADAR_NOP_FINISHED: The Non-Occupancy Period for this channel is * over, channel becomes usable. + * @NL80211_RADAR_PRE_CAC_EXPIRED: Channel Availability Check done on this + * non-operating channel is expired and no longer valid. New CAC must + * be done on this channel before starting the operation. This is not + * applicable for ETSI dfs domain where pre-CAC is valid for ever. */ enum nl80211_radar_event { NL80211_RADAR_DETECTED, NL80211_RADAR_CAC_FINISHED, NL80211_RADAR_CAC_ABORTED, NL80211_RADAR_NOP_FINISHED, + NL80211_RADAR_PRE_CAC_EXPIRED, }; /** @@ -4281,4 +5181,240 @@ enum nl80211_tdls_peer_capability { NL80211_TDLS_PEER_WMM = 1<<2, }; +/** + * enum nl80211_sched_scan_plan - scanning plan for scheduled scan + * @__NL80211_SCHED_SCAN_PLAN_INVALID: attribute number 0 is reserved + * @NL80211_SCHED_SCAN_PLAN_INTERVAL: interval between scan iterations. In + * seconds (u32). + * @NL80211_SCHED_SCAN_PLAN_ITERATIONS: number of scan iterations in this + * scan plan (u32). The last scan plan must not specify this attribute + * because it will run infinitely. A value of zero is invalid as it will + * make the scan plan meaningless. + * @NL80211_SCHED_SCAN_PLAN_MAX: highest scheduled scan plan attribute number + * currently defined + * @__NL80211_SCHED_SCAN_PLAN_AFTER_LAST: internal use + */ +enum nl80211_sched_scan_plan { + __NL80211_SCHED_SCAN_PLAN_INVALID, + NL80211_SCHED_SCAN_PLAN_INTERVAL, + NL80211_SCHED_SCAN_PLAN_ITERATIONS, + + /* keep last */ + __NL80211_SCHED_SCAN_PLAN_AFTER_LAST, + NL80211_SCHED_SCAN_PLAN_MAX = + __NL80211_SCHED_SCAN_PLAN_AFTER_LAST - 1 +}; + +/** + * struct nl80211_bss_select_rssi_adjust - RSSI adjustment parameters. + * + * @band: band of BSS that must match for RSSI value adjustment. The value + * of this field is according to &enum nl80211_band. + * @delta: value used to adjust the RSSI value of matching BSS in dB. + */ +struct nl80211_bss_select_rssi_adjust { + __u8 band; + __s8 delta; +} __attribute__((packed)); + +/** + * enum nl80211_bss_select_attr - attributes for bss selection. + * + * @__NL80211_BSS_SELECT_ATTR_INVALID: reserved. + * @NL80211_BSS_SELECT_ATTR_RSSI: Flag indicating only RSSI-based BSS selection + * is requested. + * @NL80211_BSS_SELECT_ATTR_BAND_PREF: attribute indicating BSS + * selection should be done such that the specified band is preferred. + * When there are multiple BSS-es in the preferred band, the driver + * shall use RSSI-based BSS selection as a second step. The value of + * this attribute is according to &enum nl80211_band (u32). + * @NL80211_BSS_SELECT_ATTR_RSSI_ADJUST: When present the RSSI level for + * BSS-es in the specified band is to be adjusted before doing + * RSSI-based BSS selection. The attribute value is a packed structure + * value as specified by &struct nl80211_bss_select_rssi_adjust. + * @NL80211_BSS_SELECT_ATTR_MAX: highest bss select attribute number. + * @__NL80211_BSS_SELECT_ATTR_AFTER_LAST: internal use. + * + * One and only one of these attributes are found within %NL80211_ATTR_BSS_SELECT + * for %NL80211_CMD_CONNECT. It specifies the required BSS selection behaviour + * which the driver shall use. + */ +enum nl80211_bss_select_attr { + __NL80211_BSS_SELECT_ATTR_INVALID, + NL80211_BSS_SELECT_ATTR_RSSI, + NL80211_BSS_SELECT_ATTR_BAND_PREF, + NL80211_BSS_SELECT_ATTR_RSSI_ADJUST, + + /* keep last */ + __NL80211_BSS_SELECT_ATTR_AFTER_LAST, + NL80211_BSS_SELECT_ATTR_MAX = __NL80211_BSS_SELECT_ATTR_AFTER_LAST - 1 +}; + +/** + * enum nl80211_nan_function_type - NAN function type + * + * Defines the function type of a NAN function + * + * @NL80211_NAN_FUNC_PUBLISH: function is publish + * @NL80211_NAN_FUNC_SUBSCRIBE: function is subscribe + * @NL80211_NAN_FUNC_FOLLOW_UP: function is follow-up + */ +enum nl80211_nan_function_type { + NL80211_NAN_FUNC_PUBLISH, + NL80211_NAN_FUNC_SUBSCRIBE, + NL80211_NAN_FUNC_FOLLOW_UP, + + /* keep last */ + __NL80211_NAN_FUNC_TYPE_AFTER_LAST, + NL80211_NAN_FUNC_MAX_TYPE = __NL80211_NAN_FUNC_TYPE_AFTER_LAST - 1, +}; + +/** + * enum nl80211_nan_publish_type - NAN publish tx type + * + * Defines how to send publish Service Discovery Frames + * + * @NL80211_NAN_SOLICITED_PUBLISH: publish function is solicited + * @NL80211_NAN_UNSOLICITED_PUBLISH: publish function is unsolicited + */ +enum nl80211_nan_publish_type { + NL80211_NAN_SOLICITED_PUBLISH = 1 << 0, + NL80211_NAN_UNSOLICITED_PUBLISH = 1 << 1, +}; + +/** + * enum nl80211_nan_func_term_reason - NAN functions termination reason + * + * Defines termination reasons of a NAN function + * + * @NL80211_NAN_FUNC_TERM_REASON_USER_REQUEST: requested by user + * @NL80211_NAN_FUNC_TERM_REASON_TTL_EXPIRED: timeout + * @NL80211_NAN_FUNC_TERM_REASON_ERROR: errored + */ +enum nl80211_nan_func_term_reason { + NL80211_NAN_FUNC_TERM_REASON_USER_REQUEST, + NL80211_NAN_FUNC_TERM_REASON_TTL_EXPIRED, + NL80211_NAN_FUNC_TERM_REASON_ERROR, +}; + +#define NL80211_NAN_FUNC_SERVICE_ID_LEN 6 +#define NL80211_NAN_FUNC_SERVICE_SPEC_INFO_MAX_LEN 0xff +#define NL80211_NAN_FUNC_SRF_MAX_LEN 0xff + +/** + * enum nl80211_nan_func_attributes - NAN function attributes + * @__NL80211_NAN_FUNC_INVALID: invalid + * @NL80211_NAN_FUNC_TYPE: &enum nl80211_nan_function_type (u8). + * @NL80211_NAN_FUNC_SERVICE_ID: 6 bytes of the service ID hash as + * specified in NAN spec. This is a binary attribute. + * @NL80211_NAN_FUNC_PUBLISH_TYPE: relevant if the function's type is + * publish. Defines the transmission type for the publish Service Discovery + * Frame, see &enum nl80211_nan_publish_type. Its type is u8. + * @NL80211_NAN_FUNC_PUBLISH_BCAST: relevant if the function is a solicited + * publish. Should the solicited publish Service Discovery Frame be sent to + * the NAN Broadcast address. This is a flag. + * @NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE: relevant if the function's type is + * subscribe. Is the subscribe active. This is a flag. + * @NL80211_NAN_FUNC_FOLLOW_UP_ID: relevant if the function's type is follow up. + * The instance ID for the follow up Service Discovery Frame. This is u8. + * @NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID: relevant if the function's type + * is follow up. This is a u8. + * The requestor instance ID for the follow up Service Discovery Frame. + * @NL80211_NAN_FUNC_FOLLOW_UP_DEST: the MAC address of the recipient of the + * follow up Service Discovery Frame. This is a binary attribute. + * @NL80211_NAN_FUNC_CLOSE_RANGE: is this function limited for devices in a + * close range. The range itself (RSSI) is defined by the device. + * This is a flag. + * @NL80211_NAN_FUNC_TTL: strictly positive number of DWs this function should + * stay active. If not present infinite TTL is assumed. This is a u32. + * @NL80211_NAN_FUNC_SERVICE_INFO: array of bytes describing the service + * specific info. This is a binary attribute. + * @NL80211_NAN_FUNC_SRF: Service Receive Filter. This is a nested attribute. + * See &enum nl80211_nan_srf_attributes. + * @NL80211_NAN_FUNC_RX_MATCH_FILTER: Receive Matching filter. This is a nested + * attribute. It is a list of binary values. + * @NL80211_NAN_FUNC_TX_MATCH_FILTER: Transmit Matching filter. This is a + * nested attribute. It is a list of binary values. + * @NL80211_NAN_FUNC_INSTANCE_ID: The instance ID of the function. + * Its type is u8 and it cannot be 0. + * @NL80211_NAN_FUNC_TERM_REASON: NAN function termination reason. + * See &enum nl80211_nan_func_term_reason. + * + * @NUM_NL80211_NAN_FUNC_ATTR: internal + * @NL80211_NAN_FUNC_ATTR_MAX: highest NAN function attribute + */ +enum nl80211_nan_func_attributes { + __NL80211_NAN_FUNC_INVALID, + NL80211_NAN_FUNC_TYPE, + NL80211_NAN_FUNC_SERVICE_ID, + NL80211_NAN_FUNC_PUBLISH_TYPE, + NL80211_NAN_FUNC_PUBLISH_BCAST, + NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE, + NL80211_NAN_FUNC_FOLLOW_UP_ID, + NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID, + NL80211_NAN_FUNC_FOLLOW_UP_DEST, + NL80211_NAN_FUNC_CLOSE_RANGE, + NL80211_NAN_FUNC_TTL, + NL80211_NAN_FUNC_SERVICE_INFO, + NL80211_NAN_FUNC_SRF, + NL80211_NAN_FUNC_RX_MATCH_FILTER, + NL80211_NAN_FUNC_TX_MATCH_FILTER, + NL80211_NAN_FUNC_INSTANCE_ID, + NL80211_NAN_FUNC_TERM_REASON, + + /* keep last */ + NUM_NL80211_NAN_FUNC_ATTR, + NL80211_NAN_FUNC_ATTR_MAX = NUM_NL80211_NAN_FUNC_ATTR - 1 +}; + +/** + * enum nl80211_nan_srf_attributes - NAN Service Response filter attributes + * @__NL80211_NAN_SRF_INVALID: invalid + * @NL80211_NAN_SRF_INCLUDE: present if the include bit of the SRF set. + * This is a flag. + * @NL80211_NAN_SRF_BF: Bloom Filter. Present if and only if + * &NL80211_NAN_SRF_MAC_ADDRS isn't present. This attribute is binary. + * @NL80211_NAN_SRF_BF_IDX: index of the Bloom Filter. Mandatory if + * &NL80211_NAN_SRF_BF is present. This is a u8. + * @NL80211_NAN_SRF_MAC_ADDRS: list of MAC addresses for the SRF. Present if + * and only if &NL80211_NAN_SRF_BF isn't present. This is a nested + * attribute. Each nested attribute is a MAC address. + * @NUM_NL80211_NAN_SRF_ATTR: internal + * @NL80211_NAN_SRF_ATTR_MAX: highest NAN SRF attribute + */ +enum nl80211_nan_srf_attributes { + __NL80211_NAN_SRF_INVALID, + NL80211_NAN_SRF_INCLUDE, + NL80211_NAN_SRF_BF, + NL80211_NAN_SRF_BF_IDX, + NL80211_NAN_SRF_MAC_ADDRS, + + /* keep last */ + NUM_NL80211_NAN_SRF_ATTR, + NL80211_NAN_SRF_ATTR_MAX = NUM_NL80211_NAN_SRF_ATTR - 1, +}; + +/** + * enum nl80211_nan_match_attributes - NAN match attributes + * @__NL80211_NAN_MATCH_INVALID: invalid + * @NL80211_NAN_MATCH_FUNC_LOCAL: the local function that had the + * match. This is a nested attribute. + * See &enum nl80211_nan_func_attributes. + * @NL80211_NAN_MATCH_FUNC_PEER: the peer function + * that caused the match. This is a nested attribute. + * See &enum nl80211_nan_func_attributes. + * + * @NUM_NL80211_NAN_MATCH_ATTR: internal + * @NL80211_NAN_MATCH_ATTR_MAX: highest NAN match attribute + */ +enum nl80211_nan_match_attributes { + __NL80211_NAN_MATCH_INVALID, + NL80211_NAN_MATCH_FUNC_LOCAL, + NL80211_NAN_MATCH_FUNC_PEER, + + /* keep last */ + NUM_NL80211_NAN_MATCH_ATTR, + NL80211_NAN_MATCH_ATTR_MAX = NUM_NL80211_NAN_MATCH_ATTR - 1 +}; + #endif /* __LINUX_NL80211_H */ diff --git a/user_space/sdrctl_src/nl80211_testmode_def.h b/user_space/sdrctl_src/nl80211_testmode_def.h index 99d4e3c..1fee11d 100644 --- a/user_space/sdrctl_src/nl80211_testmode_def.h +++ b/user_space/sdrctl_src/nl80211_testmode_def.h @@ -5,14 +5,14 @@ enum openwifi_testmode_attr { __OPENWIFI_ATTR_INVALID = 0, OPENWIFI_ATTR_CMD = 1, OPENWIFI_ATTR_GAP = 2, - OPENWIFI_ATTR_ADDR0 = 3, - OPENWIFI_ATTR_ADDR1 = 4, - OPENWIFI_ATTR_SLICE_TOTAL0 = 5, - OPENWIFI_ATTR_SLICE_START0 = 6, - OPENWIFI_ATTR_SLICE_END0 = 7, - OPENWIFI_ATTR_SLICE_TOTAL1 = 8, - OPENWIFI_ATTR_SLICE_START1 = 9, - OPENWIFI_ATTR_SLICE_END1 = 10, + OPENWIFI_ATTR_SLICE_IDX = 3, + OPENWIFI_ATTR_ADDR = 4, + OPENWIFI_ATTR_SLICE_TOTAL = 5, + OPENWIFI_ATTR_SLICE_START = 6, + OPENWIFI_ATTR_SLICE_END = 7, + // OPENWIFI_ATTR_SLICE_TOTAL1 = 8, + // OPENWIFI_ATTR_SLICE_START1 = 9, + // OPENWIFI_ATTR_SLICE_END1 = 10, OPENWIFI_ATTR_RSSI_TH = 11, OPENWIFI_ATTR_HIGH_TSF = 12, OPENWIFI_ATTR_LOW_TSF = 13, @@ -29,29 +29,29 @@ enum openwifi_testmode_cmd { OPENWIFI_CMD_SET_GAP = 0, OPENWIFI_CMD_GET_GAP = 1, - OPENWIFI_CMD_SET_ADDR0 = 2, - OPENWIFI_CMD_GET_ADDR0 = 3, + OPENWIFI_CMD_SET_SLICE_IDX = 2, + OPENWIFI_CMD_GET_SLICE_IDX = 3, - OPENWIFI_CMD_SET_ADDR1 = 4, - OPENWIFI_CMD_GET_ADDR1 = 5, + OPENWIFI_CMD_SET_ADDR = 4, + OPENWIFI_CMD_GET_ADDR = 5, - OPENWIFI_CMD_SET_SLICE_TOTAL0 = 6, - OPENWIFI_CMD_GET_SLICE_TOTAL0 = 7, + OPENWIFI_CMD_SET_SLICE_TOTAL = 6, + OPENWIFI_CMD_GET_SLICE_TOTAL = 7, - OPENWIFI_CMD_SET_SLICE_START0 = 8, - OPENWIFI_CMD_GET_SLICE_START0 = 9, + OPENWIFI_CMD_SET_SLICE_START = 8, + OPENWIFI_CMD_GET_SLICE_START = 9, - OPENWIFI_CMD_SET_SLICE_END0 = 10, - OPENWIFI_CMD_GET_SLICE_END0 = 11, + OPENWIFI_CMD_SET_SLICE_END = 10, + OPENWIFI_CMD_GET_SLICE_END = 11, - OPENWIFI_CMD_SET_SLICE_TOTAL1 = 12, - OPENWIFI_CMD_GET_SLICE_TOTAL1 = 13, + // OPENWIFI_CMD_SET_SLICE_TOTAL1 = 12, + // OPENWIFI_CMD_GET_SLICE_TOTAL1 = 13, - OPENWIFI_CMD_SET_SLICE_START1 = 14, - OPENWIFI_CMD_GET_SLICE_START1 = 15, + // OPENWIFI_CMD_SET_SLICE_START1 = 14, + // OPENWIFI_CMD_GET_SLICE_START1 = 15, - OPENWIFI_CMD_SET_SLICE_END1 = 16, - OPENWIFI_CMD_GET_SLICE_END1 = 17, + // OPENWIFI_CMD_SET_SLICE_END1 = 16, + // OPENWIFI_CMD_GET_SLICE_END1 = 17, OPENWIFI_CMD_SET_RSSI_TH = 18, OPENWIFI_CMD_GET_RSSI_TH = 19, @@ -65,14 +65,14 @@ enum openwifi_testmode_cmd { static const struct nla_policy openwifi_testmode_policy[OPENWIFI_ATTR_MAX + 1] = { [OPENWIFI_ATTR_CMD] = { .type = NLA_U32 }, [OPENWIFI_ATTR_GAP] = { .type = NLA_U32 }, - [OPENWIFI_ATTR_ADDR0] = { .type = NLA_U32 }, - [OPENWIFI_ATTR_ADDR1] = { .type = NLA_U32 }, - [OPENWIFI_ATTR_SLICE_TOTAL0] = { .type = NLA_U32 }, - [OPENWIFI_ATTR_SLICE_START0] = { .type = NLA_U32 }, - [OPENWIFI_ATTR_SLICE_END0] = { .type = NLA_U32 }, - [OPENWIFI_ATTR_SLICE_TOTAL1] = { .type = NLA_U32 }, - [OPENWIFI_ATTR_SLICE_START1] = { .type = NLA_U32 }, - [OPENWIFI_ATTR_SLICE_END1] = { .type = NLA_U32 }, + [OPENWIFI_ATTR_SLICE_IDX] = { .type = NLA_U32 }, + [OPENWIFI_ATTR_ADDR] = { .type = NLA_U32 }, + [OPENWIFI_ATTR_SLICE_TOTAL] = { .type = NLA_U32 }, + [OPENWIFI_ATTR_SLICE_START] = { .type = NLA_U32 }, + [OPENWIFI_ATTR_SLICE_END] = { .type = NLA_U32 }, + // [OPENWIFI_ATTR_SLICE_TOTAL1] = { .type = NLA_U32 }, + // [OPENWIFI_ATTR_SLICE_START1] = { .type = NLA_U32 }, + // [OPENWIFI_ATTR_SLICE_END1] = { .type = NLA_U32 }, [OPENWIFI_ATTR_RSSI_TH] = { .type = NLA_U32 }, [OPENWIFI_ATTR_HIGH_TSF] = { .type = NLA_U32 }, [OPENWIFI_ATTR_LOW_TSF] = { .type = NLA_U32 }, diff --git a/user_space/sdrctl_src/sdrctl.h b/user_space/sdrctl_src/sdrctl.h index eedf31e..2be0627 100644 --- a/user_space/sdrctl_src/sdrctl.h +++ b/user_space/sdrctl_src/sdrctl.h @@ -9,7 +9,7 @@ #include #include "nl80211.h" -#include "ieee80211.h" +//#include "ieee80211.h" #define ETH_ALEN 6