Browse Source

qcacld-3.0: Reset wifi flag when wifi is turned off with static driver

qcacld-2.0 to qcacld-3.0 propagation

In case of static driver, upon wifi turn off module exit
doesn't happens. Module exit helps in cleanup of static memory.

If driver is loaded statically, at the time of driver unload,
wiphy flags are not cleared because of static memory.
Fix it by removing channel type as static.

Change-Id: I198ea87da3d160716a8c1c04b879ecb7c6f63180
CRs-Fixed: 944530
Abhishek Singh 9 years ago
parent
commit
f512bf3377

+ 55 - 4
core/hdd/src/wlan_hdd_cfg80211.c

@@ -158,7 +158,7 @@ static const u32 hdd_cipher_suites[] = {
 #endif
 };
 
-static struct ieee80211_channel hdd_channels_2_4_ghz[] = {
+static const struct ieee80211_channel hdd_channels_2_4_ghz[] = {
 	HDD2GHZCHAN(2412, 1, 0),
 	HDD2GHZCHAN(2417, 2, 0),
 	HDD2GHZCHAN(2422, 3, 0),
@@ -175,7 +175,7 @@ static struct ieee80211_channel hdd_channels_2_4_ghz[] = {
 	HDD2GHZCHAN(2484, 14, 0),
 };
 
-static struct ieee80211_channel hdd_channels_5_ghz[] = {
+static const struct ieee80211_channel hdd_channels_5_ghz[] = {
 	HDD5GHZCHAN(5180, 36, 0),
 	HDD5GHZCHAN(5200, 40, 0),
 	HDD5GHZCHAN(5220, 44, 0),
@@ -245,7 +245,7 @@ static struct ieee80211_rate a_mode_rates[] = {
 };
 
 static struct ieee80211_supported_band wlan_hdd_band_2_4_ghz = {
-	.channels = hdd_channels_2_4_ghz,
+	.channels = NULL,
 	.n_channels = ARRAY_SIZE(hdd_channels_2_4_ghz),
 	.band = IEEE80211_BAND_2GHZ,
 	.bitrates = g_mode_rates,
@@ -264,7 +264,7 @@ static struct ieee80211_supported_band wlan_hdd_band_2_4_ghz = {
 };
 
 static struct ieee80211_supported_band wlan_hdd_band_5_ghz = {
-	.channels = hdd_channels_5_ghz,
+	.channels = NULL,
 	.n_channels = ARRAY_SIZE(hdd_channels_5_ghz),
 	.band = IEEE80211_BAND_5GHZ,
 	.bitrates = a_mode_rates,
@@ -6034,9 +6034,38 @@ int wlan_hdd_cfg80211_init(struct device *dev,
 			~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
 	}
 
+	/*
+	 * In case of static linked driver at the time of driver unload,
+	 * module exit doesn't happens. Module cleanup helps in cleaning
+	 * of static memory.
+	 * If driver load happens statically, at the time of driver unload,
+	 * wiphy flags don't get reset because of static memory.
+	 * It's better not to store channel in static memory.
+	 */
 	wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_ghz;
+	wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
+		qdf_mem_malloc(sizeof(hdd_channels_2_4_ghz));
+	if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL) {
+		hdd_err("Not enough memory to allocate channels");
+		return -ENOMEM;
+	}
+	qdf_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
+			&hdd_channels_2_4_ghz[0],
+			sizeof(hdd_channels_2_4_ghz));
 	if (true == hdd_is_5g_supported(pHddCtx)) {
 		wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_ghz;
+		wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
+			qdf_mem_malloc(sizeof(hdd_channels_5_ghz));
+		if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL) {
+			hdd_err("Not enough memory to allocate channels");
+			qdf_mem_free(wiphy->
+				bands[IEEE80211_BAND_2GHZ]->channels);
+			wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
+			return -ENOMEM;
+		}
+		qdf_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
+			&hdd_channels_5_ghz[0],
+			sizeof(hdd_channels_5_ghz));
 	}
 
 	for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
@@ -6104,6 +6133,28 @@ int wlan_hdd_cfg80211_init(struct device *dev,
 	return 0;
 }
 
+/**
+ * wlan_hdd_cfg80211_deinit - Deinit cfg80211
+ * @ wiphy: the wiphy to validate against
+ *
+ * this function deinit cfg80211 and cleanup the
+ * memory allocated in wlan_hdd_cfg80211_init
+ *
+ * Return: void
+ */
+void wlan_hdd_cfg80211_deinit(struct wiphy *wiphy)
+{
+	int i;
+
+	for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
+		if (NULL != wiphy->bands[i] &&
+		   (NULL != wiphy->bands[i]->channels)) {
+			qdf_mem_free(wiphy->bands[i]->channels);
+			wiphy->bands[i]->channels = NULL;
+		}
+	}
+}
+
 /*
  * In this function, wiphy structure is updated after QDF
  * initialization. In wlan_hdd_cfg80211_init, only the

+ 2 - 0
core/hdd/src/wlan_hdd_cfg80211.h

@@ -2389,6 +2389,8 @@ int wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
 int wlan_hdd_cfg80211_init(struct device *dev,
 			   struct wiphy *wiphy, struct hdd_config *pCfg);
 
+void wlan_hdd_cfg80211_deinit(struct wiphy *wiphy);
+
 void wlan_hdd_update_wiphy(struct wiphy *wiphy, struct hdd_config *pCfg);
 
 int wlan_hdd_cfg80211_register(struct wiphy *wiphy);

+ 2 - 0
core/hdd/src/wlan_hdd_main.c

@@ -4191,6 +4191,7 @@ free_hdd_ctx:
 
 	wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
 	wiphy_unregister(wiphy);
+	wlan_hdd_cfg80211_deinit(wiphy);
 
 	hdd_context_destroy(hdd_ctx);
 }
@@ -6350,6 +6351,7 @@ err_ipa_cleanup:
 
 err_wiphy_unregister:
 	wiphy_unregister(hdd_ctx->wiphy);
+	wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy);
 
 err_cds_close:
 	status = cds_sched_close(hdd_ctx->pcds_context);

+ 1 - 0
core/hdd/src/wlan_hdd_power.c

@@ -1685,6 +1685,7 @@ err_cds_close:
 		pHddCtx->config = NULL;
 		wlan_hdd_deinit_tx_rx_histogram(pHddCtx);
 		wiphy_unregister(pHddCtx->wiphy);
+		wlan_hdd_cfg80211_deinit(pHddCtx->wiphy);
 		wiphy_free(pHddCtx->wiphy);
 
 		if (!QDF_IS_STATUS_SUCCESS(cds_deinit_policy_mgr())) {