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; }