Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[deliverable/linux.git] / drivers / net / wireless / mwifiex / cfg80211.c
index 0170e87f7ca43bfa8a5896cd134875db1fe0dacf..c7a177c62625699444136b94a95479990b5a9b3b 100644 (file)
@@ -941,6 +941,42 @@ static int mwifiex_cfg80211_change_beacon(struct wiphy *wiphy,
        return 0;
 }
 
+static int
+mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
+{
+       struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
+       struct mwifiex_private *priv = mwifiex_get_priv(adapter,
+                                                       MWIFIEX_BSS_ROLE_ANY);
+       struct mwifiex_ds_ant_cfg ant_cfg;
+
+       if (!tx_ant || !rx_ant)
+               return -EOPNOTSUPP;
+
+       if (adapter->hw_dev_mcs_support != HT_STREAM_2X2) {
+               /* Not a MIMO chip. User should provide specific antenna number
+                * for Tx/Rx path or enable all antennas for diversity
+                */
+               if (tx_ant != rx_ant)
+                       return -EOPNOTSUPP;
+
+               if ((tx_ant & (tx_ant - 1)) &&
+                   (tx_ant != BIT(adapter->number_of_antenna) - 1))
+                       return -EOPNOTSUPP;
+
+               if ((tx_ant == BIT(adapter->number_of_antenna) - 1) &&
+                   (priv->adapter->number_of_antenna > 1)) {
+                       tx_ant = RF_ANTENNA_AUTO;
+                       rx_ant = RF_ANTENNA_AUTO;
+               }
+       }
+
+       ant_cfg.tx_ant = tx_ant;
+       ant_cfg.rx_ant = rx_ant;
+
+       return mwifiex_send_cmd_sync(priv, HostCmd_CMD_RF_ANTENNA,
+                                    HostCmd_ACT_GEN_SET, 0, &ant_cfg);
+}
+
 /* cfg80211 operation handler for stop ap.
  * Function stops BSS running at uAP interface.
  */
@@ -1726,6 +1762,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
        .stop_ap = mwifiex_cfg80211_stop_ap,
        .change_beacon = mwifiex_cfg80211_change_beacon,
        .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config,
+       .set_antenna = mwifiex_cfg80211_set_antenna,
 };
 
 /*
@@ -1772,7 +1809,14 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
 
        memcpy(wiphy->perm_addr, priv->curr_addr, ETH_ALEN);
        wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
-       wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
+       wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
+                       WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
+
+       wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
+                                   NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2;
+
+       wiphy->available_antennas_tx = BIT(adapter->number_of_antenna) - 1;
+       wiphy->available_antennas_rx = BIT(adapter->number_of_antenna) - 1;
 
        /* Reserve space for mwifiex specific private data for BSS */
        wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv);
@@ -1783,7 +1827,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
        wdev_priv = wiphy_priv(wiphy);
        *(unsigned long *)wdev_priv = (unsigned long)adapter;
 
-       set_wiphy_dev(wiphy, (struct device *)priv->adapter->dev);
+       set_wiphy_dev(wiphy, priv->adapter->dev);
 
        ret = wiphy_register(wiphy);
        if (ret < 0) {
This page took 0.026741 seconds and 5 git commands to generate.