Browse Source

qcacmn: Move qdf_nbuf_map call to after adding HTT header

Remove the dependency of dma_map for align_pad calculation
move the dma_map to correct position after mesh mode header addition

Change-Id: Idd309ed47d82f68f97191048c582c1b429f3b378
CRs-Fixed: 2004658
Pamidipati, Vijay 8 years ago
parent
commit
8a4e27cd59
1 changed files with 55 additions and 65 deletions
  1. 55 65
      dp/wifi3.0/dp_tx.c

+ 55 - 65
dp/wifi3.0/dp_tx.c

@@ -126,30 +126,6 @@ dp_tx_desc_release(struct dp_tx_desc_s *tx_desc, uint8_t desc_pool_id)
  * dp_tx_htt_metadata_prepare() - Prepare HTT metadata for special frames
  * @vdev: DP vdev Handle
  * @nbuf: skb
- * @align_pad: Alignment Pad bytes to be pushed in headroom before adding
- * HTT metadata
- *
- *  |-----------------------------|
- *  |                             |
- *  |-----------------------------| <-----Buffer Pointer Address given
- *  |                             |  ^    in HW descriptor (aligned)
- *  |                             |  |
- *  |       HTT Metadata          |  |
- *  |                             |  |
- *  |                             |  | Packet Offset given in descriptor
- *  |                             |  |
- *  |                             |  |
- *  |-----------------------------|  |
- *  |       Alignment Pad         |  v
- *  |-----------------------------| <----- Actual buffer start address
- *  |        SKB Data             |           (Unaligned)
- *  |                             |
- *  |                             |
- *  |                             |
- *  |                             |
- *  |                             |
- *  |                             |
- *  |-----------------------------|
  *
  * Prepares and fills HTT metadata in the frame pre-header for special frames
  * that should be transmitted using varying transmit parameters.
@@ -161,11 +137,15 @@ dp_tx_desc_release(struct dp_tx_desc_s *tx_desc, uint8_t desc_pool_id)
  *
  */
 static uint8_t dp_tx_prepare_htt_metadata(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
-		uint8_t align_pad, uint32_t *meta_data)
+		uint32_t *meta_data)
 {
 	struct htt_tx_msdu_desc_ext2_t *desc_ext =
 				(struct htt_tx_msdu_desc_ext2_t *) meta_data;
-	uint8_t htt_desc_size  = 0;
+
+	uint8_t htt_desc_size;
+
+	/* Size rounded of multiple of 8 bytes */
+	uint8_t htt_desc_size_aligned;
 
 	uint8_t *hdr = NULL;
 
@@ -177,30 +157,19 @@ static uint8_t dp_tx_prepare_htt_metadata(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
 	 * Metadata - HTT MSDU Extension header
 	 */
 	htt_desc_size = sizeof(struct htt_tx_msdu_desc_ext2_t);
+	htt_desc_size_aligned = (htt_desc_size + 7) & ~0x7;
 
 	if (vdev->mesh_vdev) {
+
 		/* Fill and add HTT metaheader */
-		hdr = qdf_nbuf_push_head(nbuf, htt_desc_size + align_pad);
+		hdr = qdf_nbuf_push_head(nbuf, htt_desc_size_aligned);
 		qdf_mem_copy(hdr, desc_ext, htt_desc_size);
 
-		if (qdf_unlikely(QDF_STATUS_SUCCESS !=
-					qdf_nbuf_map_nbytes_single(
-						vdev->pdev->soc->osdev, nbuf,
-						QDF_DMA_TO_DEVICE,
-						(htt_desc_size + align_pad)))) {
-
-			/* Handle failure */
-			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
-					"htt qdf_nbuf_map failed\n");
-
-			return 0;
-		}
-
 	} else if (vdev->opmode == wlan_op_mode_ocb) {
 		/* Todo - Add support for DSRC */
 	}
 
-	return htt_desc_size;
+	return htt_desc_size_aligned;
 }
 
 /**
@@ -434,16 +403,17 @@ struct dp_tx_desc_s *dp_tx_prepare_desc_single(struct dp_vdev *vdev,
 	tx_desc->pdev = pdev;
 	tx_desc->msdu_ext_desc = NULL;
 
-	if (qdf_unlikely(QDF_STATUS_SUCCESS !=
-				qdf_nbuf_map(soc->osdev, nbuf,
-				QDF_DMA_TO_DEVICE))) {
-		/* Handle failure */
-		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
-				"qdf_nbuf_map failed\n");
-		goto failure;
-	}
-
-	align_pad = ((unsigned long) qdf_nbuf_mapped_paddr_get(nbuf)) & 0x7;
+	/**
+	 * For non-scatter regular frames, buffer pointer is directly
+	 * programmed in TCL input descriptor instead of using an MSDU
+	 * extension descriptor.For this cass, HW requirement is that
+	 * descriptor should always point to a 8-byte aligned address.
+	 *
+	 * So we add alignment pad to start of buffer, and specify the actual
+	 * start of data through pkt_offset
+	 */
+	align_pad = ((unsigned long) qdf_nbuf_data(nbuf)) & 0x7;
+	qdf_nbuf_push_head(nbuf, align_pad);
 	tx_desc->pkt_offset = align_pad;
 
 	/*
@@ -452,16 +422,47 @@ struct dp_tx_desc_s *dp_tx_prepare_desc_single(struct dp_vdev *vdev,
 	 * transmit rate, power, priority, channel, channel bandwidth , nss etc.
 	 * These are filled in HTT MSDU descriptor and sent in frame pre-header.
 	 * These frames are sent as exception packets to firmware.
+	 *
+	 *  HTT Metadata should be ensured to be multiple of 8-bytes,
+	 *  to get 8-byte aligned start address along with align_pad added above
+	 *
+	 *  |-----------------------------|
+	 *  |                             |
+	 *  |-----------------------------| <-----Buffer Pointer Address given
+	 *  |                             |  ^    in HW descriptor (aligned)
+	 *  |       HTT Metadata          |  |
+	 *  |                             |  |
+	 *  |                             |  | Packet Offset given in descriptor
+	 *  |                             |  |
+	 *  |-----------------------------|  |
+	 *  |       Alignment Pad         |  v
+	 *  |-----------------------------| <----- Actual buffer start address
+	 *  |        SKB Data             |           (Unaligned)
+	 *  |                             |
+	 *  |                             |
+	 *  |                             |
+	 *  |                             |
+	 *  |                             |
+	 *  |-----------------------------|
 	 */
 	if (qdf_unlikely(vdev->mesh_vdev ||
 				(vdev->opmode == wlan_op_mode_ocb))) {
 		htt_hdr_size = dp_tx_prepare_htt_metadata(vdev, nbuf,
-				align_pad, meta_data);
+				meta_data);
 		tx_desc->pkt_offset += htt_hdr_size;
 		tx_desc->flags |= DP_TX_DESC_FLAG_TO_FW;
 		is_exception = 1;
 	}
 
+	if (qdf_unlikely(QDF_STATUS_SUCCESS !=
+				qdf_nbuf_map(soc->osdev, nbuf,
+					QDF_DMA_TO_DEVICE))) {
+		/* Handle failure */
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+				"qdf_nbuf_map failed\n");
+		goto failure;
+	}
+
 	if (qdf_unlikely(vdev->nawds_enabled)) {
 		eh = (struct ether_header *) qdf_nbuf_data(nbuf);
 		if (DP_FRAME_IS_MULTICAST((eh)->ether_dhost)) {
@@ -652,22 +653,11 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev,
 		type = HAL_TX_BUF_TYPE_EXT_DESC;
 		dma_addr = tx_desc->msdu_ext_desc->paddr;
 	} else {
-		length = qdf_nbuf_len(tx_desc->nbuf);
+		length = qdf_nbuf_len(tx_desc->nbuf) - tx_desc->pkt_offset;
 		type = HAL_TX_BUF_TYPE_BUFFER;
-
-		/**
-		 * For non-scatter regular frames, buffer pointer is directly
-		 * programmed in TCL input descriptor instead of using an MSDU
-		 * extension descriptor.For the direct buffer pointer case, HW
-		 * requirement is that descriptor should always point to a
-		 * 8-byte aligned address.
-		 * Alignment padding is already accounted in pkt_offset
-		 *
-		 */
-		dma_addr = (qdf_nbuf_mapped_paddr_get(tx_desc->nbuf) & ~0x7);
+		dma_addr = qdf_nbuf_mapped_paddr_get(tx_desc->nbuf);
 	}
 
-
 	hal_tx_desc_set_fw_metadata(hal_tx_desc_cached, fw_metadata);
 	hal_tx_desc_set_buf_addr(hal_tx_desc_cached,
 			dma_addr , bm_id, tx_desc->id, type);