Ejemplo n.º 1
0
struct ol_tx_desc_t *ol_tx_desc_ll(struct ol_txrx_pdev_t *pdev,
				   struct ol_txrx_vdev_t *vdev,
				   cdf_nbuf_t netbuf,
				   struct ol_txrx_msdu_info_t *msdu_info)
{
	struct ol_tx_desc_t *tx_desc;
	unsigned int i;
	uint32_t num_frags;

	msdu_info->htt.info.vdev_id = vdev->vdev_id;
	msdu_info->htt.action.cksum_offload = cdf_nbuf_get_tx_cksum(netbuf);
	switch (cdf_nbuf_get_exemption_type(netbuf)) {
	case CDF_NBUF_EXEMPT_NO_EXEMPTION:
	case CDF_NBUF_EXEMPT_ON_KEY_MAPPING_KEY_UNAVAILABLE:
		/* We want to encrypt this frame */
		msdu_info->htt.action.do_encrypt = 1;
		break;
	case CDF_NBUF_EXEMPT_ALWAYS:
		/* We don't want to encrypt this frame */
		msdu_info->htt.action.do_encrypt = 0;
		break;
	default:
		cdf_assert(0);
		break;
	}

	/* allocate the descriptor */
	tx_desc = ol_tx_desc_alloc_wrapper(pdev, vdev, msdu_info);
	if (!tx_desc)
		return NULL;

	/* initialize the SW tx descriptor */
	tx_desc->netbuf = netbuf;

	if (msdu_info->tso_info.is_tso) {
		tx_desc->tso_desc = msdu_info->tso_info.curr_seg;
		tx_desc->pkt_type = ol_tx_frm_tso;
		TXRX_STATS_MSDU_INCR(pdev, tx.tso.tso_pkts, netbuf);
	} else {
		tx_desc->pkt_type = ol_tx_frm_std;
	}

	/* initialize the HW tx descriptor */

	htt_tx_desc_init(pdev->htt_pdev, tx_desc->htt_tx_desc,
			 tx_desc->htt_tx_desc_paddr,
			 ol_tx_desc_id(pdev, tx_desc), netbuf, &msdu_info->htt,
			 &msdu_info->tso_info,
			 NULL, vdev->opmode == wlan_op_mode_ocb);

	/*
	 * Initialize the fragmentation descriptor.
	 * Skip the prefix fragment (HTT tx descriptor) that was added
	 * during the call to htt_tx_desc_init above.
	 */
	num_frags = cdf_nbuf_get_num_frags(netbuf);
	/* num_frags are expected to be 2 max */
	num_frags = (num_frags > CVG_NBUF_MAX_EXTRA_FRAGS)
		? CVG_NBUF_MAX_EXTRA_FRAGS
		: num_frags;
#if defined(HELIUMPLUS_PADDR64)
	/*
	 * Use num_frags - 1, since 1 frag is used to store
	 * the HTT/HTC descriptor
	 * Refer to htt_tx_desc_init()
	 */
	htt_tx_desc_num_frags(pdev->htt_pdev, tx_desc->htt_frag_desc,
			      num_frags - 1);
#else /* ! defined(HELIUMPLUSPADDR64) */
	htt_tx_desc_num_frags(pdev->htt_pdev, tx_desc->htt_tx_desc,
			      num_frags - 1);
#endif /* defined(HELIUMPLUS_PADDR64) */

	if (msdu_info->tso_info.is_tso) {
		htt_tx_desc_fill_tso_info(pdev->htt_pdev,
			 tx_desc->htt_frag_desc, &msdu_info->tso_info);
		TXRX_STATS_TSO_SEG_UPDATE(pdev,
			 msdu_info->tso_info.curr_seg->seg);
	} else {
		for (i = 1; i < num_frags; i++) {
			cdf_size_t frag_len;
			uint32_t frag_paddr;

			frag_len = cdf_nbuf_get_frag_len(netbuf, i);
			frag_paddr = cdf_nbuf_get_frag_paddr_lo(netbuf, i);
#if defined(HELIUMPLUS_PADDR64)
			htt_tx_desc_frag(pdev->htt_pdev, tx_desc->htt_frag_desc, i - 1,
				 frag_paddr, frag_len);
#if defined(HELIUMPLUS_DEBUG)
			cdf_print("%s:%d: htt_fdesc=%p frag_paddr=%u len=%zu\n",
					  __func__, __LINE__, tx_desc->htt_frag_desc,
					  frag_paddr, frag_len);
			dump_pkt(netbuf, frag_paddr, 64);
#endif /* HELIUMPLUS_DEBUG */
#else /* ! defined(HELIUMPLUSPADDR64) */
			htt_tx_desc_frag(pdev->htt_pdev, tx_desc->htt_tx_desc, i - 1,
							 frag_paddr, frag_len);
#endif /* defined(HELIUMPLUS_PADDR64) */
		}
	}

#if defined(HELIUMPLUS_DEBUG)
	dump_frag_desc("ol_tx_desc_ll()", tx_desc);
#endif
	return tx_desc;
}
struct ol_tx_desc_t *
ol_tx_desc_ll(
    struct ol_txrx_pdev_t *pdev,
    struct ol_txrx_vdev_t *vdev,
    adf_nbuf_t netbuf,
    struct ol_txrx_msdu_info_t *msdu_info)
{
    struct ol_tx_desc_t *tx_desc;
    unsigned int i;
    u_int32_t num_frags;

    msdu_info->htt.info.vdev_id = vdev->vdev_id;
    msdu_info->htt.action.cksum_offload = adf_nbuf_get_tx_cksum(netbuf);
    switch (adf_nbuf_get_exemption_type(netbuf)) {
    case ADF_NBUF_EXEMPT_NO_EXEMPTION:
    case ADF_NBUF_EXEMPT_ON_KEY_MAPPING_KEY_UNAVAILABLE:
        /* We want to encrypt this frame */
        msdu_info->htt.action.do_encrypt = 1;
        break;
    case ADF_NBUF_EXEMPT_ALWAYS:
        /* We don't want to encrypt this frame */
        msdu_info->htt.action.do_encrypt = 0;
        break;
    default:
        adf_os_assert(0);
        break;
    }

    /* allocate the descriptor */
    tx_desc = ol_tx_desc_alloc(pdev, vdev);
    if (!tx_desc) return NULL;

    /* initialize the SW tx descriptor */
    tx_desc->netbuf = netbuf;
    /* fix this - get pkt_type from msdu_info */
    tx_desc->pkt_type = ol_tx_frm_std;

    /* initialize the HW tx descriptor */
    htt_tx_desc_init(
        pdev->htt_pdev, tx_desc->htt_tx_desc,
        tx_desc->htt_tx_desc_paddr,
        ol_tx_desc_id(pdev, tx_desc),
        netbuf,
        &msdu_info->htt, NULL, vdev->opmode == wlan_op_mode_ocb);

    /*
     * Initialize the fragmentation descriptor.
     * Skip the prefix fragment (HTT tx descriptor) that was added
     * during the call to htt_tx_desc_init above.
     */
    num_frags = adf_nbuf_get_num_frags(netbuf);
    /* num_frags are expected to be 2 max */
    num_frags = (num_frags > CVG_NBUF_MAX_EXTRA_FRAGS) ? CVG_NBUF_MAX_EXTRA_FRAGS : num_frags;
    htt_tx_desc_num_frags(pdev->htt_pdev, tx_desc->htt_tx_desc, num_frags-1);
    for (i = 1; i < num_frags; i++) {
        adf_os_size_t frag_len;
        u_int32_t frag_paddr;

        frag_len = adf_nbuf_get_frag_len(netbuf, i);
        frag_paddr = adf_nbuf_get_frag_paddr_lo(netbuf, i);
        htt_tx_desc_frag(
            pdev->htt_pdev, tx_desc->htt_tx_desc, i-1, frag_paddr, frag_len);
    }
    return tx_desc;
}