[PATCH 5/7] bcmdhd: Enable Ad-Hoc (IBSS) mode

Ricardo Salveti de Araujo ricardo.salveti at canonical.com
Fri Jul 19 18:50:29 UTC 2013


From: Bruno Randolf <br1 at einfach.org>

This enables Ad-Hoc (IBSS) mode for bcmdhd. We basically just need to set the
interface flag and avoid some P2P specific settings while scanning.

Also add the "station get" command for IBSS mode.

Signed-off-by: Bruno Randolf <br1 at einfach.org>

Change-Id: I10a047f76495d7fedfee16d0ac10de239e494567
Signed-off-by: Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>

 1 file changed, 63 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index 2f28bf1..2796352 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -1614,7 +1614,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
 				 */
@@ -3064,7 +3064,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;
 }
 
@@ -4649,7 +4710,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;
-- 
1.8.3.2





More information about the kernel-team mailing list