[NEUS7920-477] [9610] wlbt: API for configuraing number of antennas
authordujeonglee <dujeong.lee@samsung.com>
Fri, 19 Apr 2019 02:51:31 +0000 (11:51 +0900)
committerKim Gunho <gunho.kim@samsung.com>
Fri, 28 Jun 2019 14:46:21 +0000 (23:46 +0900)
Support runtime change for number of antennas.

Change-Id: I0297a1a0c6ef382c8e089dcc259a68a4fc3a8a25
SCSC-Bug-Id: SSB-51894
Signed-off-by: dujeonglee <dujeong.lee@samsung.com>
drivers/net/wireless/scsc/Kconfig
drivers/net/wireless/scsc/cfg80211_ops.c
drivers/net/wireless/scsc/ioctl.c
drivers/net/wireless/scsc/mgt.c
drivers/net/wireless/scsc/mgt.h

index 64357e5bf90279213a926ee1c3dd1f21d29decb7..ce055300ece4988e1e869ebc5c3fb829e8c3b6cb 100755 (executable)
@@ -222,3 +222,9 @@ config SCSC_WIFI_NAN_ENABLE
         default n
         ---help---
           This option tells whether WiFi NAN is enabled or not.
+
+config SCSC_WLAN_SET_NUM_ANTENNAS
+        bool "Enable configuring of number of antennas"
+        default n
+        ---help---
+          This option tells whether configuring of number of antennas is enabled or not.
index 5379435cf9ed77806e49d9520bfe4ece1b27b230..8faf308087a7b8154ef438cac590d845e0e9dd5b 100755 (executable)
@@ -2386,7 +2386,6 @@ int slsi_start_ap(struct wiphy *wiphy, struct net_device *dev,
        if (SLSI_IS_VIF_INDEX_MHS(sdev, ndev_vif))
                ndev_vif->chan = settings->chandef.chan;
 #endif
-
        if (r != 0) {
                SLSI_NET_ERR(dev, "Start ap failed: resultcode = %d frequency = %d\n", r,
                             settings->chandef.chan->center_freq);
@@ -2394,7 +2393,12 @@ int slsi_start_ap(struct wiphy *wiphy, struct net_device *dev,
        } else if (ndev_vif->iftype == NL80211_IFTYPE_P2P_GO) {
                SLSI_P2P_STATE_CHANGE(sdev, P2P_GROUP_FORMED_GO);
        }
-
+#ifdef CONFIG_SCSC_WLAN_SET_NUM_ANTENNAS
+       if (ndev_vif->iftype == NL80211_IFTYPE_AP) {
+               /* Don't care results. */
+               slsi_set_num_antennas(dev, 1 /*SISO*/);
+       }
+#endif
        ndev_vif->ap.beacon_interval = settings->beacon_interval;
        ndev_vif->ap.ssid_len = settings->ssid_len;
        memcpy(ndev_vif->ap.ssid, settings->ssid, settings->ssid_len);
index 2466a4d050d1eadab1b0e3aee726e4f133d08603..f1e2b0a89e8cd288f6611c01248521214fb291e7 100755 (executable)
 #define CMD_SET_TX_POWER_SAR "SET_TX_POWER_SAR"
 #define CMD_GET_TX_POWER_SAR "GET_TX_POWER_SAR"
 
+#ifdef CONFIG_SCSC_WLAN_SET_NUM_ANTENNAS
+#define CMD_SET_NUM_ANTENNAS "SET_NUM_ANTENNAS"
+#endif
+
 #define ROAMOFFLAPLIST_MIN 1
 #define ROAMOFFLAPLIST_MAX 100
 
@@ -2530,6 +2534,17 @@ int slsi_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 #else
                ret = mx140_log_dump();
 #endif
+#endif
+#ifdef CONFIG_SCSC_WLAN_SET_NUM_ANTENNAS
+       } else if (strncasecmp(command, CMD_SET_NUM_ANTENNAS, strlen(CMD_SET_NUM_ANTENNAS)) == 0) {
+               struct netdev_vif *ndev_vif = netdev_priv(dev);
+               const u16 num_of_antennas = *(command + strlen(CMD_SET_NUM_ANTENNAS) + 1) - '0';
+
+               /* We cannot lock in slsi_set_num_antennas as
+                  this is also called in slsi_start_ap with netdev_vif lock. */
+               SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
+               ret = slsi_set_num_antennas(dev, num_of_antennas);
+               SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
 #endif
        } else {
                ret  = -ENOTSUPP;
index b4686df6e802349fe9518c540948d07bff3830f5..2b5394cddcf2c25e2d012a02b0f40e808015d8be 100755 (executable)
@@ -5511,3 +5511,48 @@ int slsi_find_chan_idx(u16 chan, u8 hw_mode)
        }
        return idx;
 }
+
+#ifdef CONFIG_SCSC_WLAN_SET_NUM_ANTENNAS
+/* Note : netdev_vif lock should be taken care by caller. */
+int slsi_set_num_antennas(struct net_device *dev, const u16 num_of_antennas)
+{
+       struct netdev_vif *ndev_vif = netdev_priv(dev);
+       struct slsi_dev   *sdev = ndev_vif->sdev;
+       struct sk_buff    *req;
+       struct sk_buff    *cfm;
+       int               ret = 0;
+       const bool        is_sta = (ndev_vif->iftype == NL80211_IFTYPE_STATION);
+       const bool        is_softap = (ndev_vif->iftype == NL80211_IFTYPE_AP);
+
+       WARN_ON(!SLSI_MUTEX_IS_LOCKED(ndev_vif->vif_mutex));
+
+       if (num_of_antennas > 2 || num_of_antennas == 0) {
+               SLSI_NET_ERR(dev, "Invalid num_of_antennas %hu\n", num_of_antennas);
+               return -EINVAL;
+       }
+       if (!is_sta && !is_softap) {
+               SLSI_NET_ERR(dev, "Invalid interface type %s\n", dev->name);
+               return -EPERM;
+       }
+       if (is_sta && (ndev_vif->sta.vif_status != SLSI_VIF_STATUS_CONNECTED)) {
+               SLSI_NET_ERR(dev, "sta is not in connected state\n");
+               return -EPERM;
+       }
+       SLSI_NET_INFO(dev, "mlme_set_num_antennas_req(vif:%u num_of_antennas:%u)\n", ndev_vif->ifnum, num_of_antennas);
+       /* TODO: Change signal name to MLME_SET_NUM_ANTENNAS_REQ and MLME_SET_NUM_ANTENNAS_CFM. */
+       req = fapi_alloc(mlme_set_nss_req, MLME_SET_NSS_REQ, ndev_vif->ifnum, 0);
+       fapi_set_u16(req, u.mlme_set_nss_req.vif, ndev_vif->ifnum);
+       fapi_set_u16(req, u.mlme_set_nss_req.rx_nss, num_of_antennas);
+       cfm = slsi_mlme_req_cfm(sdev, dev, req, MLME_SET_NSS_CFM);
+       if (!cfm)
+               return -EIO;
+
+       if (fapi_get_u16(cfm, u.mlme_set_nss_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) {
+               SLSI_NET_ERR(dev, "mlme_set_nss_cfm(result:0x%04x) ERROR\n",
+                            fapi_get_u16(cfm, u.mlme_set_nss_cfm.result_code));
+               ret = -EINVAL;
+       }
+       slsi_kfree_skb(cfm);
+       return ret;
+}
+#endif
index b18e80974872e42ee47c422df840d36911415a70..7f43994996261359fb1ad2b8a95990c05fd27135 100755 (executable)
@@ -528,5 +528,7 @@ void slsi_wlan_dump_public_action_subtype(struct slsi_dev *sdev, struct ieee8021
 void slsi_reset_channel_flags(struct slsi_dev *sdev);
 
 int slsi_find_chan_idx(u16 chan, u8 hw_mode);
-
+#ifdef CONFIG_SCSC_WLAN_SET_NUM_ANTENNAS
+int slsi_set_num_antennas(struct net_device *dev, const u16 num_of_antennas);
+#endif
 #endif /*__SLSI_MGT_H__*/