forked from rrcarlosr/Jetpack
574 lines
20 KiB
C
574 lines
20 KiB
C
/*
|
|
* Portions of this code are copyright (c) 2017 Cypress Semiconductor Corporation
|
|
*
|
|
* Copyright (C) 1999-2017, Broadcom Corporation
|
|
*
|
|
* Unless you and Broadcom execute a separate written software license
|
|
* agreement governing use of this software, this software is licensed to you
|
|
* under the terms of the GNU General Public License version 2 (the "GPL"),
|
|
* available at http://www.broadcom.com/licenses/GPLv2.php, with the
|
|
* following added to such license:
|
|
*
|
|
* As a special exception, the copyright holders of this software give you
|
|
* permission to link this software with independent modules, and to copy and
|
|
* distribute the resulting executable under terms of your choice, provided that
|
|
* you also meet, for each linked independent module, the terms and conditions of
|
|
* the license of that module. An independent module is a module which is not
|
|
* derived from this software. The special exception does not apply to any
|
|
* modifications of the software.
|
|
*
|
|
* Notwithstanding the above, under no circumstances may you combine this
|
|
* software in any way with any other Broadcom software provided under a license
|
|
* other than the GPL, without Broadcom's express prior written consent.
|
|
*
|
|
*
|
|
* <<Broadcom-WL-IPTag/Open:>>
|
|
*
|
|
* $Id: dhd_wlfc.h 674206 2017-10-12 07:09:16Z $
|
|
*
|
|
*/
|
|
#ifndef __wlfc_host_driver_definitions_h__
|
|
#define __wlfc_host_driver_definitions_h__
|
|
|
|
|
|
/* #define OOO_DEBUG */
|
|
|
|
#define KERNEL_THREAD_RETURN_TYPE int
|
|
|
|
typedef int (*f_commitpkt_t)(void* ctx, void* p);
|
|
typedef bool (*f_processpkt_t)(void* p, void* arg);
|
|
|
|
#define WLFC_UNSUPPORTED -9999
|
|
|
|
#define WLFC_NO_TRAFFIC -1
|
|
#define WLFC_MULTI_TRAFFIC 0
|
|
|
|
#define BUS_RETRIES 1 /* # of retries before aborting a bus tx operation */
|
|
|
|
/** 16 bits will provide an absolute max of 65536 slots */
|
|
#define WLFC_HANGER_MAXITEMS 3072
|
|
|
|
#define WLFC_HANGER_ITEM_STATE_FREE 1
|
|
#define WLFC_HANGER_ITEM_STATE_INUSE 2
|
|
#define WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED 3
|
|
#define WLFC_HANGER_ITEM_STATE_FLUSHED 4
|
|
|
|
#define WLFC_HANGER_PKT_STATE_TXSTATUS 1
|
|
#define WLFC_HANGER_PKT_STATE_BUSRETURNED 2
|
|
#define WLFC_HANGER_PKT_STATE_COMPLETE \
|
|
(WLFC_HANGER_PKT_STATE_TXSTATUS | WLFC_HANGER_PKT_STATE_BUSRETURNED)
|
|
|
|
typedef enum {
|
|
Q_TYPE_PSQ, /**< Power Save Queue, contains both delayed and suppressed packets */
|
|
Q_TYPE_AFQ /**< At Firmware Queue */
|
|
} q_type_t;
|
|
|
|
typedef enum ewlfc_packet_state {
|
|
eWLFC_PKTTYPE_NEW, /**< unused in the code (Jan 2015) */
|
|
eWLFC_PKTTYPE_DELAYED, /**< packet did not enter wlfc yet */
|
|
eWLFC_PKTTYPE_SUPPRESSED, /**< packet entered wlfc and was suppressed by the dongle */
|
|
eWLFC_PKTTYPE_MAX
|
|
} ewlfc_packet_state_t;
|
|
|
|
typedef enum ewlfc_mac_entry_action {
|
|
eWLFC_MAC_ENTRY_ACTION_ADD,
|
|
eWLFC_MAC_ENTRY_ACTION_DEL,
|
|
eWLFC_MAC_ENTRY_ACTION_UPDATE,
|
|
eWLFC_MAC_ENTRY_ACTION_MAX
|
|
} ewlfc_mac_entry_action_t;
|
|
|
|
typedef struct wlfc_hanger_item {
|
|
uint8 state;
|
|
uint8 gen;
|
|
uint8 pkt_state; /**< bitmask containing eg WLFC_HANGER_PKT_STATE_TXCOMPLETE */
|
|
uint8 pkt_txstatus;
|
|
uint32 identifier;
|
|
void* pkt;
|
|
#ifdef PROP_TXSTATUS_DEBUG
|
|
uint32 push_time;
|
|
#endif
|
|
struct wlfc_hanger_item *next;
|
|
} wlfc_hanger_item_t;
|
|
|
|
/** hanger contains packets that have been posted by the dhd to the dongle and are expected back */
|
|
typedef struct wlfc_hanger {
|
|
int max_items;
|
|
uint32 pushed;
|
|
uint32 popped;
|
|
uint32 failed_to_push;
|
|
uint32 failed_to_pop;
|
|
uint32 failed_slotfind;
|
|
uint32 slot_pos;
|
|
wlfc_hanger_item_t items[1];
|
|
} wlfc_hanger_t;
|
|
|
|
#define WLFC_HANGER_SIZE(n) ((sizeof(wlfc_hanger_t) - \
|
|
sizeof(wlfc_hanger_item_t)) + ((n)*sizeof(wlfc_hanger_item_t)))
|
|
|
|
#define WLFC_STATE_OPEN 1 /**< remote MAC is able to receive packets */
|
|
#define WLFC_STATE_CLOSE 2 /**< remote MAC is in power save mode */
|
|
|
|
#define WLFC_PSQ_PREC_COUNT ((AC_COUNT + 1) * 2) /**< 2 for each AC traffic and bc/mc */
|
|
#define WLFC_AFQ_PREC_COUNT (AC_COUNT + 1)
|
|
|
|
#define WLFC_PSQ_LEN 2048
|
|
|
|
#define WLFC_FLOWCONTROL_HIWATER (2048 - 256)
|
|
#define WLFC_FLOWCONTROL_LOWATER 256
|
|
|
|
#if (WLFC_FLOWCONTROL_HIWATER >= (WLFC_PSQ_LEN - 256))
|
|
#undef WLFC_FLOWCONTROL_HIWATER
|
|
#define WLFC_FLOWCONTROL_HIWATER (WLFC_PSQ_LEN - 256)
|
|
#undef WLFC_FLOWCONTROL_LOWATER
|
|
#define WLFC_FLOWCONTROL_LOWATER (WLFC_FLOWCONTROL_HIWATER / 4)
|
|
#endif
|
|
|
|
#define WLFC_LOG_BUF_SIZE (1024*1024)
|
|
|
|
/** Properties related to a remote MAC entity */
|
|
typedef struct wlfc_mac_descriptor {
|
|
uint8 occupied; /**< if 0, this descriptor is unused and thus can be (re)used */
|
|
uint8 interface_id;
|
|
uint8 iftype; /**< eg WLC_E_IF_ROLE_STA */
|
|
uint8 state; /**< eg WLFC_STATE_OPEN */
|
|
uint8 ac_bitmap; /**< automatic power save delivery (APSD) */
|
|
uint8 requested_credit;
|
|
uint8 requested_packet; /**< unit: [number of packets] */
|
|
uint8 ea[ETHER_ADDR_LEN];
|
|
|
|
/** maintain (MAC,AC) based seq count for packets going to the device. As well as bc/mc. */
|
|
uint8 seq[AC_COUNT + 1];
|
|
uint8 generation; /**< toggles between 0 and 1 */
|
|
struct pktq psq; /**< contains both 'delayed' and 'suppressed' packets */
|
|
/** packets at firmware queue */
|
|
struct pktq afq;
|
|
/** The AC pending bitmap that was reported to the fw at last change */
|
|
uint8 traffic_lastreported_bmp;
|
|
/** The new AC pending bitmap */
|
|
uint8 traffic_pending_bmp;
|
|
/** 1= send on next opportunity */
|
|
uint8 send_tim_signal;
|
|
uint8 mac_handle; /**< mac handles are assigned by the dongle */
|
|
/** Number of packets at dongle for this entry. */
|
|
int transit_count;
|
|
/** Number of suppression to wait before evict from delayQ */
|
|
int suppr_transit_count;
|
|
/** pkt sent to bus but no bus TX complete yet */
|
|
int onbus_pkts_count;
|
|
/** flag. TRUE when remote MAC is in suppressed state */
|
|
uint8 suppressed;
|
|
|
|
|
|
#ifdef PROP_TXSTATUS_DEBUG
|
|
uint32 dstncredit_sent_packets;
|
|
uint32 dstncredit_acks;
|
|
uint32 opened_ct;
|
|
uint32 closed_ct;
|
|
#endif
|
|
|
|
int grp_idx;
|
|
struct wlfc_mac_descriptor* prev;
|
|
struct wlfc_mac_descriptor* next;
|
|
} wlfc_mac_descriptor_t;
|
|
|
|
/** A 'commit' is the hand over of a packet from the host OS layer to the layer below (eg DBUS) */
|
|
typedef struct dhd_wlfc_commit_info {
|
|
uint8 needs_hdr;
|
|
uint8 ac_fifo_credit_spent;
|
|
ewlfc_packet_state_t pkt_type;
|
|
wlfc_mac_descriptor_t* mac_entry;
|
|
void* p;
|
|
} dhd_wlfc_commit_info_t;
|
|
|
|
#define WLFC_DECR_SEQCOUNT(entry, prec) do { if (entry->seq[(prec)] == 0) {\
|
|
entry->seq[prec] = 0xff; } else entry->seq[prec]--;} while (0)
|
|
|
|
#define WLFC_INCR_SEQCOUNT(entry, prec) entry->seq[(prec)]++
|
|
#define WLFC_SEQCOUNT(entry, prec) entry->seq[(prec)]
|
|
|
|
typedef struct athost_wl_stat_counters {
|
|
uint32 pktin;
|
|
uint32 pktout;
|
|
uint32 pkt2bus;
|
|
uint32 pktdropped;
|
|
uint32 tlv_parse_failed;
|
|
uint32 rollback;
|
|
uint32 rollback_failed;
|
|
uint32 delayq_full_error;
|
|
uint32 credit_request_failed;
|
|
uint32 packet_request_failed;
|
|
uint32 mac_update_failed;
|
|
uint32 psmode_update_failed;
|
|
uint32 interface_update_failed;
|
|
uint32 wlfc_header_only_pkt;
|
|
uint32 txstatus_in;
|
|
uint32 d11_suppress;
|
|
uint32 wl_suppress;
|
|
uint32 bad_suppress;
|
|
uint32 pkt_freed;
|
|
uint32 pkt_free_err;
|
|
uint32 psq_wlsup_retx;
|
|
uint32 psq_wlsup_enq;
|
|
uint32 psq_d11sup_retx;
|
|
uint32 psq_d11sup_enq;
|
|
uint32 psq_hostq_retx;
|
|
uint32 psq_hostq_enq;
|
|
uint32 mac_handle_notfound;
|
|
uint32 wlc_tossed_pkts;
|
|
uint32 dhd_hdrpulls;
|
|
uint32 generic_error;
|
|
/* an extra one for bc/mc traffic */
|
|
uint32 send_pkts[AC_COUNT + 1];
|
|
uint32 drop_pkts[WLFC_PSQ_PREC_COUNT];
|
|
uint32 ooo_pkts[AC_COUNT + 1];
|
|
#ifdef PROP_TXSTATUS_DEBUG
|
|
/** all pkt2bus -> txstatus latency accumulated */
|
|
uint32 latency_sample_count;
|
|
uint32 total_status_latency;
|
|
uint32 latency_most_recent;
|
|
int idx_delta;
|
|
uint32 deltas[10];
|
|
uint32 fifo_credits_sent[6];
|
|
uint32 fifo_credits_back[6];
|
|
uint32 dropped_qfull[6];
|
|
uint32 signal_only_pkts_sent;
|
|
uint32 signal_only_pkts_freed;
|
|
#endif
|
|
uint32 cleanup_txq_cnt;
|
|
uint32 cleanup_psq_cnt;
|
|
uint32 cleanup_fw_cnt;
|
|
} athost_wl_stat_counters_t;
|
|
|
|
#ifdef PROP_TXSTATUS_DEBUG
|
|
#define WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac) do { \
|
|
(ctx)->stats.fifo_credits_sent[(ac)]++;} while (0)
|
|
#define WLFC_HOST_FIFO_CREDIT_INC_BACKCTRS(ctx, ac) do { \
|
|
(ctx)->stats.fifo_credits_back[(ac)]++;} while (0)
|
|
#define WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, ac) do { \
|
|
(ctx)->stats.dropped_qfull[(ac)]++;} while (0)
|
|
#else
|
|
#define WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac) do {} while (0)
|
|
#define WLFC_HOST_FIFO_CREDIT_INC_BACKCTRS(ctx, ac) do {} while (0)
|
|
#define WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, ac) do {} while (0)
|
|
#endif
|
|
|
|
#define WLFC_FCMODE_NONE 0
|
|
#define WLFC_FCMODE_IMPLIED_CREDIT 1
|
|
#define WLFC_FCMODE_EXPLICIT_CREDIT 2
|
|
#define WLFC_ONLY_AMPDU_HOSTREORDER 3
|
|
|
|
/** Reserved credits ratio when borrowed by hihger priority */
|
|
#define WLFC_BORROW_LIMIT_RATIO 4
|
|
|
|
/** How long to defer borrowing in milliseconds */
|
|
#define WLFC_BORROW_DEFER_PERIOD_MS 100
|
|
|
|
/** How long to defer flow control in milliseconds */
|
|
#define WLFC_FC_DEFER_PERIOD_MS 200
|
|
|
|
/** How long to detect occurance per AC in miliseconds */
|
|
#define WLFC_RX_DETECTION_THRESHOLD_MS 100
|
|
|
|
/** Mask to represent available ACs (note: BC/MC is ignored) */
|
|
#define WLFC_AC_MASK 0xF
|
|
|
|
/** Maximum groups for splitting credits among */
|
|
#define WLFC_MAX_GROUPS 2
|
|
|
|
/** credit groups characteristic */
|
|
#define WLFC_GROUP_NONE 0
|
|
#define WLFC_GROUP_LIMITED 1
|
|
|
|
/** flow control specific information, only 1 instance during driver lifetime */
|
|
typedef struct athost_wl_status_info {
|
|
uint8 last_seqid_to_wlc;
|
|
|
|
/** OSL handle */
|
|
osl_t *osh;
|
|
/** dhd public struct pointer */
|
|
void *dhdp;
|
|
|
|
f_commitpkt_t fcommit;
|
|
void* commit_ctx;
|
|
|
|
/** statistics */
|
|
athost_wl_stat_counters_t stats;
|
|
|
|
/** incremented on eg receiving a credit map event from the dongle */
|
|
int Init_FIFO_credit[AC_COUNT + 2];
|
|
int Init_FIFO_group_credit[WLFC_MAX_GROUPS][AC_COUNT + 2];
|
|
/** the additional ones are for bc/mc and ATIM FIFO */
|
|
int FIFO_credit[WLFC_MAX_GROUPS][AC_COUNT + 2];
|
|
/** Credit borrow counts for each FIFO from each of the other FIFOs */
|
|
int credits_borrowed[WLFC_MAX_GROUPS][AC_COUNT + 2][AC_COUNT + 2];
|
|
|
|
/** packet hanger and MAC->handle lookup table */
|
|
void *hanger;
|
|
|
|
struct {
|
|
/** table for individual nodes */
|
|
wlfc_mac_descriptor_t nodes[WLFC_MAC_DESC_TABLE_SIZE];
|
|
/** table for interfaces */
|
|
wlfc_mac_descriptor_t interfaces[WLFC_MAX_IFNUM];
|
|
/* OS may send packets to unknown (unassociated) destinations */
|
|
/** A place holder for bc/mc and packets to unknown destinations */
|
|
wlfc_mac_descriptor_t other;
|
|
} destination_entries;
|
|
|
|
/**< a chain of MAC descriptors */
|
|
wlfc_mac_descriptor_t *active_entry_head[WLFC_MAX_GROUPS];
|
|
|
|
int active_entry_count[WLFC_MAX_GROUPS];
|
|
|
|
/* count of active groups */
|
|
int total_credit_groups;
|
|
|
|
wlfc_mac_descriptor_t *requested_entry[WLFC_MAC_DESC_TABLE_SIZE];
|
|
int requested_entry_count;
|
|
|
|
/* pkt counts for each interface and ac */
|
|
int pkt_cnt_in_q[WLFC_MAX_IFNUM][AC_COUNT+1];
|
|
int pkt_cnt_per_ac[AC_COUNT+1];
|
|
int pkt_cnt_in_drv[WLFC_MAX_IFNUM][AC_COUNT+1];
|
|
int pkt_cnt_in_psq;
|
|
uint8 allow_fc; /**< Boolean */
|
|
uint32 fc_defer_timestamp;
|
|
uint32 rx_timestamp[AC_COUNT+1];
|
|
|
|
/** ON/OFF state for flow control to the host network interface */
|
|
uint8 hostif_flow_state[WLFC_MAX_IFNUM];
|
|
uint8 host_ifidx;
|
|
|
|
/** to flow control an OS interface */
|
|
uint8 toggle_host_if;
|
|
|
|
/** To borrow credits */
|
|
uint8 allow_credit_borrow[WLFC_MAX_GROUPS];
|
|
|
|
/** ac number for the first single ac traffic */
|
|
uint8 single_ac[WLFC_MAX_GROUPS];
|
|
|
|
/** Timestamp for the first single ac traffic */
|
|
uint32 single_ac_timestamp[WLFC_MAX_GROUPS];
|
|
|
|
bool bcmc_credit_supported;
|
|
|
|
} athost_wl_status_info_t;
|
|
|
|
/** Please be mindful that total pkttag space is 32 octets only */
|
|
typedef struct dhd_pkttag {
|
|
|
|
#ifdef BCM_OBJECT_TRACE
|
|
/* if use this field, keep it at the first 4 bytes */
|
|
uint32 sn;
|
|
#endif /* BCM_OBJECT_TRACE */
|
|
|
|
/**
|
|
b[15] - 1 = wlfc packet
|
|
b[14:13] - encryption exemption
|
|
b[12 ] - 1 = event channel
|
|
b[11 ] - 1 = this packet was sent in response to one time packet request,
|
|
do not increment credit on status for this one. [WLFC_CTL_TYPE_MAC_REQUEST_PACKET].
|
|
b[10 ] - 1 = signal-only-packet to firmware [i.e. nothing to piggyback on]
|
|
b[9 ] - 1 = packet is host->firmware (transmit direction)
|
|
- 0 = packet received from firmware (firmware->host)
|
|
b[8 ] - 1 = packet was sent due to credit_request (pspoll),
|
|
packet does not count against FIFO credit.
|
|
- 0 = normal transaction, packet counts against FIFO credit
|
|
b[7 ] - 1 = AP, 0 = STA
|
|
b[6:4] - AC FIFO number
|
|
b[3:0] - interface index
|
|
*/
|
|
uint16 if_flags;
|
|
|
|
/**
|
|
* destination MAC address for this packet so that not every module needs to open the packet
|
|
* to find this
|
|
*/
|
|
uint8 dstn_ether[ETHER_ADDR_LEN];
|
|
|
|
/** This 32-bit goes from host to device for every packet. */
|
|
uint32 htod_tag;
|
|
|
|
/** This 16-bit is original seq number for every suppress packet. */
|
|
uint16 htod_seq;
|
|
|
|
/** This address is mac entry for every packet. */
|
|
void *entry;
|
|
|
|
/** bus specific stuff */
|
|
union {
|
|
struct {
|
|
void *stuff;
|
|
uint32 thing1;
|
|
uint32 thing2;
|
|
} sd;
|
|
|
|
struct {
|
|
void *bus;
|
|
void *urb;
|
|
} usb;
|
|
} bus_specific;
|
|
} dhd_pkttag_t;
|
|
|
|
#define DHD_PKTTAG_WLFCPKT_MASK 0x1
|
|
#define DHD_PKTTAG_WLFCPKT_SHIFT 15
|
|
#define DHD_PKTTAG_WLFCPKT_SET(tag, value) ((dhd_pkttag_t*)(tag))->if_flags = \
|
|
(((dhd_pkttag_t*)(tag))->if_flags & \
|
|
~(DHD_PKTTAG_WLFCPKT_MASK << DHD_PKTTAG_WLFCPKT_SHIFT)) | \
|
|
(((value) & DHD_PKTTAG_WLFCPKT_MASK) << DHD_PKTTAG_WLFCPKT_SHIFT)
|
|
#define DHD_PKTTAG_WLFCPKT(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
|
DHD_PKTTAG_WLFCPKT_SHIFT) & DHD_PKTTAG_WLFCPKT_MASK)
|
|
|
|
#define DHD_PKTTAG_EXEMPT_MASK 0x3
|
|
#define DHD_PKTTAG_EXEMPT_SHIFT 13
|
|
#define DHD_PKTTAG_EXEMPT_SET(tag, value) ((dhd_pkttag_t*)(tag))->if_flags = \
|
|
(((dhd_pkttag_t*)(tag))->if_flags & \
|
|
~(DHD_PKTTAG_EXEMPT_MASK << DHD_PKTTAG_EXEMPT_SHIFT)) | \
|
|
(((value) & DHD_PKTTAG_EXEMPT_MASK) << DHD_PKTTAG_EXEMPT_SHIFT)
|
|
#define DHD_PKTTAG_EXEMPT(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
|
DHD_PKTTAG_EXEMPT_SHIFT) & DHD_PKTTAG_EXEMPT_MASK)
|
|
|
|
#define DHD_PKTTAG_EVENT_MASK 0x1
|
|
#define DHD_PKTTAG_EVENT_SHIFT 12
|
|
#define DHD_PKTTAG_SETEVENT(tag, event) ((dhd_pkttag_t*)(tag))->if_flags = \
|
|
(((dhd_pkttag_t*)(tag))->if_flags & \
|
|
~(DHD_PKTTAG_EVENT_MASK << DHD_PKTTAG_EVENT_SHIFT)) | \
|
|
(((event) & DHD_PKTTAG_EVENT_MASK) << DHD_PKTTAG_EVENT_SHIFT)
|
|
#define DHD_PKTTAG_EVENT(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
|
DHD_PKTTAG_EVENT_SHIFT) & DHD_PKTTAG_EVENT_MASK)
|
|
|
|
#define DHD_PKTTAG_ONETIMEPKTRQST_MASK 0x1
|
|
#define DHD_PKTTAG_ONETIMEPKTRQST_SHIFT 11
|
|
#define DHD_PKTTAG_SETONETIMEPKTRQST(tag) ((dhd_pkttag_t*)(tag))->if_flags = \
|
|
(((dhd_pkttag_t*)(tag))->if_flags & \
|
|
~(DHD_PKTTAG_ONETIMEPKTRQST_MASK << DHD_PKTTAG_ONETIMEPKTRQST_SHIFT)) | \
|
|
(1 << DHD_PKTTAG_ONETIMEPKTRQST_SHIFT)
|
|
#define DHD_PKTTAG_ONETIMEPKTRQST(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
|
DHD_PKTTAG_ONETIMEPKTRQST_SHIFT) & DHD_PKTTAG_ONETIMEPKTRQST_MASK)
|
|
|
|
#define DHD_PKTTAG_SIGNALONLY_MASK 0x1
|
|
#define DHD_PKTTAG_SIGNALONLY_SHIFT 10
|
|
#define DHD_PKTTAG_SETSIGNALONLY(tag, signalonly) ((dhd_pkttag_t*)(tag))->if_flags = \
|
|
(((dhd_pkttag_t*)(tag))->if_flags & \
|
|
~(DHD_PKTTAG_SIGNALONLY_MASK << DHD_PKTTAG_SIGNALONLY_SHIFT)) | \
|
|
(((signalonly) & DHD_PKTTAG_SIGNALONLY_MASK) << DHD_PKTTAG_SIGNALONLY_SHIFT)
|
|
#define DHD_PKTTAG_SIGNALONLY(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
|
DHD_PKTTAG_SIGNALONLY_SHIFT) & DHD_PKTTAG_SIGNALONLY_MASK)
|
|
|
|
#define DHD_PKTTAG_PKTDIR_MASK 0x1
|
|
#define DHD_PKTTAG_PKTDIR_SHIFT 9
|
|
#define DHD_PKTTAG_SETPKTDIR(tag, dir) ((dhd_pkttag_t*)(tag))->if_flags = \
|
|
(((dhd_pkttag_t*)(tag))->if_flags & \
|
|
~(DHD_PKTTAG_PKTDIR_MASK << DHD_PKTTAG_PKTDIR_SHIFT)) | \
|
|
(((dir) & DHD_PKTTAG_PKTDIR_MASK) << DHD_PKTTAG_PKTDIR_SHIFT)
|
|
#define DHD_PKTTAG_PKTDIR(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
|
DHD_PKTTAG_PKTDIR_SHIFT) & DHD_PKTTAG_PKTDIR_MASK)
|
|
|
|
#define DHD_PKTTAG_CREDITCHECK_MASK 0x1
|
|
#define DHD_PKTTAG_CREDITCHECK_SHIFT 8
|
|
#define DHD_PKTTAG_SETCREDITCHECK(tag, check) ((dhd_pkttag_t*)(tag))->if_flags = \
|
|
(((dhd_pkttag_t*)(tag))->if_flags & \
|
|
~(DHD_PKTTAG_CREDITCHECK_MASK << DHD_PKTTAG_CREDITCHECK_SHIFT)) | \
|
|
(((check) & DHD_PKTTAG_CREDITCHECK_MASK) << DHD_PKTTAG_CREDITCHECK_SHIFT)
|
|
#define DHD_PKTTAG_CREDITCHECK(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
|
DHD_PKTTAG_CREDITCHECK_SHIFT) & DHD_PKTTAG_CREDITCHECK_MASK)
|
|
|
|
#define DHD_PKTTAG_IFTYPE_MASK 0x1
|
|
#define DHD_PKTTAG_IFTYPE_SHIFT 7
|
|
#define DHD_PKTTAG_SETIFTYPE(tag, isAP) ((dhd_pkttag_t*)(tag))->if_flags = \
|
|
(((dhd_pkttag_t*)(tag))->if_flags & \
|
|
~(DHD_PKTTAG_IFTYPE_MASK << DHD_PKTTAG_IFTYPE_SHIFT)) | \
|
|
(((isAP) & DHD_PKTTAG_IFTYPE_MASK) << DHD_PKTTAG_IFTYPE_SHIFT)
|
|
#define DHD_PKTTAG_IFTYPE(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
|
DHD_PKTTAG_IFTYPE_SHIFT) & DHD_PKTTAG_IFTYPE_MASK)
|
|
|
|
#define DHD_PKTTAG_FIFO_MASK 0x7
|
|
#define DHD_PKTTAG_FIFO_SHIFT 4
|
|
#define DHD_PKTTAG_SETFIFO(tag, fifo) ((dhd_pkttag_t*)(tag))->if_flags = \
|
|
(((dhd_pkttag_t*)(tag))->if_flags & ~(DHD_PKTTAG_FIFO_MASK << DHD_PKTTAG_FIFO_SHIFT)) | \
|
|
(((fifo) & DHD_PKTTAG_FIFO_MASK) << DHD_PKTTAG_FIFO_SHIFT)
|
|
#define DHD_PKTTAG_FIFO(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
|
DHD_PKTTAG_FIFO_SHIFT) & DHD_PKTTAG_FIFO_MASK)
|
|
|
|
#define DHD_PKTTAG_IF_MASK 0xf
|
|
#define DHD_PKTTAG_IF_SHIFT 0
|
|
#define DHD_PKTTAG_SETIF(tag, if) ((dhd_pkttag_t*)(tag))->if_flags = \
|
|
(((dhd_pkttag_t*)(tag))->if_flags & ~(DHD_PKTTAG_IF_MASK << DHD_PKTTAG_IF_SHIFT)) | \
|
|
(((if) & DHD_PKTTAG_IF_MASK) << DHD_PKTTAG_IF_SHIFT)
|
|
#define DHD_PKTTAG_IF(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
|
DHD_PKTTAG_IF_SHIFT) & DHD_PKTTAG_IF_MASK)
|
|
|
|
#define DHD_PKTTAG_SETDSTN(tag, dstn_MAC_ea) memcpy(((dhd_pkttag_t*)((tag)))->dstn_ether, \
|
|
(dstn_MAC_ea), ETHER_ADDR_LEN)
|
|
#define DHD_PKTTAG_DSTN(tag) ((dhd_pkttag_t*)(tag))->dstn_ether
|
|
|
|
#define DHD_PKTTAG_SET_H2DTAG(tag, h2dvalue) ((dhd_pkttag_t*)(tag))->htod_tag = (h2dvalue)
|
|
#define DHD_PKTTAG_H2DTAG(tag) (((dhd_pkttag_t*)(tag))->htod_tag)
|
|
|
|
#define DHD_PKTTAG_SET_H2DSEQ(tag, seq) ((dhd_pkttag_t*)(tag))->htod_seq = (seq)
|
|
#define DHD_PKTTAG_H2DSEQ(tag) (((dhd_pkttag_t*)(tag))->htod_seq)
|
|
|
|
#define DHD_PKTTAG_SET_ENTRY(tag, entry) ((dhd_pkttag_t*)(tag))->entry = (entry)
|
|
#define DHD_PKTTAG_ENTRY(tag) (((dhd_pkttag_t*)(tag))->entry)
|
|
|
|
#define PSQ_SUP_IDX(x) (x * 2 + 1)
|
|
#define PSQ_DLY_IDX(x) (x * 2)
|
|
|
|
#ifdef PROP_TXSTATUS_DEBUG
|
|
#define DHD_WLFC_CTRINC_MAC_CLOSE(entry) do { (entry)->closed_ct++; } while (0)
|
|
#define DHD_WLFC_CTRINC_MAC_OPEN(entry) do { (entry)->opened_ct++; } while (0)
|
|
#else
|
|
#define DHD_WLFC_CTRINC_MAC_CLOSE(entry) do {} while (0)
|
|
#define DHD_WLFC_CTRINC_MAC_OPEN(entry) do {} while (0)
|
|
#endif
|
|
|
|
#ifdef BCM_OBJECT_TRACE
|
|
#define DHD_PKTTAG_SET_SN(tag, val) ((dhd_pkttag_t*)(tag))->sn = (val)
|
|
#define DHD_PKTTAG_SN(tag) (((dhd_pkttag_t*)(tag))->sn)
|
|
#endif /* BCM_OBJECT_TRACE */
|
|
|
|
/* public functions */
|
|
int dhd_wlfc_parse_header_info(dhd_pub_t *dhd, void* pktbuf, int tlv_hdr_len,
|
|
uchar *reorder_info_buf, uint *reorder_info_len);
|
|
KERNEL_THREAD_RETURN_TYPE dhd_wlfc_transfer_packets(void *data);
|
|
int dhd_wlfc_commit_packets(dhd_pub_t *dhdp, f_commitpkt_t fcommit,
|
|
void* commit_ctx, void *pktbuf, bool need_toggle_host_if);
|
|
int dhd_wlfc_txcomplete(dhd_pub_t *dhd, void *txp, bool success);
|
|
int dhd_wlfc_init(dhd_pub_t *dhd);
|
|
#ifdef SUPPORT_P2P_GO_PS
|
|
int dhd_wlfc_suspend(dhd_pub_t *dhd);
|
|
int dhd_wlfc_resume(dhd_pub_t *dhd);
|
|
#endif /* SUPPORT_P2P_GO_PS */
|
|
int dhd_wlfc_hostreorder_init(dhd_pub_t *dhd);
|
|
int dhd_wlfc_cleanup_txq(dhd_pub_t *dhd, f_processpkt_t fn, void *arg);
|
|
int dhd_wlfc_cleanup(dhd_pub_t *dhd, f_processpkt_t fn, void* arg);
|
|
int dhd_wlfc_deinit(dhd_pub_t *dhd);
|
|
int dhd_wlfc_interface_event(dhd_pub_t *dhdp, uint8 action, uint8 ifid, uint8 iftype, uint8* ea);
|
|
int dhd_wlfc_update_interface_credit_group(dhd_pub_t *dhdp, uint8 ifid, uint8 action,
|
|
uint8 credit_group);
|
|
int dhd_wlfc_FIFOcreditmap_event(dhd_pub_t *dhdp, uint8* event_data, uint32 evt_datalen);
|
|
int dhd_wlfc_BCMCCredit_support_event(dhd_pub_t *dhdp);
|
|
int dhd_wlfc_enable(dhd_pub_t *dhdp);
|
|
int dhd_wlfc_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
|
|
int dhd_wlfc_clear_counts(dhd_pub_t *dhd);
|
|
int dhd_wlfc_get_enable(dhd_pub_t *dhd, bool *val);
|
|
int dhd_wlfc_get_mode(dhd_pub_t *dhd, int *val);
|
|
int dhd_wlfc_set_mode(dhd_pub_t *dhd, int val);
|
|
bool dhd_wlfc_is_supported(dhd_pub_t *dhd);
|
|
bool dhd_wlfc_is_header_only_pkt(dhd_pub_t * dhd, void *pktbuf);
|
|
int dhd_wlfc_flowcontrol(dhd_pub_t *dhdp, bool state, bool bAcquireLock);
|
|
int dhd_wlfc_save_rxpath_ac_time(dhd_pub_t * dhd, uint8 prio);
|
|
|
|
int dhd_wlfc_get_module_ignore(dhd_pub_t *dhd, int *val);
|
|
int dhd_wlfc_set_module_ignore(dhd_pub_t *dhd, int val);
|
|
int dhd_wlfc_get_credit_ignore(dhd_pub_t *dhd, int *val);
|
|
int dhd_wlfc_set_credit_ignore(dhd_pub_t *dhd, int val);
|
|
int dhd_wlfc_get_txstatus_ignore(dhd_pub_t *dhd, int *val);
|
|
int dhd_wlfc_set_txstatus_ignore(dhd_pub_t *dhd, int val);
|
|
|
|
int dhd_wlfc_get_rxpkt_chk(dhd_pub_t *dhd, int *val);
|
|
int dhd_wlfc_set_rxpkt_chk(dhd_pub_t *dhd, int val);
|
|
|
|
#endif /* __wlfc_host_driver_definitions_h__ */
|