@@ -2396,101 +2396,129 @@ brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
23962396 brcmf_err ("set wsec error (%d)\n" , err );
23972397}
23982398
2399+ static void brcmf_convert_sta_flags (u32 fw_sta_flags , struct station_info * si )
2400+ {
2401+ struct nl80211_sta_flag_update * sfu ;
2402+
2403+ brcmf_dbg (TRACE , "flags %08x\n" , fw_sta_flags );
2404+ si -> filled |= BIT (NL80211_STA_INFO_STA_FLAGS );
2405+ sfu = & si -> sta_flags ;
2406+ sfu -> mask = BIT (NL80211_STA_FLAG_WME ) |
2407+ BIT (NL80211_STA_FLAG_AUTHENTICATED ) |
2408+ BIT (NL80211_STA_FLAG_ASSOCIATED ) |
2409+ BIT (NL80211_STA_FLAG_AUTHORIZED );
2410+ if (fw_sta_flags & BRCMF_STA_WME )
2411+ sfu -> set |= BIT (NL80211_STA_FLAG_WME );
2412+ if (fw_sta_flags & BRCMF_STA_AUTHE )
2413+ sfu -> set |= BIT (NL80211_STA_FLAG_AUTHENTICATED );
2414+ if (fw_sta_flags & BRCMF_STA_ASSOC )
2415+ sfu -> set |= BIT (NL80211_STA_FLAG_ASSOCIATED );
2416+ if (fw_sta_flags & BRCMF_STA_AUTHO )
2417+ sfu -> set |= BIT (NL80211_STA_FLAG_AUTHORIZED );
2418+ }
2419+
2420+ static void brcmf_fill_bss_param (struct brcmf_if * ifp , struct station_info * si )
2421+ {
2422+ struct {
2423+ __le32 len ;
2424+ struct brcmf_bss_info_le bss_le ;
2425+ } * buf ;
2426+ u16 capability ;
2427+ int err ;
2428+
2429+ buf = kzalloc (WL_BSS_INFO_MAX , GFP_KERNEL );
2430+ if (!buf )
2431+ return ;
2432+
2433+ buf -> len = cpu_to_le32 (WL_BSS_INFO_MAX );
2434+ err = brcmf_fil_cmd_data_get (ifp , BRCMF_C_GET_BSS_INFO , buf ,
2435+ WL_BSS_INFO_MAX );
2436+ if (err ) {
2437+ brcmf_err ("Failed to get bss info (%d)\n" , err );
2438+ return ;
2439+ }
2440+ si -> filled |= BIT (NL80211_STA_INFO_BSS_PARAM );
2441+ si -> bss_param .beacon_interval = le16_to_cpu (buf -> bss_le .beacon_period );
2442+ si -> bss_param .dtim_period = buf -> bss_le .dtim_period ;
2443+ capability = le16_to_cpu (buf -> bss_le .capability );
2444+ if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT )
2445+ si -> bss_param .flags |= BSS_PARAM_FLAGS_CTS_PROT ;
2446+ if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE )
2447+ si -> bss_param .flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE ;
2448+ if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME )
2449+ si -> bss_param .flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME ;
2450+ }
2451+
23992452static s32
24002453brcmf_cfg80211_get_station (struct wiphy * wiphy , struct net_device * ndev ,
24012454 const u8 * mac , struct station_info * sinfo )
24022455{
24032456 struct brcmf_if * ifp = netdev_priv (ndev );
2404- struct brcmf_cfg80211_profile * profile = & ifp -> vif -> profile ;
2405- struct brcmf_scb_val_le scb_val ;
2406- int rssi ;
2407- s32 rate ;
24082457 s32 err = 0 ;
2409- u8 * bssid = profile -> bssid ;
24102458 struct brcmf_sta_info_le sta_info_le ;
2411- u32 beacon_period ;
2412- u32 dtim_period ;
2459+ u32 sta_flags ;
2460+ u32 is_tdls_peer ;
24132461
24142462 brcmf_dbg (TRACE , "Enter, MAC %pM\n" , mac );
24152463 if (!check_vif_up (ifp -> vif ))
24162464 return - EIO ;
24172465
2418- if (brcmf_is_apmode (ifp -> vif )) {
2419- memcpy (& sta_info_le , mac , ETH_ALEN );
2466+ memset (& sta_info_le , 0 , sizeof (sta_info_le ));
2467+ memcpy (& sta_info_le , mac , ETH_ALEN );
2468+ err = brcmf_fil_iovar_data_get (ifp , "tdls_sta_info" ,
2469+ & sta_info_le ,
2470+ sizeof (sta_info_le ));
2471+ is_tdls_peer = !err ;
2472+ if (err ) {
24202473 err = brcmf_fil_iovar_data_get (ifp , "sta_info" ,
24212474 & sta_info_le ,
24222475 sizeof (sta_info_le ));
24232476 if (err < 0 ) {
24242477 brcmf_err ("GET STA INFO failed, %d\n" , err );
24252478 goto done ;
24262479 }
2427- sinfo -> filled = BIT (NL80211_STA_INFO_INACTIVE_TIME );
2428- sinfo -> inactive_time = le32_to_cpu (sta_info_le .idle ) * 1000 ;
2429- if (le32_to_cpu (sta_info_le .flags ) & BRCMF_STA_ASSOC ) {
2430- sinfo -> filled |= BIT (NL80211_STA_INFO_CONNECTED_TIME );
2431- sinfo -> connected_time = le32_to_cpu (sta_info_le .in );
2432- }
2433- brcmf_dbg (TRACE , "STA idle time : %d ms, connected time :%d sec\n" ,
2434- sinfo -> inactive_time , sinfo -> connected_time );
2435- } else if (ifp -> vif -> wdev .iftype == NL80211_IFTYPE_STATION ) {
2436- if (memcmp (mac , bssid , ETH_ALEN )) {
2437- brcmf_err ("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n" ,
2438- mac , bssid );
2439- err = - ENOENT ;
2440- goto done ;
2441- }
2442- /* Report the current tx rate */
2443- err = brcmf_fil_cmd_int_get (ifp , BRCMF_C_GET_RATE , & rate );
2444- if (err ) {
2445- brcmf_err ("Could not get rate (%d)\n" , err );
2446- goto done ;
2447- } else {
2480+ }
2481+ brcmf_dbg (TRACE , "version %d\n" , le16_to_cpu (sta_info_le .ver ));
2482+ sinfo -> filled = BIT (NL80211_STA_INFO_INACTIVE_TIME );
2483+ sinfo -> inactive_time = le32_to_cpu (sta_info_le .idle ) * 1000 ;
2484+ sta_flags = le32_to_cpu (sta_info_le .flags );
2485+ brcmf_convert_sta_flags (sta_flags , sinfo );
2486+ sinfo -> sta_flags .mask |= BIT (NL80211_STA_FLAG_TDLS_PEER );
2487+ if (is_tdls_peer )
2488+ sinfo -> sta_flags .set |= BIT (NL80211_STA_FLAG_TDLS_PEER );
2489+ else
2490+ sinfo -> sta_flags .set &= ~BIT (NL80211_STA_FLAG_TDLS_PEER );
2491+ if (sta_flags & BRCMF_STA_ASSOC ) {
2492+ sinfo -> filled |= BIT (NL80211_STA_INFO_CONNECTED_TIME );
2493+ sinfo -> connected_time = le32_to_cpu (sta_info_le .in );
2494+ brcmf_fill_bss_param (ifp , sinfo );
2495+ }
2496+ if (sta_flags & BRCMF_STA_SCBSTATS ) {
2497+ sinfo -> filled |= BIT (NL80211_STA_INFO_TX_FAILED );
2498+ sinfo -> tx_failed = le32_to_cpu (sta_info_le .tx_failures );
2499+ sinfo -> filled |= BIT (NL80211_STA_INFO_TX_PACKETS );
2500+ sinfo -> tx_packets = le32_to_cpu (sta_info_le .tx_pkts );
2501+ sinfo -> tx_packets += le32_to_cpu (sta_info_le .tx_mcast_pkts );
2502+ sinfo -> filled |= BIT (NL80211_STA_INFO_RX_PACKETS );
2503+ sinfo -> rx_packets = le32_to_cpu (sta_info_le .rx_ucast_pkts );
2504+ sinfo -> rx_packets += le32_to_cpu (sta_info_le .rx_mcast_pkts );
2505+ if (sinfo -> tx_packets ) {
24482506 sinfo -> filled |= BIT (NL80211_STA_INFO_TX_BITRATE );
2449- sinfo -> txrate .legacy = rate * 5 ;
2450- brcmf_dbg ( CONN , "Rate %d Mbps\n" , rate / 2 ) ;
2507+ sinfo -> txrate .legacy = le32_to_cpu ( sta_info_le . tx_rate ) ;
2508+ sinfo -> txrate . legacy /= 100 ;
24512509 }
2452-
2453- if (test_bit (BRCMF_VIF_STATUS_CONNECTED ,
2454- & ifp -> vif -> sme_state )) {
2455- memset (& scb_val , 0 , sizeof (scb_val ));
2456- err = brcmf_fil_cmd_data_get (ifp , BRCMF_C_GET_RSSI ,
2457- & scb_val , sizeof (scb_val ));
2458- if (err ) {
2459- brcmf_err ("Could not get rssi (%d)\n" , err );
2460- goto done ;
2461- } else {
2462- rssi = le32_to_cpu (scb_val .val );
2463- sinfo -> filled |= BIT (NL80211_STA_INFO_SIGNAL );
2464- sinfo -> signal = rssi ;
2465- brcmf_dbg (CONN , "RSSI %d dBm\n" , rssi );
2466- }
2467- err = brcmf_fil_cmd_int_get (ifp , BRCMF_C_GET_BCNPRD ,
2468- & beacon_period );
2469- if (err ) {
2470- brcmf_err ("Could not get beacon period (%d)\n" ,
2471- err );
2472- goto done ;
2473- } else {
2474- sinfo -> bss_param .beacon_interval =
2475- beacon_period ;
2476- brcmf_dbg (CONN , "Beacon peroid %d\n" ,
2477- beacon_period );
2478- }
2479- err = brcmf_fil_cmd_int_get (ifp , BRCMF_C_GET_DTIMPRD ,
2480- & dtim_period );
2481- if (err ) {
2482- brcmf_err ("Could not get DTIM period (%d)\n" ,
2483- err );
2484- goto done ;
2485- } else {
2486- sinfo -> bss_param .dtim_period = dtim_period ;
2487- brcmf_dbg (CONN , "DTIM peroid %d\n" ,
2488- dtim_period );
2489- }
2490- sinfo -> filled |= BIT (NL80211_STA_INFO_BSS_PARAM );
2510+ if (sinfo -> rx_packets ) {
2511+ sinfo -> filled |= BIT (NL80211_STA_INFO_RX_BITRATE );
2512+ sinfo -> rxrate .legacy = le32_to_cpu (sta_info_le .rx_rate );
2513+ sinfo -> rxrate .legacy /= 100 ;
24912514 }
2492- } else
2493- err = - EPERM ;
2515+ if (le16_to_cpu (sta_info_le .ver ) >= 4 ) {
2516+ sinfo -> filled |= BIT (NL80211_STA_INFO_TX_BYTES );
2517+ sinfo -> tx_bytes = le64_to_cpu (sta_info_le .tx_tot_bytes );
2518+ sinfo -> filled |= BIT (NL80211_STA_INFO_RX_BYTES );
2519+ sinfo -> rx_bytes = le64_to_cpu (sta_info_le .rx_tot_bytes );
2520+ }
2521+ }
24942522done :
24952523 brcmf_dbg (TRACE , "Exit\n" );
24962524 return err ;
0 commit comments