aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.c65
1 files changed, 63 insertions, 2 deletions
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index 3b9ca46..30e7006 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -1616,7 +1616,7 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
WL_DBG(("P2P: GO_NEG_PHASE status cleared \n"));
p2p_scan(wl) = true;
}
- } else {
+ } else if (wl_get_mode_by_netdev(wl, ndev) != WL_MODE_IBSS) {
/* legacy scan trigger
* So, we have to disable p2p discovery if p2p discovery is on
*/
@@ -3068,7 +3068,68 @@ get_station_err:
wl_link_down(wl);
}
}
+ else if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_IBSS) {
+ u8 *curmacp = wl_read_prof(wl, dev, WL_PROF_BSSID);
+
+ memset(&scb_val, 0, sizeof(scb_val));
+ bcopy(mac, &scb_val.ea, 6);
+
+ err = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val,
+ sizeof(scb_val_t), false);
+ if (err) {
+ WL_ERR(("Could not get rssi (%d)\n", err));
+ return err;
+ }
+ rssi = dtoh32(scb_val.val);
+
+ /* the RSSI value from the firmware is an average but user-space
+ expects it as signal, so we fill in both */
+ sinfo->filled |= STATION_INFO_SIGNAL;
+ sinfo->signal = rssi;
+ sinfo->filled |= STATION_INFO_SIGNAL_AVG;
+ sinfo->signal_avg = rssi;
+
+ if (!memcmp(mac, curmacp, ETHER_ADDR_LEN)) {
+ // BSSID is not a real station. Can't get sta_info; Done
+ return 0;
+ }
+ err = wldev_iovar_getbuf(dev, "sta_info", (struct ether_addr *)mac,
+ ETHER_ADDR_LEN, wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
+ if (err < 0) {
+ WL_ERR(("GET STA INFO failed, %d\n", err));
+ return err;
+ }
+
+ sta = (sta_info_t *)wl->ioctl_buf;
+ sta->len = dtoh16(sta->len);
+ sta->cap = dtoh16(sta->cap);
+ sta->flags = dtoh32(sta->flags);
+ sta->idle = dtoh32(sta->idle);
+ sta->in = dtoh32(sta->in);
+ sta->listen_interval_inms = dtoh32(sta->listen_interval_inms);
+ sta->tx_pkts = dtoh32(sta->tx_pkts);
+ sta->tx_failures = dtoh32(sta->tx_failures);
+ sta->rx_ucast_pkts = dtoh32(sta->rx_ucast_pkts);
+ sta->rx_mcast_pkts = dtoh32(sta->rx_mcast_pkts);
+ sta->tx_rate = dtoh32(sta->tx_rate);
+ sta->rx_rate = dtoh32(sta->rx_rate);
+ sta->rx_decrypt_succeeds = dtoh32(sta->rx_decrypt_succeeds);
+ sta->rx_decrypt_failures = dtoh32(sta->rx_decrypt_failures);
+
+ sinfo->filled |= STATION_INFO_INACTIVE_TIME | STATION_INFO_TX_PACKETS |
+ STATION_INFO_TX_FAILED | STATION_INFO_RX_PACKETS |
+ STATION_INFO_TX_BITRATE | STATION_INFO_RX_BITRATE |
+ STATION_INFO_RX_DROP_MISC;
+
+ sinfo->inactive_time = sta->idle * 1000;
+ sinfo->tx_packets = sta->tx_pkts;
+ sinfo->tx_failed = sta->tx_failures;
+ sinfo->rx_packets = sta->rx_ucast_pkts + sta->rx_mcast_pkts;
+ sinfo->txrate.legacy = sta->tx_rate / 100;
+ sinfo->rxrate.legacy = sta->rx_rate / 100;
+ sinfo->rx_dropped_misc = sta->rx_decrypt_failures;
+ }
return err;
}
@@ -4653,7 +4714,7 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev
wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
#endif /* WL_SCHED_SCAN */
wdev->wiphy->interface_modes =
- BIT(NL80211_IFTYPE_STATION)
+ BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC)
| BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR);
wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;