/**
 * adf_log_dhcp_pkt() - log DHCP packet
 * @session_id: vdev_id
 * @skb: skb pointer
 * @dir: direction
 *
 * Return: true/false
 */
bool adf_log_dhcp_pkt(uint8_t session_id, struct sk_buff *skb,
		      enum adf_proto_dir dir)
{
	enum adf_proto_subtype subtype = ADF_PROTO_INVALID;

	if ((adf_dp_get_proto_bitmap() & NBUF_PKT_TRAC_TYPE_DHCP) &&
		((dir == ADF_TX && ADF_NBUF_GET_IS_DHCP(skb)) ||
		(dir == ADF_RX && adf_nbuf_is_dhcp_pkt(skb)))) {

		subtype = adf_nbuf_get_dhcp_subtype(skb);
		DPTRACE(adf_dp_trace_proto_pkt(ADF_DP_TRACE_DHCP_PACKET_RECORD,
			session_id, (skb->data + ADF_NBUF_SRC_MAC_OFFSET),
			(skb->data + ADF_NBUF_DEST_MAC_OFFSET),
			ADF_PROTO_TYPE_DHCP, subtype,
			dir));
		if (ADF_TX == dir)
			ADF_NBUF_CB_TX_DP_TRACE(skb) = 1;
		else if (ADF_RX == dir)
			ADF_NBUF_CB_RX_DP_TRACE(skb) = 1;

		return true;
	}
	return false;
}
Exemplo n.º 2
0
struct ol_tx_frms_queue_t *
ol_tx_classify(
    struct ol_txrx_vdev_t *vdev,
    struct ol_tx_desc_t *tx_desc,
    adf_nbuf_t tx_nbuf,
    struct ol_txrx_msdu_info_t *tx_msdu_info)
{
    struct ol_txrx_pdev_t *pdev = vdev->pdev;
    struct ol_txrx_peer_t *peer = NULL;
    struct ol_tx_frms_queue_t *txq = NULL;
    A_UINT8 *dest_addr;
    A_UINT8 tid;
#if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS)
    u_int8_t peer_id;
#endif

    TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);

    dest_addr = ol_tx_dest_addr_find(pdev, tx_nbuf);
    if ((IEEE80211_IS_MULTICAST(dest_addr))
            || (vdev->opmode == wlan_op_mode_ocb)) {
        txq = &vdev->txqs[OL_TX_VDEV_MCAST_BCAST];
        tx_msdu_info->htt.info.ext_tid = HTT_TX_EXT_TID_NON_QOS_MCAST_BCAST;
        if (vdev->opmode == wlan_op_mode_sta) {
            /*
             * The STA sends a frame with a broadcast dest addr (DA) as a
             * unicast frame to the AP's receive addr (RA).
             * Find the peer object that represents the AP that the STA
             * is associated with.
             */
            peer = ol_txrx_assoc_peer_find(vdev);
            if (!peer) {
                VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
                    "Error: STA %p (%02x:%02x:%02x:%02x:%02x:%02x) "
                    "trying to send bcast DA tx data frame "
                    "w/o association\n",
                    vdev,
                    vdev->mac_addr.raw[0], vdev->mac_addr.raw[1],
                    vdev->mac_addr.raw[2], vdev->mac_addr.raw[3],
                    vdev->mac_addr.raw[4], vdev->mac_addr.raw[5]);
                return NULL; /* error */
            } else if ((peer->security[OL_TXRX_PEER_SECURITY_MULTICAST].sec_type
                              != htt_sec_type_wapi) &&
                              (A_STATUS_OK == adf_nbuf_is_dhcp_pkt(tx_nbuf))) {
                /* DHCP frame to go with voice priority */
                txq = &peer->txqs[TX_DHCP_TID];
                tx_msdu_info->htt.info.ext_tid = TX_DHCP_TID;
            }
            /*
             * The following line assumes each peer object has a single ID.
             * This is currently true, and is expected to remain true.
             */
            tx_msdu_info->htt.info.peer_id = peer->peer_ids[0];
        } else if (vdev->opmode == wlan_op_mode_ocb) {
            tx_msdu_info->htt.info.peer_id = HTT_INVALID_PEER_ID;
            /* In OCB mode, don't worry about the peer. We don't need it. */
            peer = NULL;
        } else {
            tx_msdu_info->htt.info.peer_id = HTT_INVALID_PEER_ID;
            /*
             * Look up the vdev's BSS peer, so that the classify_extension
             * function can check whether to encrypt multicast / broadcast
             * frames.
             */
            peer = ol_txrx_peer_find_hash_find(pdev, vdev->mac_addr.raw, 0, 1);
            if (!peer) {
                VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
                    "Error: vdev %p (%02x:%02x:%02x:%02x:%02x:%02x) "
                    "trying to send bcast/mcast, but no self-peer found\n",
                    vdev,
                    vdev->mac_addr.raw[0], vdev->mac_addr.raw[1],
                    vdev->mac_addr.raw[2], vdev->mac_addr.raw[3],
                    vdev->mac_addr.raw[4], vdev->mac_addr.raw[5]);
                return NULL; /* error */
            }
        }
        tx_msdu_info->htt.info.is_unicast = FALSE;
    } else {
        /* tid would be overwritten for non QoS case*/
        tid = ol_tx_tid(pdev, tx_nbuf, tx_msdu_info);
        if ((HTT_TX_EXT_TID_INVALID == tid) || (tid >= OL_TX_NUM_TIDS)) {
             VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
                 "%s Error: could not classify packet into valid TID(%d).\n",
                 __func__, tid);
             return NULL;
        }
        #ifdef ATH_SUPPORT_WAPI
        /* Check to see if a frame is a WAI frame */
        if (tx_msdu_info->htt.info.ethertype == ETHERTYPE_WAI) {
            /* WAI frames should not be encrypted */
            tx_msdu_info->htt.action.do_encrypt = 0;
            VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO,
                "Tx Frame is a WAI frame\n");
        }
        #endif /* ATH_SUPPORT_WAPI */

        /*
         * Find the peer and increment its reference count.
         * If this vdev is an AP, use the dest addr (DA) to determine
         * which peer STA this unicast data frame is for.
         * If this vdev is a STA, the unicast data frame is for the
         * AP the STA is associated with.
         */
        if (vdev->opmode == wlan_op_mode_sta) {
            /*
             * TO DO:
             * To support TDLS, first check if there is a TDLS peer STA,
             * and if so, check if the DA matches the TDLS peer STA's
             * MAC address.
             * If there is no peer TDLS STA, or if the DA is not the
             * TDLS STA's address, then the frame is either for the AP
             * itself, or is supposed to be sent to the AP for forwarding.
             */
            #if 0
            if (vdev->num_tdls_peers > 0) {
                peer = NULL;
                for (i = 0; i < vdev->num_tdls_peers); i++) {
                    int differs = adf_os_mem_cmp(
                        vdev->tdls_peers[i]->mac_addr.raw,
                        dest_addr, OL_TXRX_MAC_ADDR_LEN);
                    if (!differs) {
                        peer = vdev->tdls_peers[i];
                        break;
                    }
                }
            } else {
                /* send to AP */
                peer = ol_txrx_assoc_peer_find(vdev);
            }
            #endif
            #if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS)
            if (vdev->hlTdlsFlag) {
                peer = ol_txrx_find_peer_by_addr(pdev, vdev->hl_tdls_ap_mac_addr.raw, &peer_id);
                if (peer &&  (peer->peer_ids[0] == HTT_INVALID_PEER_ID))
                    peer = NULL;
                else {
                    if (peer)
                       adf_os_atomic_inc(&peer->ref_cnt);
                }
            }
            if (!peer)
                peer = ol_txrx_assoc_peer_find(vdev);
            #else
            peer = ol_txrx_assoc_peer_find(vdev);
            #endif
        } else {