162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright (c) 2014, Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Permission to use, copy, modify, and/or distribute this software for any
562306a36Sopenharmony_ci * purpose with or without fee is hereby granted, provided that the above
662306a36Sopenharmony_ci * copyright notice and this permission notice appear in all copies.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
962306a36Sopenharmony_ci * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1062306a36Sopenharmony_ci * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1162306a36Sopenharmony_ci * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1262306a36Sopenharmony_ci * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1362306a36Sopenharmony_ci * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1462306a36Sopenharmony_ci * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1562306a36Sopenharmony_ci */
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#ifndef DYNACK_H
1862306a36Sopenharmony_ci#define DYNACK_H
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#define ATH_DYN_BUF	64
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistruct ath_hw;
2362306a36Sopenharmony_cistruct ath_node;
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci/**
2662306a36Sopenharmony_ci * struct ath_dyn_rxbuf - ACK frame ring buffer
2762306a36Sopenharmony_ci * @h_rb: ring buffer head
2862306a36Sopenharmony_ci * @t_rb: ring buffer tail
2962306a36Sopenharmony_ci * @tstamp: ACK RX timestamp buffer
3062306a36Sopenharmony_ci */
3162306a36Sopenharmony_cistruct ath_dyn_rxbuf {
3262306a36Sopenharmony_ci	u16 h_rb, t_rb;
3362306a36Sopenharmony_ci	u32 tstamp[ATH_DYN_BUF];
3462306a36Sopenharmony_ci};
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_cistruct ts_info {
3762306a36Sopenharmony_ci	u32 tstamp;
3862306a36Sopenharmony_ci	u32 dur;
3962306a36Sopenharmony_ci};
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_cistruct haddr_pair {
4262306a36Sopenharmony_ci	u8 h_dest[ETH_ALEN];
4362306a36Sopenharmony_ci	u8 h_src[ETH_ALEN];
4462306a36Sopenharmony_ci};
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/**
4762306a36Sopenharmony_ci * struct ath_dyn_txbuf - tx frame ring buffer
4862306a36Sopenharmony_ci * @h_rb: ring buffer head
4962306a36Sopenharmony_ci * @t_rb: ring buffer tail
5062306a36Sopenharmony_ci * @addr: dest/src address pair for a given TX frame
5162306a36Sopenharmony_ci * @ts: TX frame timestamp buffer
5262306a36Sopenharmony_ci */
5362306a36Sopenharmony_cistruct ath_dyn_txbuf {
5462306a36Sopenharmony_ci	u16 h_rb, t_rb;
5562306a36Sopenharmony_ci	struct haddr_pair addr[ATH_DYN_BUF];
5662306a36Sopenharmony_ci	struct ts_info ts[ATH_DYN_BUF];
5762306a36Sopenharmony_ci};
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci/**
6062306a36Sopenharmony_ci * struct ath_dynack - dynack processing info
6162306a36Sopenharmony_ci * @enabled: enable dyn ack processing
6262306a36Sopenharmony_ci * @ackto: current ACK timeout
6362306a36Sopenharmony_ci * @lto: last ACK timeout computation
6462306a36Sopenharmony_ci * @nodes: ath_node linked list
6562306a36Sopenharmony_ci * @qlock: ts queue spinlock
6662306a36Sopenharmony_ci * @ack_rbf: ACK ts ring buffer
6762306a36Sopenharmony_ci * @st_rbf: status ts ring buffer
6862306a36Sopenharmony_ci */
6962306a36Sopenharmony_cistruct ath_dynack {
7062306a36Sopenharmony_ci	bool enabled;
7162306a36Sopenharmony_ci	int ackto;
7262306a36Sopenharmony_ci	unsigned long lto;
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	struct list_head nodes;
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci	/* protect timestamp queue access */
7762306a36Sopenharmony_ci	spinlock_t qlock;
7862306a36Sopenharmony_ci	struct ath_dyn_rxbuf ack_rbf;
7962306a36Sopenharmony_ci	struct ath_dyn_txbuf st_rbf;
8062306a36Sopenharmony_ci};
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci#if defined(CONFIG_ATH9K_DYNACK)
8362306a36Sopenharmony_civoid ath_dynack_reset(struct ath_hw *ah);
8462306a36Sopenharmony_civoid ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an);
8562306a36Sopenharmony_civoid ath_dynack_node_deinit(struct ath_hw *ah, struct ath_node *an);
8662306a36Sopenharmony_civoid ath_dynack_init(struct ath_hw *ah);
8762306a36Sopenharmony_civoid ath_dynack_sample_ack_ts(struct ath_hw *ah, struct sk_buff *skb, u32 ts);
8862306a36Sopenharmony_civoid ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb,
8962306a36Sopenharmony_ci			     struct ath_tx_status *ts,
9062306a36Sopenharmony_ci			     struct ieee80211_sta *sta);
9162306a36Sopenharmony_ci#else
9262306a36Sopenharmony_cistatic inline void ath_dynack_init(struct ath_hw *ah) {}
9362306a36Sopenharmony_cistatic inline void ath_dynack_node_init(struct ath_hw *ah,
9462306a36Sopenharmony_ci					struct ath_node *an) {}
9562306a36Sopenharmony_cistatic inline void ath_dynack_node_deinit(struct ath_hw *ah,
9662306a36Sopenharmony_ci					  struct ath_node *an) {}
9762306a36Sopenharmony_cistatic inline void ath_dynack_sample_ack_ts(struct ath_hw *ah,
9862306a36Sopenharmony_ci					    struct sk_buff *skb, u32 ts) {}
9962306a36Sopenharmony_cistatic inline void ath_dynack_sample_tx_ts(struct ath_hw *ah,
10062306a36Sopenharmony_ci					   struct sk_buff *skb,
10162306a36Sopenharmony_ci					   struct ath_tx_status *ts,
10262306a36Sopenharmony_ci					   struct ieee80211_sta *sta) {}
10362306a36Sopenharmony_ci#endif
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci#endif /* DYNACK_H */
106