From 949674c4cbc9ed5be74d8ae03c15b352cb495444 Mon Sep 17 00:00:00 2001 From: Ishank Jain Date: Mon, 27 Feb 2017 17:09:29 +0530 Subject: [PATCH] qcacmn: Add DSCP_TID changes for Lithium Add command to set mapid for each VAP using: iwpriv athX s_dscp_mapid N Add command to change tid values in PDEV maps using: iwpriv wifiX s_dscp_tid_map Change-Id: I510a40e71ecec5c453dd2dff1b13fd5ebedbe98a CRs-Fixed: 1108452 --- dp/inc/cdp_txrx_cmn.h | 35 +++++++++ dp/inc/cdp_txrx_ops.h | 7 ++ dp/wifi3.0/dp_main.c | 88 +++++++++++++++++++++++ dp/wifi3.0/dp_rx.c | 2 +- dp/wifi3.0/dp_tx.c | 151 ++++++++++++++++++++++++++++++--------- dp/wifi3.0/dp_types.h | 20 +++++- hal/wifi3.0/hal_tx.h | 38 ++++++++++ qdf/inc/qdf_net_types.h | 59 +++++++++++++++ qdf/linux/src/qdf_nbuf.c | 5 ++ 9 files changed, 366 insertions(+), 39 deletions(-) diff --git a/dp/inc/cdp_txrx_cmn.h b/dp/inc/cdp_txrx_cmn.h index 47c752985bcd..ab1aeb991887 100644 --- a/dp/inc/cdp_txrx_cmn.h +++ b/dp/inc/cdp_txrx_cmn.h @@ -400,4 +400,39 @@ cdp_get_peer_mac_addr_frm_id(ol_txrx_soc_handle soc, uint16_t peer_id, peer_id, mac_addr); return CDP_INVALID_VDEV_ID; } + +/** + * cdp_set_vdev_dscp_tid_map(): function to set DSCP-tid map in the vap + * @vdev: vdev handle + * @map_id: id of the tid map + * + * Return: void + */ +static inline void cdp_set_vdev_dscp_tid_map(ol_txrx_soc_handle soc, + struct cdp_vdev *vdev, uint8_t map_id) +{ + if (soc->ops->cmn_drv_ops->set_vdev_dscp_tid_map) + return soc->ops->cmn_drv_ops->set_vdev_dscp_tid_map(vdev, + map_id); + return; +} + +/** + * cdp_set_pdev_dscp_tid_map(): function to change tid values in DSCP-tid map + * @pdev: pdev handle + * @map_id: id of the tid map + * @tos: index value in map that needs to be changed + * @tid: tid value passed by user + * + * Return: void + */ +static inline void cdp_set_pdev_dscp_tid_map(ol_txrx_soc_handle soc, + struct cdp_pdev *pdev, uint8_t map_id, uint8_t tos, uint8_t tid) +{ + if (soc->ops->cmn_drv_ops->set_pdev_dscp_tid_map) { + return soc->ops->cmn_drv_ops->set_pdev_dscp_tid_map(pdev, + map_id, tos, tid); + } + return; +} #endif /* _CDP_TXRX_CMN_H_ */ diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 15fc190e1785..30fadd2db8f0 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -186,6 +186,13 @@ struct cdp_cmn_ops { uint8_t (*get_peer_mac_addr_frm_id)(struct cdp_soc_t *soc_handle, uint16_t peer_id, uint8_t *mac_addr); + + void (*set_vdev_dscp_tid_map)(struct cdp_vdev *vdev_handle, + uint8_t map_id); + + void (*set_pdev_dscp_tid_map)(struct cdp_pdev *pdev, uint8_t map_id, + uint8_t tos, uint8_t tid); + }; struct cdp_ctrl_ops { diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 14430d93eb1b..3d53a07e0f12 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -40,6 +40,31 @@ #define DP_NSS_LENGTH (6*SS_COUNT) #define DP_RXDMA_ERR_LENGTH (6*MAX_RXDMA_ERRORS) #define DP_REO_ERR_LENGTH (6*REO_ERROR_TYPE_MAX) + +/** + * default_dscp_tid_map - Default DSCP-TID mapping + * + * DSCP TID AC + * 000000 0 WME_AC_BE + * 001000 1 WME_AC_BK + * 010000 1 WME_AC_BK + * 011000 0 WME_AC_BE + * 100000 5 WME_AC_VI + * 101000 5 WME_AC_VI + * 110000 6 WME_AC_VO + * 111000 6 WME_AC_VO + */ +static uint8_t default_dscp_tid_map[DSCP_TID_MAP_MAX] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, +}; + /** * dp_setup_srng - Internal function to setup SRNG rings used by data path */ @@ -987,6 +1012,28 @@ static int dp_rxdma_ring_setup(struct dp_soc *soc, return QDF_STATUS_SUCCESS; } #endif + +/** + * dp_dscp_tid_map_setup(): Initialize the dscp-tid maps + * @pdev - DP_PDEV handle + * + * Return: void + */ +static inline void +dp_dscp_tid_map_setup(struct dp_pdev *pdev) +{ + uint8_t map_id; + for (map_id = 0; map_id < DP_MAX_TID_MAPS; map_id++) { + qdf_mem_copy(pdev->dscp_tid_map[map_id], default_dscp_tid_map, + sizeof(default_dscp_tid_map)); + } + for (map_id = 0; map_id < HAL_MAX_HW_DSCP_TID_MAPS; map_id++) { + hal_tx_set_dscp_tid_map(pdev->soc->hal_soc, + pdev->dscp_tid_map[map_id], + map_id); + } +} + /* * dp_pdev_attach_wifi3() - attach txrx pdev * @osif_pdev: Opaque PDEV handle from OSIF/HDD @@ -1119,6 +1166,7 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, dp_local_peer_id_pool_init(pdev); #endif dp_lro_hash_setup(soc); + dp_dscp_tid_map_setup(pdev); return (struct cdp_pdev *)pdev; @@ -1446,6 +1494,7 @@ static struct cdp_vdev *dp_vdev_attach_wifi3(struct cdp_pdev *txrx_pdev, vdev->tx_encap_type = wlan_cfg_pkt_type(soc->wlan_cfg_ctx); vdev->rx_decap_type = wlan_cfg_pkt_type(soc->wlan_cfg_ctx); + vdev->dscp_tid_map_id = 0; /* TODO: Initialize default HTT meta data that will be used in * TCL descriptors for packets transmitted from this VDEV @@ -2708,6 +2757,42 @@ dp_get_peer_stats(struct cdp_pdev *pdev_handle, char *mac_addr) return; } +/* + * dp_set_vdev_dscp_tid_map_wifi3(): Update Map ID selected for particular vdev + * @vdev_handle: DP_VDEV handle + * @map_id:ID of map that needs to be updated + * + * Return: void + */ +static void dp_set_vdev_dscp_tid_map_wifi3(struct cdp_vdev *vdev_handle, + uint8_t map_id) +{ + struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + vdev->dscp_tid_map_id = map_id; + return; +} + +/** + * dp_set_pdev_dscp_tid_map_wifi3(): update dscp tid map in pdev + * @pdev: DP_PDEV handle + * @map_id: ID of map that needs to be updated + * @tos: index value in map + * @tid: tid value passed by the user + * + * Return: void + */ +static void dp_set_pdev_dscp_tid_map_wifi3(struct cdp_pdev *pdev_handle, + uint8_t map_id, uint8_t tos, uint8_t tid) +{ + uint8_t dscp; + struct dp_pdev *pdev = (struct dp_pdev *) pdev_handle; + dscp = (tos >> DP_IP_DSCP_SHIFT) & DP_IP_DSCP_MASK; + pdev->dscp_tid_map[map_id][dscp] = tid; + hal_tx_update_dscp_tid(pdev->soc->hal_soc, tid, + map_id, dscp); + return; +} + static struct cdp_cmn_ops dp_ops_cmn = { .txrx_soc_attach_target = dp_soc_attach_target_wifi3, .txrx_vdev_attach = dp_vdev_attach_wifi3, @@ -2727,6 +2812,9 @@ static struct cdp_cmn_ops dp_ops_cmn = { .addba_responsesetup = dp_addba_responsesetup_wifi3, .delba_process = dp_delba_process_wifi3, .get_peer_mac_addr_frm_id = dp_get_peer_mac_addr_frm_id, + /* TODO: get API's for dscp-tid need to be added*/ + .set_vdev_dscp_tid_map = dp_set_vdev_dscp_tid_map_wifi3, + .set_pdev_dscp_tid_map = dp_set_pdev_dscp_tid_map_wifi3, /* TODO: Add other functions */ }; diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index c30c70745cd7..d775203ea22c 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -739,7 +739,7 @@ done: } } - if (qdf_unlikely(vdev->rx_decap_type == htt_pkt_type_raw)) + if (qdf_unlikely(vdev->rx_decap_type == htt_cmn_pkt_type_raw)) dp_rx_deliver_raw(vdev, deliver_list_head); else if (qdf_likely(vdev->osif_rx) && deliver_list_head) vdev->osif_rx(vdev->osif_vdev, deliver_list_head); diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index 36df8d0f3124..1ea4a0243e53 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -48,30 +48,6 @@ /* disable TQM_BYPASS */ #define TQM_BYPASS_WAR 0 -/* - * default_dscp_tid_map - Default DSCP-TID mapping - * - * DSCP TID AC - * 000000 0 WME_AC_BE - * 001000 1 WME_AC_BK - * 010000 1 WME_AC_BK - * 011000 0 WME_AC_BE - * 100000 5 WME_AC_VI - * 101000 5 WME_AC_VI - * 110000 6 WME_AC_VO - * 111000 6 WME_AC_VO - */ -static uint8_t default_dscp_tid_map[64] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, -}; - /** * dp_tx_get_queue() - Returns Tx queue IDs to be used for this Tx frame * @vdev: DP Virtual device handle @@ -669,6 +645,8 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev, hal_tx_desc_set_buf_length(hal_tx_desc_cached, length); hal_tx_desc_set_buf_offset(hal_tx_desc_cached, tx_desc->pkt_offset); hal_tx_desc_set_encap_type(hal_tx_desc_cached, tx_desc->tx_encap_type); + hal_tx_desc_set_dscp_tid_table_id(hal_tx_desc_cached, + vdev->dscp_tid_map_id); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, "%s length:%d , type = %d, dma_addr %llx, offset %d\n", @@ -730,15 +708,122 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev, * Extract the DSCP or PCP information from frame and map into TID value. * Software based TID classification is required when more than 2 DSCP-TID * mapping tables are needed. - * Hardware supports 2 DSCP-TID mapping tables. + * Hardware supports 2 DSCP-TID mapping tables * - * Return: + * Return: void */ -static int dp_tx_classify_tid(struct dp_vdev *vdev, qdf_nbuf_t nbuf, - struct dp_tx_msdu_info_s *msdu_info) +static void dp_tx_classify_tid(struct dp_vdev *vdev, qdf_nbuf_t nbuf, + struct dp_tx_msdu_info_s *msdu_info) { - /* TODO */ - return 0; + uint8_t tos = 0, dscp_tid_override = 0; + uint8_t *hdr_ptr, *L3datap; + uint8_t is_mcast = 0; + struct ether_header *eh = NULL; + qdf_ethervlan_header_t *evh = NULL; + uint16_t ether_type; + qdf_llc_t *llcHdr; + struct dp_pdev *pdev = (struct dp_pdev *)vdev->pdev; + + /* for mesh packets don't do any classification */ + if (qdf_unlikely(vdev->mesh_vdev)) + return; + + if (qdf_likely(vdev->tx_encap_type != htt_cmn_pkt_type_raw)) { + eh = (struct ether_header *) nbuf->data; + hdr_ptr = eh->ether_dhost; + L3datap = hdr_ptr + sizeof(struct ether_header); + } else { + qdf_dot3_qosframe_t *qos_wh = + (qdf_dot3_qosframe_t *) nbuf->data; + msdu_info->tid = qos_wh->i_fc[0] & DP_FC0_SUBTYPE_QOS ? + qos_wh->i_qos[0] & DP_QOS_TID : 0; + return; + } + + is_mcast = DP_FRAME_IS_MULTICAST(hdr_ptr); + ether_type = eh->ether_type; + /* + * Check if packet is dot3 or eth2 type. + */ + if (IS_LLC_PRESENT(ether_type)) { + ether_type = (uint16_t)*(nbuf->data + 2*ETHER_ADDR_LEN + + sizeof(*llcHdr)); + + if (ether_type == htons(ETHERTYPE_8021Q)) { + L3datap = hdr_ptr + sizeof(qdf_ethervlan_header_t) + + sizeof(*llcHdr); + ether_type = (uint16_t)*(nbuf->data + 2*ETHER_ADDR_LEN + + sizeof(*llcHdr) + + sizeof(qdf_net_vlanhdr_t)); + } else { + L3datap = hdr_ptr + sizeof(struct ether_header) + + sizeof(*llcHdr); + } + + } else { + if (ether_type == htons(ETHERTYPE_8021Q)) { + evh = (qdf_ethervlan_header_t *) eh; + ether_type = evh->ether_type; + L3datap = hdr_ptr + sizeof(qdf_ethervlan_header_t); + } + } + /* + * Find priority from IP TOS DSCP field + */ + if (qdf_nbuf_is_ipv4_pkt(nbuf)) { + qdf_net_iphdr_t *ip = (qdf_net_iphdr_t *) L3datap; + if (qdf_nbuf_is_ipv4_dhcp_pkt(nbuf)) { + /* Only for unicast frames */ + if (!is_mcast) { + /* send it on VO queue */ + msdu_info->tid = DP_VO_TID; + } + } else { + /* + * IP frame: exclude ECN bits 0-1 and map DSCP bits 2-7 + * from TOS byte. + */ + tos = ip->ip_tos; + dscp_tid_override = 1; + + } + } else if (qdf_nbuf_is_ipv6_pkt(nbuf)) { + /* TODO + * use flowlabel + *igmpmld cases to be handled in phase 2 + */ + unsigned long ver_pri_flowlabel; + unsigned long pri; + ver_pri_flowlabel = *(unsigned long *) L3datap; + pri = (ntohl(ver_pri_flowlabel) & IPV6_FLOWINFO_PRIORITY) >> + DP_IPV6_PRIORITY_SHIFT; + tos = pri; + dscp_tid_override = 1; + } else if (qdf_nbuf_is_ipv4_eapol_pkt(nbuf)) + msdu_info->tid = DP_VO_TID; + else if (qdf_nbuf_is_ipv4_arp_pkt(nbuf)) { + /* Only for unicast frames */ + if (!is_mcast) { + /* send ucast arp on VO queue */ + msdu_info->tid = DP_VO_TID; + } + } + + /* + * Assign all MCAST packets to BE + */ + if (qdf_unlikely(vdev->tx_encap_type != htt_cmn_pkt_type_raw)) { + if (is_mcast) { + tos = 0; + dscp_tid_override = 1; + } + } + + if (dscp_tid_override == 1) { + tos = (tos >> DP_IP_DSCP_SHIFT) & DP_IP_DSCP_MASK; + msdu_info->tid = pdev->dscp_tid_map[vdev->dscp_tid_map_id][tos]; + } + return; } /** @@ -1197,7 +1282,7 @@ qdf_nbuf_t dp_tx_send(void *vap_dev, qdf_nbuf_t nbuf) } /* RAW */ - if (qdf_unlikely(vdev->tx_encap_type == htt_pkt_type_raw)) { + if (qdf_unlikely(vdev->tx_encap_type == htt_cmn_pkt_type_raw)) { nbuf = dp_tx_prepare_raw(vdev, nbuf, &seg_info, &msdu_info); if (nbuf == NULL) return NULL; @@ -1979,10 +2064,6 @@ QDF_STATUS dp_tx_soc_attach(struct dp_soc *soc) */ soc->process_tx_status = 1; - /* Initialize Default DSCP-TID mapping table in TCL */ - hal_tx_set_dscp_tid_map(soc->hal_soc, default_dscp_tid_map, - HAL_TX_DSCP_TID_MAP_TABLE_DEFAULT); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, "%s HAL Tx init Success\n", __func__); diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index b79ce12235ad..fc56150de2c7 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -45,6 +45,16 @@ #define REPT_MU_MIMO 1 #define REPT_MU_OFDMA_MIMO 3 #define REO_ERROR_TYPE_MAX (HAL_REO_ERR_QUEUE_DESC_BLOCKED_SET+1) +#define DP_VO_TID 6 + +#define DP_MAX_INTERRUPT_CONTEXTS 8 +#define DP_MAX_TID_MAPS 16 /* MAX TID MAPS AVAILABLE PER PDEV*/ +#define DSCP_TID_MAP_MAX (64) +#define DP_IP_DSCP_SHIFT 2 +#define DP_IP_DSCP_MASK 0x3f +#define DP_FC0_SUBTYPE_QOS 0x80 +#define DP_QOS_TID 0x0f +#define DP_IPV6_PRIORITY_SHIFT 20 struct dp_soc_cmn; struct dp_pdev; @@ -69,6 +79,7 @@ union dp_rx_desc_list_elem_t; (_a)[3] == 0xff && \ (_a)[4] == 0xff && \ (_a)[5] == 0xff) +#define IS_LLC_PRESENT(typeorlen) ((typeorlen) >= 0x600) /** * macros to convert hw mac id to sw mac id: @@ -581,6 +592,10 @@ struct dp_pdev { qdf_spinlock_t lock; struct dp_peer *map[OL_TXRX_NUM_LOCAL_PEER_IDS]; } local_peer_ids; + + /* dscp_tid_map_*/ + uint8_t dscp_tid_map[DP_MAX_TID_MAPS][DSCP_TID_MAP_MAX]; + /* TBD */ }; @@ -668,9 +683,9 @@ struct dp_vdev { enum wlan_op_mode opmode; /* Tx encapsulation type for this VAP */ - enum htt_pkt_type tx_encap_type; + enum htt_cmn_pkt_type tx_encap_type; /* Rx Decapsulation type for this VAP */ - enum htt_pkt_type rx_decap_type; + enum htt_cmn_pkt_type rx_decap_type; /* BSS peer */ struct dp_peer *vap_bss_peer; @@ -771,5 +786,4 @@ struct dp_peer { /* Peer Stats */ struct cdp_peer_stats stats; }; - #endif /* _DP_TYPES_H_ */ diff --git a/hal/wifi3.0/hal_tx.h b/hal/wifi3.0/hal_tx.h index b1524f5089cf..ff15ff3e73ef 100644 --- a/hal/wifi3.0/hal_tx.h +++ b/hal/wifi3.0/hal_tx.h @@ -75,6 +75,9 @@ do { \ #define HAL_TX_COMPLETION_DESC_LEN_DWORDS (NUM_OF_DWORDS_WBM_RELEASE_RING) #define HAL_TX_COMPLETION_DESC_LEN_BYTES (NUM_OF_DWORDS_WBM_RELEASE_RING*4) +#define HAL_TX_BITS_PER_TID 3 +#define HAL_TX_NUM_DSCP_PER_REGISTER 10 +#define HAL_MAX_HW_DSCP_TID_MAPS 2 #define HTT_META_HEADER_LEN_BYTES 64 #define HAL_TX_EXT_DESC_WITH_META_DATA \ @@ -1025,6 +1028,41 @@ static inline void hal_tx_set_dscp_tid_map(void *hal_soc, uint8_t *map, } } +/** + * hal_tx_update_dscp_tid() - Update the dscp tid map table as updated by user + * @soc: HAL SoC context + * @map: DSCP-TID mapping table + * @id : MAP ID + * @dscp: DSCP_TID map index + * + * Return: void + */ +static inline void hal_tx_update_dscp_tid(void *hal_soc, uint8_t tid, + uint8_t id, uint8_t dscp) +{ + int index; + uint32_t addr; + uint32_t value; + + struct hal_soc *soc = (struct hal_soc *)hal_soc; + + if (id == HAL_TX_DSCP_TID_MAP_TABLE_DEFAULT) + addr = + HWIO_TCL_R0_DSCP_TID1_MAP_0_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); + else + addr = + HWIO_TCL_R0_DSCP_TID2_MAP_0_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); + + index = dscp % HAL_TX_NUM_DSCP_PER_REGISTER; + addr += 4 * (dscp/HAL_TX_NUM_DSCP_PER_REGISTER); + value = tid << (HAL_TX_BITS_PER_TID * index); + + HAL_REG_WRITE(soc, addr, + (value & HWIO_TCL_R0_DSCP_TID1_MAP_1_RMSK)); +} + /** * hal_tx_init_data_ring() - Initialize all the TCL Descriptors in SRNG * @hal_soc: Handle to HAL SoC structure diff --git a/qdf/inc/qdf_net_types.h b/qdf/inc/qdf_net_types.h index 386f72fcf6ee..49ceab5857b3 100644 --- a/qdf/inc/qdf_net_types.h +++ b/qdf/inc/qdf_net_types.h @@ -463,4 +463,63 @@ static inline int32_t qdf_csum_ipv6(const in6_addr_t *saddr, return (int32_t)__qdf_csum_ipv6(saddr, daddr, len, proto, sum); } +typedef struct { + uint8_t i_fc[2]; + uint8_t i_dur[2]; + uint8_t i_addr1[QDF_NET_MAC_ADDR_MAX_LEN]; + uint8_t i_addr2[QDF_NET_MAC_ADDR_MAX_LEN]; + uint8_t i_addr3[QDF_NET_MAC_ADDR_MAX_LEN]; + uint8_t i_seq[2]; + uint8_t i_qos[2]; +} qdf_dot3_qosframe_t; + +typedef struct { + uint8_t ether_dhost[QDF_NET_MAC_ADDR_MAX_LEN]; + uint8_t ether_shost[QDF_NET_MAC_ADDR_MAX_LEN]; + uint16_t vlan_TCI; + uint16_t vlan_encapsulated_proto; + uint16_t ether_type; +} qdf_ethervlan_header_t; + +typedef struct { + uint8_t llc_dsap; + uint8_t llc_ssap; + union { + struct { + uint8_t control; + uint8_t format_id; + uint8_t class; + uint8_t window_x2; + } __packed type_u; + struct { + uint8_t num_snd_x2; + uint8_t num_rcv_x2; + } __packed type_i; + struct { + uint8_t control; + uint8_t num_rcv_x2; + } __packed type_s; + struct { + uint8_t control; + /* + * We cannot put the following fields in a structure + * because the structure rounding might cause padding. + */ + uint8_t frmr_rej_pdu0; + uint8_t frmr_rej_pdu1; + uint8_t frmr_control; + uint8_t frmr_control_ext; + uint8_t frmr_cause; + } __packed type_frmr; + struct { + uint8_t control; + uint8_t org_code[3]; + uint16_t ether_type; + } __packed type_snap; + struct { + uint8_t control; + uint8_t control_ext; + } __packed type_raw; + } llc_un /* XXX __packed ??? */; +} qdf_llc_t; #endif /*_QDF_NET_TYPES_H*/ diff --git a/qdf/linux/src/qdf_nbuf.c b/qdf/linux/src/qdf_nbuf.c index 1cb4572cb15a..6e8f6bcb528c 100644 --- a/qdf/linux/src/qdf_nbuf.c +++ b/qdf/linux/src/qdf_nbuf.c @@ -739,6 +739,7 @@ bool __qdf_nbuf_data_is_ipv4_pkt(uint8_t *data) else return false; } +EXPORT_SYMBOL(__qdf_nbuf_data_is_ipv4_pkt); /** * __qdf_nbuf_data_is_ipv4_dhcp_pkt() - check if skb data is a dhcp packet @@ -768,6 +769,7 @@ bool __qdf_nbuf_data_is_ipv4_dhcp_pkt(uint8_t *data) else return false; } +EXPORT_SYMBOL(__qdf_nbuf_data_is_ipv4_dhcp_pkt); /** * __qdf_nbuf_data_is_ipv4_eapol_pkt() - check if skb data is a eapol packet @@ -790,6 +792,7 @@ bool __qdf_nbuf_data_is_ipv4_eapol_pkt(uint8_t *data) else return false; } +EXPORT_SYMBOL(__qdf_nbuf_data_is_ipv4_eapol_pkt); /** * __qdf_nbuf_is_ipv4_wapi_pkt() - check if skb data is a wapi packet @@ -834,6 +837,7 @@ bool __qdf_nbuf_data_is_ipv4_arp_pkt(uint8_t *data) else return false; } +EXPORT_SYMBOL(__qdf_nbuf_data_is_ipv4_arp_pkt); /** * __qdf_nbuf_data_is_ipv6_pkt() - check if it is IPV6 packet. @@ -856,6 +860,7 @@ bool __qdf_nbuf_data_is_ipv6_pkt(uint8_t *data) else return false; } +EXPORT_SYMBOL(__qdf_nbuf_data_is_ipv6_pkt); /** * __qdf_nbuf_data_is_ipv4_mcast_pkt() - check if it is IPV4 multicast packet.