unsigned int rx_total;
unsigned int rx_overruns;
+ /* tx sequence control counters */
+ unsigned int sequence[CARL9170_INTF_NUM];
+
#ifdef CONFIG_CARL9170FW_TX_AMPDU
/* tx aggregate scheduling */
struct carl9170_tx_superframe *ampdu_prev[__AR9170_NUM_TX_QUEUES];
struct carl9170_firmware_descriptor {
struct carl9170fw_otus_desc otus;
+ struct carl9170fw_txsq_desc txsq;
struct carl9170fw_motd_desc motd;
struct carl9170fw_dbg_desc dbg;
struct carl9170fw_last_desc last;
void handle_wlan(void);
void wlan_cab_flush_queue(const unsigned int vif);
-void wlan_cab_modify_dtim_beacon(const unsigned int vif,
- const unsigned int bcn_addr,
- const unsigned int bcn_len);
+void wlan_modify_beacon(const unsigned int vif,
+ const unsigned int bcn_addr,
+ const unsigned int bcn_len);
static inline void wlan_prepare_wol(void)
{
resp->hdr.len = 0;
if (cmd->bcn_ctrl.mode & CARL9170_BCN_CTRL_CAB_TRIGGER) {
- wlan_cab_modify_dtim_beacon(cmd->bcn_ctrl.vif_id,
+ wlan_modify_beacon(cmd->bcn_ctrl.vif_id,
cmd->bcn_ctrl.bcn_addr, cmd->bcn_ctrl.bcn_len);
set(AR9170_MAC_REG_BCN_ADDR, cmd->bcn_ctrl.bcn_addr);
set(AR9170_MAC_REG_BCN_LENGTH, cmd->bcn_ctrl.bcn_len);
.api_ver = CONFIG_CARL9170FW_RELEASE_VERSION,
),
+ FILL(txsq, TXSQ,
+ .seq_table_addr = cpu_to_le32(&fw.wlan.sequence),
+ ),
+
FILL(motd, MOTD,
.fw_year_month_day = cpu_to_le32(
CARL9170FW_SET_DAY(CARL9170FW_VERSION_DAY) +
#endif /* CONFIG_CARL9170FW_LOOPBACK */
}
+static void wlan_assign_seq(struct ieee80211_hdr *hdr, unsigned int vif)
+{
+ hdr->seq_ctrl &= cpu_to_le16(~IEEE80211_SCTL_SEQ);
+ hdr->seq_ctrl |= cpu_to_le16(fw.wlan.sequence[vif]);
+
+ if (!(hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)))
+ fw.wlan.sequence[vif] += 0x10;
+}
+
/* prepares frame for the first transmission */
static void _wlan_tx(struct dma_desc *desc)
{
struct carl9170_tx_superframe *super = get_super(desc);
+ if (unlikely(super->s.assign_seq)) {
+ wlan_assign_seq(&super->f.data.i3e, super->s.vif_id);
+ }
+
if (unlikely(super->s.ampdu_commit_density)) {
set(AR9170_MAC_REG_AMPDU_DENSITY,
MOD_VAL(AR9170_MAC_AMPDU_DENSITY,
return NULL;
}
-void wlan_cab_modify_dtim_beacon(const unsigned int vif,
+void wlan_modify_beacon(const unsigned int vif,
const unsigned int addr, const unsigned int len)
{
uint8_t *_ie;
ie->bitmap_ctrl |= 0x1;
}
}
+
+ /*
+ * Ideally, the sequence number should be assigned by the TX arbiter
+ * hardware. But AFAIK that's not possible, so we have to go for the
+ * next best thing and write it into the beacon fifo during the open
+ * beacon update window.
+ */
+
+ wlan_assign_seq((struct ieee80211_hdr *)addr, vif);
}
#endif /* CONFIG_CARL9170FW_CAB_QUEUE */
bcn_count = get(AR9170_MAC_REG_BCN_COUNT);
send_cmd_to_host(4, CARL9170_RSP_BEACON_CONFIG, 0x00,
(uint8_t *) &bcn_count);
-
- set(AR9170_MAC_REG_BCN_CTRL, AR9170_BCN_CTRL_READY);
}
static void handle_pretbtt(void)
#define FIX_MAGIC "FIX\0"
#define DBG_MAGIC "DBG\0"
#define CHK_MAGIC "CHK\0"
+#define TXSQ_MAGIC "TXSQ"
#define LAST_MAGIC "LAST"
#define CARL9170FW_SET_DAY(d) (((d) - 1) % 31)
#define CARL9170FW_CHK_DESC_SIZE \
(sizeof(struct carl9170fw_chk_desc))
+#define CARL9170FW_TXSQ_DESC_MIN_VER 1
+#define CARL9170FW_TXSQ_DESC_CUR_VER 1
+struct carl9170fw_txsq_desc {
+ struct carl9170fw_desc_head head;
+
+ __le32 seq_table_addr;
+} __packed;
+#define CARL9170FW_TXSQ_DESC_SIZE \
+ (sizeof(struct carl9170fw_txsq_desc))
+
#define CARL9170FW_LAST_DESC_MIN_VER 1
#define CARL9170FW_LAST_DESC_CUR_VER 2
struct carl9170fw_last_desc {
#define __CARL9170_SHARED_VERSION_H
#define CARL9170FW_VERSION_YEAR 11
#define CARL9170FW_VERSION_MONTH 1
-#define CARL9170FW_VERSION_DAY 15
+#define CARL9170FW_VERSION_DAY 22
#define CARL9170FW_VERSION_GIT "1.9.2"
#endif /* __CARL9170_SHARED_VERSION_H */
u8 ampdu_commit_factor:1;
u8 ampdu_unused_bit:1;
u8 queue:2;
- u8 reserved:1;
+ u8 assign_seq:1;
u8 vif_id:3;
u8 fill_in_tsf:1;
u8 cab:1;
#define CARL9170_TX_SUPER_MISC_QUEUE 0x3
#define CARL9170_TX_SUPER_MISC_QUEUE_S 0
+#define CARL9170_TX_SUPER_MISC_ASSIGN_SEQ 0x4
#define CARL9170_TX_SUPER_MISC_VIF_ID 0x38
#define CARL9170_TX_SUPER_MISC_VIF_ID_S 3
#define CARL9170_TX_SUPER_MISC_FILL_IN_TSF 0x40
DBG_ADDR("rx filer ", rx_filter);
}
+static void show_txsq_desc(const struct carl9170fw_desc_head *head,
+ struct carlfw *fw __unused)
+{
+ const struct carl9170fw_txsq_desc *txsq = (const void *) head;
+
+ fprintf(stdout, "\t\ttx-seq table addr: 0x%x\n",
+ le32_to_cpu(txsq->seq_table_addr));
+}
+
static void show_chk_desc(const struct carl9170fw_desc_head *head,
struct carlfw *fw __unused)
{
uint16_t size;
} known_magics[] = {
ADD_HANDLER(OTUS, show_otus_desc),
+ ADD_HANDLER(TXSQ, show_txsq_desc),
ADD_HANDLER(MOTD, show_motd_desc),
ADD_HANDLER(DBG, show_dbg_desc),
ADD_HANDLER(FIX, show_fix_desc),