+
+static void wlan_wol_connect_callback(void __unused *dummy, bool success)
+{
+ if (success)
+ fw.wlan.wol.lost_null = 0;
+ else
+ fw.wlan.wol.lost_null++;
+}
+
+static void wlan_wol_connection_monitor(void)
+{
+ struct carl9170_tx_null_superframe *nullf = &dma_mem.reserved.cmd.null;
+ struct ieee80211_hdr *null = (struct ieee80211_hdr *) &nullf->f.null;
+
+ if (!fw.wlan.fw_desc_available)
+ return;
+
+ memset(nullf, 0, sizeof(nullf));
+
+ nullf->s.len = sizeof(struct carl9170_tx_superdesc) +
+ sizeof(struct ar9170_tx_hwdesc) +
+ sizeof(struct ieee80211_hdr);
+ nullf->s.ri[0].tries = 3;
+ nullf->s.assign_seq = true;
+ nullf->s.queue = AR9170_TXQ_VO;
+ nullf->f.hdr.length = sizeof(struct ieee80211_hdr) + FCS_LEN;
+
+ nullf->f.hdr.mac.backoff = 1;
+ nullf->f.hdr.mac.hw_duration = 1;
+ nullf->f.hdr.mac.erp_prot = AR9170_TX_MAC_PROT_RTS;
+
+ nullf->f.hdr.phy.modulation = AR9170_TX_PHY_MOD_OFDM;
+ nullf->f.hdr.phy.bandwidth = AR9170_TX_PHY_BW_20MHZ;
+ nullf->f.hdr.phy.chains = AR9170_TX_PHY_TXCHAIN_2;
+ nullf->f.hdr.phy.tx_power = 29; /* 14.5 dBm */
+ nullf->f.hdr.phy.mcs = AR9170_TXRX_PHY_RATE_OFDM_6M;
+
+ /* format outgoing nullfunc */
+ null->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
+ IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS);
+
+ memcpy(null->addr1, fw.wlan.wol.cmd.bssid, 6);
+ memcpy(null->addr2, fw.wlan.wol.cmd.mac, 6);
+ memcpy(null->addr3, fw.wlan.wol.cmd.bssid, 6);
+
+ wlan_tx_fw(&nullf->s, wlan_wol_connect_callback);
+}
+
+static bool wlan_rx_wol_disconnect(const unsigned int rx_filter,
+ struct ieee80211_hdr *hdr,
+ unsigned int __unused len)
+{
+ const unsigned char *bssid;
+ bssid = (const unsigned char *) AR9170_MAC_REG_BSSID_L;
+
+ /* should catch both broadcast and unicast MLMEs */
+ if (!(rx_filter & CARL9170_RX_FILTER_OTHER_RA)) {
+ if (ieee80211_is_deauth(hdr->frame_control) ||
+ ieee80211_is_disassoc(hdr->frame_control))
+ return true;
+ }
+
+ if (ieee80211_is_beacon(hdr->frame_control) &&
+ compare_ether_address(hdr->addr3, bssid)) {
+ fw.wlan.wol.last_beacon = get_clock_counter();
+ }
+
+ return false;
+}
+
+#endif /* CARL9170FW_WOL_NL80211_TRIGGERS */