Ver código fonte

qcacld-3.0: Handle multiple map/unmap handler for same peer_id

Handle multiple map/unmap handler from firmware
for same peer_id. Firmware sends map/unmap event
per copy engine enabled for RX path.

CRs-Fixed: 1009289
Change-Id: Id8b0c27920a7aae95ddd4cff26731de85248457e
Nirav Shah 9 anos atrás
pai
commit
f099e5e180

+ 15 - 5
core/dp/txrx/ol_txrx_peer_find.c

@@ -346,7 +346,13 @@ ol_txrx_peer_find_add_id(struct ol_txrx_pdev_t *pdev,
 	if (peer) {
 		/* peer's ref count was already incremented by
 		   peer_find_hash_find */
-		pdev->peer_id_to_obj_map[peer_id] = peer;
+		if (!pdev->peer_id_to_obj_map[peer_id].peer) {
+			pdev->peer_id_to_obj_map[peer_id].peer = peer;
+			qdf_atomic_init
+			  (&pdev->peer_id_to_obj_map[peer_id].peer_id_ref_cnt);
+		}
+		qdf_atomic_inc
+			(&pdev->peer_id_to_obj_map[peer_id].peer_id_ref_cnt);
 		/*
 		 * remove the reference added in ol_txrx_peer_find_hash_find.
 		 * the reference for the first peer id is already added in
@@ -408,11 +414,15 @@ void ol_rx_peer_unmap_handler(ol_txrx_pdev_handle pdev, uint16_t peer_id)
 {
 	struct ol_txrx_peer_t *peer;
 	peer = (peer_id == HTT_INVALID_PEER) ? NULL :
-	       pdev->peer_id_to_obj_map[peer_id];
+	       pdev->peer_id_to_obj_map[peer_id].peer;
 	TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1,
 		   "%s: peer %p with ID %d to be unmapped.\n", __func__, peer,
 		   peer_id);
-	pdev->peer_id_to_obj_map[peer_id] = NULL;
+
+	if (qdf_atomic_dec_and_test
+		(&pdev->peer_id_to_obj_map[peer_id].peer_id_ref_cnt)) {
+		pdev->peer_id_to_obj_map[peer_id].peer = NULL;
+	}
 	/*
 	 * Currently peer IDs are assigned for vdevs as well as peers.
 	 * If the peer ID is for a vdev, then the peer pointer stored
@@ -461,11 +471,11 @@ void ol_txrx_peer_find_display(ol_txrx_pdev_handle pdev, int indent)
 		  "%*speer map:\n", indent, " ");
 	max_peers = ol_cfg_max_peer_id(pdev->ctrl_pdev) + 1;
 	for (i = 0; i < max_peers; i++) {
-		if (pdev->peer_id_to_obj_map[i]) {
+		if (pdev->peer_id_to_obj_map[i].peer) {
 			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
 				  "%*sid %d -> %p\n",
 				  indent + 4, " ", i,
-				  pdev->peer_id_to_obj_map[i]);
+				  pdev->peer_id_to_obj_map[i].peer);
 		}
 	}
 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,

+ 2 - 2
core/dp/txrx/ol_txrx_peer_find.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, 2015-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -63,7 +63,7 @@ struct ol_txrx_peer_t *ol_txrx_peer_find_by_id(struct ol_txrx_pdev_t *pdev,
 {
 	struct ol_txrx_peer_t *peer;
 	peer = (peer_id > ol_cfg_max_peer_id(pdev->ctrl_pdev)) ? NULL :
-	       pdev->peer_id_to_obj_map[peer_id];
+	       pdev->peer_id_to_obj_map[peer_id].peer;
 	/*
 	 * Currently, peer IDs are assigned to vdevs as well as peers.
 	 * If the peer ID is for a vdev, the peer_id_to_obj_map entry

+ 6 - 1
core/dp/txrx/ol_txrx_types.h

@@ -386,6 +386,11 @@ struct ol_tx_flow_pool_t {
 
 #endif
 
+struct ol_txrx_peer_id_map {
+	struct ol_txrx_peer_t *peer;
+	qdf_atomic_t peer_id_ref_cnt;
+};
+
 /*
  * As depicted in the diagram below, the pdev contains an array of
  * NUM_EXT_TID ol_tx_active_queues_in_tid_t elements.
@@ -504,7 +509,7 @@ struct ol_txrx_pdev_t {
 	TAILQ_HEAD(, ol_txrx_vdev_t) vdev_list;
 
 	/* peer ID to peer object map (array of pointers to peer objects) */
-	struct ol_txrx_peer_t **peer_id_to_obj_map;
+	struct ol_txrx_peer_id_map *peer_id_to_obj_map;
 
 	struct {
 		unsigned mask;