Browse Source

qcacld-3.0: Convert open adapters to vtable map

Using a switch case as a method for mapping an enumerated value to a
handler function has the down side of allowing future changes to pollute
the switch case with additional logic. It also tends to lead to high
cyclomatic complexity. Avoid these issues in hdd_open_adapters_for_mode
by converting the switch case to a vtable.

Change-Id: If91cbaf1e0ed561122b599550f3c450ec47eda31
CRs-Fixed: 2335970
Dustin Brown 6 years ago
parent
commit
61cc393b74
1 changed files with 124 additions and 109 deletions
  1. 124 109
      core/hdd/src/wlan_hdd_main.c

+ 124 - 109
core/hdd/src/wlan_hdd_main.c

@@ -3360,16 +3360,13 @@ uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx)
 {
 	int i;
 
-	for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
-		if (0 == ((hdd_ctx->config->intfAddrMask) & (1 << i)))
-			break;
-	}
-
-	if (QDF_MAX_CONCURRENCY_PERSONA == i)
+	i = qdf_ffz(hdd_ctx->config->intfAddrMask);
+	if (i < 0 || i >= QDF_MAX_CONCURRENCY_PERSONA)
 		return NULL;
 
 	hdd_ctx->config->intfAddrMask |= (1 << i);
-	return &hdd_ctx->config->intfMacAddr[i].bytes[0];
+
+	return hdd_ctx->config->intfMacAddr[i].bytes;
 }
 
 void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx,
@@ -3379,8 +3376,8 @@ void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx,
 
 	for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
 		if (!memcmp(releaseAddr,
-			    &hdd_ctx->config->intfMacAddr[i].bytes[0],
-			    6)) {
+			    hdd_ctx->config->intfMacAddr[i].bytes,
+			    QDF_MAC_ADDR_SIZE)) {
 			hdd_ctx->config->intfAddrMask &= ~(1 << i);
 			break;
 		}
@@ -9140,77 +9137,89 @@ err_out:
 #ifdef WLAN_OPEN_P2P_INTERFACE
 /**
  * hdd_open_p2p_interface - Open P2P interface
- * @hdd_ctx:	HDD context
- * @rtnl_held:	True if RTNL lock held
- *
- * Open P2P interface during probe. This function called to open the P2P
- * interface at probe along with STA interface.
+ * @hdd_ctx: HDD context
  *
- * Return: 0 on success and errno on failure
+ * Return: QDF_STATUS
  */
-static int hdd_open_p2p_interface(struct hdd_context *hdd_ctx, bool rtnl_held)
+static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
 {
 	struct hdd_adapter *adapter;
-	uint8_t *p2p_dev_addr;
-	bool p2p_dev_addr_admin = false;
+	bool p2p_dev_addr_admin;
 
 	cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin);
+
 	if (p2p_dev_addr_admin &&
 	    !(hdd_ctx->config->intfMacAddr[0].bytes[0] & 0x02)) {
-		qdf_mem_copy(hdd_ctx->p2p_device_address.bytes,
-			     hdd_ctx->config->intfMacAddr[0].bytes,
-			     sizeof(tSirMacAddr));
+		hdd_ctx->p2p_device_address = hdd_ctx->config->intfMacAddr[0];
 
 		/*
-		 * Generate the P2P Device Address.  This consists of
+		 * Generate the P2P Device Address. This consists of
 		 * the device's primary MAC address with the locally
 		 * administered bit set.
 		 */
 		hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
 	} else {
+		uint8_t *p2p_dev_addr;
+
 		p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx);
-		if (p2p_dev_addr == NULL) {
-			hdd_err("Failed to allocate mac_address for p2p_device");
-			return -ENOSPC;
+		if (!p2p_dev_addr) {
+			hdd_err("Failed to get MAC address for new p2p device");
+			return QDF_STATUS_E_INVAL;
 		}
 
-		qdf_mem_copy(&hdd_ctx->p2p_device_address.bytes[0],
+		qdf_mem_copy(hdd_ctx->p2p_device_address.bytes,
 			     p2p_dev_addr, QDF_MAC_ADDR_SIZE);
 	}
 
 	adapter = hdd_open_adapter(hdd_ctx, QDF_P2P_DEVICE_MODE, "p2p%d",
-				   &hdd_ctx->p2p_device_address.bytes[0],
-				   NET_NAME_UNKNOWN, rtnl_held);
-
-	if (NULL == adapter) {
-		hdd_err("Failed to do hdd_open_adapter for P2P Device Interface");
-		return -ENOSPC;
+				   hdd_ctx->p2p_device_address.bytes,
+				   NET_NAME_UNKNOWN, true);
+	if (!adapter) {
+		hdd_err("Failed to open p2p interface");
+		return QDF_STATUS_E_INVAL;
 	}
 
-	return 0;
+	return QDF_STATUS_SUCCESS;
 }
 #else
-static inline int hdd_open_p2p_interface(struct hdd_context *hdd_ctx,
-					 bool rtnl_held)
+static inline QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
 {
-	return 0;
+	return QDF_STATUS_SUCCESS;
 }
 #endif
 
-static int hdd_open_ocb_interface(struct hdd_context *hdd_ctx, bool rtnl_held)
+static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx)
 {
 	struct hdd_adapter *adapter;
-	int ret = 0;
 
 	adapter = hdd_open_adapter(hdd_ctx, QDF_OCB_MODE, "wlanocb%d",
 				   wlan_hdd_get_intf_addr(hdd_ctx),
-				   NET_NAME_UNKNOWN, rtnl_held);
-	if (adapter == NULL) {
+				   NET_NAME_UNKNOWN, true);
+	if (!adapter) {
 		hdd_err("Failed to open 802.11p interface");
-		ret = -ENOSPC;
+		return QDF_STATUS_E_INVAL;
 	}
 
-	return ret;
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+
+	if (qdf_str_eq(hdd_ctx->config->enableConcurrentSTA, ""))
+		return QDF_STATUS_SUCCESS;
+
+	adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE,
+				   hdd_ctx->config->enableConcurrentSTA,
+				   wlan_hdd_get_intf_addr(hdd_ctx),
+				   NET_NAME_UNKNOWN, true);
+	if (!adapter) {
+		hdd_err("Failed to open concurrent station interface");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return QDF_STATUS_SUCCESS;
 }
 
 /**
@@ -9321,22 +9330,6 @@ int hdd_start_ap_adapter(struct hdd_adapter *adapter)
 	return 0;
 }
 
-static int hdd_open_concurrent_interface(struct hdd_context *hdd_ctx,
-								bool rtnl_held)
-{
-	struct hdd_adapter *adapter;
-
-	adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE,
-				       hdd_ctx->config->enableConcurrentSTA,
-				       wlan_hdd_get_intf_addr(hdd_ctx),
-				       NET_NAME_UNKNOWN, rtnl_held);
-
-	if (!adapter)
-		return -ENOSPC;
-
-	return 0;
-}
-
 #ifdef QCA_LL_TX_FLOW_CONTROL_V2
 /**
  * hdd_txrx_populate_cds_config() - Populate txrx cds configuration
@@ -11260,102 +11253,124 @@ static int wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
 }
 #endif
 
-static int hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx)
+static QDF_STATUS
+hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx)
 {
 	struct hdd_adapter *adapter;
 	enum dot11p_mode dot11p_mode;
-	int errno;
+	QDF_STATUS status;
 
 	ucfg_mlme_get_dot11p_mode(hdd_ctx->psoc, &dot11p_mode);
 
 	/* Create only 802.11p interface? */
 	if (dot11p_mode == CFG_11P_STANDALONE)
-		return hdd_open_ocb_interface(hdd_ctx, true);
+		return hdd_open_ocb_interface(hdd_ctx);
 
 	adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE, "wlan%d",
 				   wlan_hdd_get_intf_addr(hdd_ctx),
 				   NET_NAME_UNKNOWN, true);
 	if (!adapter)
-		return -EINVAL;
+		return QDF_STATUS_E_INVAL;
 
-	if (strlen(hdd_ctx->config->enableConcurrentSTA)) {
-		errno = hdd_open_concurrent_interface(hdd_ctx, true);
-		if (errno)
-			hdd_err("Cannot create concurrent STA interface");
-	}
+	/* opening concurrent STA is best effort, continue on error */
+	hdd_open_concurrent_interface(hdd_ctx);
 
-	errno = hdd_open_p2p_interface(hdd_ctx, true);
-	if (errno)
+	status = hdd_open_p2p_interface(hdd_ctx);
+	if (status)
 		goto err_close_adapters;
 
 	/* Open 802.11p Interface */
 	if (dot11p_mode == CFG_11P_CONCURRENT) {
-		errno = hdd_open_ocb_interface(hdd_ctx, true);
-		if (errno)
+		status = hdd_open_ocb_interface(hdd_ctx);
+		if (QDF_IS_STATUS_ERROR(status))
 			goto err_close_adapters;
 	}
 
-	return 0;
+	return QDF_STATUS_SUCCESS;
 
 err_close_adapters:
 	hdd_close_all_adapters(hdd_ctx, true);
 
-	return errno;
+	return status;
 }
 
-static int hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx,
-				      enum QDF_GLOBAL_MODE mode)
+static QDF_STATUS hdd_open_adapters_for_ftm_mode(struct hdd_context *hdd_ctx)
 {
 	struct hdd_adapter *adapter;
-	qdf_device_t qdf_dev;
+
+	adapter = hdd_open_adapter(hdd_ctx, QDF_FTM_MODE, "wlan%d",
+				   wlan_hdd_get_intf_addr(hdd_ctx),
+				   NET_NAME_UNKNOWN, true);
+
+	return adapter ? QDF_STATUS_SUCCESS : QDF_STATUS_E_INVAL;
+}
+
+static QDF_STATUS
+hdd_open_adapters_for_monitor_mode(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+
+	adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, "wlan%d",
+				   wlan_hdd_get_intf_addr(hdd_ctx),
+				   NET_NAME_UNKNOWN, true);
+
+	return adapter ? QDF_STATUS_SUCCESS : QDF_STATUS_E_INVAL;
+}
+
+static QDF_STATUS hdd_open_adapters_for_epping_mode(struct hdd_context *hdd_ctx)
+{
 	QDF_STATUS status;
-	int errno;
+	qdf_device_t qdf_dev;
 
 	qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
 	QDF_BUG(qdf_dev);
 	if (!qdf_dev)
-		return -EINVAL;
+		return QDF_STATUS_E_INVAL;
 
-	hdd_hold_rtnl_lock();
-	switch (mode) {
-	case QDF_GLOBAL_MISSION_MODE:
-		errno = hdd_open_adapters_for_mission_mode(hdd_ctx);
+	status = epping_open();
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
 
-		break;
-	case QDF_GLOBAL_FTM_MODE:
-		adapter = hdd_open_adapter(hdd_ctx, QDF_FTM_MODE, "wlan%d",
-					   wlan_hdd_get_intf_addr(hdd_ctx),
-					   NET_NAME_UNKNOWN, true);
-		errno = adapter ? 0 : -EINVAL;
+	if (epping_enable(qdf_dev->dev)) {
+		status = QDF_STATUS_E_INVAL;
+		goto epping_close;
+	}
 
-		break;
-	case QDF_GLOBAL_MONITOR_MODE:
-		adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, "wlan%d",
-					   wlan_hdd_get_intf_addr(hdd_ctx),
-					   NET_NAME_UNKNOWN, true);
-		errno = adapter ? 0 : -EINVAL;
+	return QDF_STATUS_SUCCESS;
 
-		break;
-	case QDF_GLOBAL_EPPING_MODE:
-		status = epping_open();
-		errno = qdf_status_to_os_return(status);
-		if (errno)
-			break;
+epping_close:
+	epping_close();
+
+	return status;
+}
 
-		errno = epping_enable(qdf_dev->dev);
-		if (errno)
-			epping_close();
+typedef QDF_STATUS (*hdd_open_mode_handler)(struct hdd_context *hdd_ctx);
 
-		break;
-	default:
-		hdd_err("Mode not supported");
-		errno = -ENOTSUPP;
+static const hdd_open_mode_handler
+hdd_open_mode_handlers[QDF_GLOBAL_MAX_MODE] = {
+	[QDF_GLOBAL_MISSION_MODE] = hdd_open_adapters_for_mission_mode,
+	[QDF_GLOBAL_FTM_MODE] = hdd_open_adapters_for_ftm_mode,
+	[QDF_GLOBAL_MONITOR_MODE] = hdd_open_adapters_for_monitor_mode,
+	[QDF_GLOBAL_EPPING_MODE] = hdd_open_adapters_for_epping_mode,
+};
 
-		break;
+static int hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx,
+				      enum QDF_GLOBAL_MODE driver_mode)
+{
+	QDF_STATUS status;
+
+	if (driver_mode < 0 ||
+	    driver_mode >= QDF_GLOBAL_MAX_MODE ||
+	    !hdd_open_mode_handlers[driver_mode]) {
+		hdd_err("Driver mode %d not supported", driver_mode);
+		return -ENOTSUPP;
 	}
+
+	hdd_hold_rtnl_lock();
+	status = hdd_open_mode_handlers[driver_mode](hdd_ctx);
 	hdd_release_rtnl_lock();
 
-	return errno;
+	return qdf_status_to_os_return(status);
 }
 
 /**