Lines Matching +full:ieee80211 +full:- +full:freq +full:- +full:limit
48 /* Host->device communications */
59 /* Device->host communications */
104 #define mwl8k_tx_queues(priv) (MWL8K_TX_WMM_QUEUES + (priv)->num_ampdu_queues)
116 #define MWL8K_NUM_AMPDU_STREAMS (TOTAL_HW_TX_QUEUES - 1)
331 #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
346 #define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))
420 #define MWL8K_CMD_SET_BEACON 0x0100 /* per-vif */
434 #define MWL8K_CMD_SET_MAC_ADDR 0x0202 /* per-vif */
437 #define MWL8K_CMD_DEL_MAC_ADDR 0x0206 /* per-vif */
438 #define MWL8K_CMD_BSS_START 0x1100 /* per-vif */
439 #define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */
440 #define MWL8K_CMD_UPDATE_ENCRYPTION 0x1122 /* per-vif */
445 (ARRAY_SIZE(mwl8k_rates_24) - ARRAY_SIZE(mwl8k_rates_50))
499 priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS); in mwl8k_hw_reset()
501 priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS); in mwl8k_hw_reset()
516 mwl8k_release_fw(&priv->fw_ucode); in mwl8k_release_firmware()
517 mwl8k_release_fw(&priv->fw_helper); in mwl8k_release_firmware()
540 &priv->pdev->dev, GFP_KERNEL, in mwl8k_request_fw()
543 return request_firmware(fw, fname, &priv->pdev->dev); in mwl8k_request_fw()
549 struct mwl8k_device_info *di = priv->device_info; in mwl8k_request_firmware()
552 if (di->helper_image != NULL) { in mwl8k_request_firmware()
554 rc = mwl8k_request_fw(priv, di->helper_image, in mwl8k_request_firmware()
555 &priv->fw_helper, true); in mwl8k_request_firmware()
557 rc = mwl8k_request_fw(priv, di->helper_image, in mwl8k_request_firmware()
558 &priv->fw_helper, false); in mwl8k_request_firmware()
561 pci_name(priv->pdev), di->helper_image); in mwl8k_request_firmware()
572 priv->fw_state = FW_STATE_LOADING_PREF; in mwl8k_request_firmware()
574 &priv->fw_ucode, in mwl8k_request_firmware()
578 &priv->fw_ucode, false); in mwl8k_request_firmware()
581 pci_name(priv->pdev), fw_image); in mwl8k_request_firmware()
582 mwl8k_release_fw(&priv->fw_helper); in mwl8k_request_firmware()
609 void __iomem *regs = priv->regs; in mwl8k_send_fw_load_cmd()
613 dma_addr = dma_map_single(&priv->pdev->dev, data, length, in mwl8k_send_fw_load_cmd()
615 if (dma_mapping_error(&priv->pdev->dev, dma_addr)) in mwl8k_send_fw_load_cmd()
616 return -ENOMEM; in mwl8k_send_fw_load_cmd()
628 if (priv->is_8764) { in mwl8k_send_fw_load_cmd()
642 } while (--loops); in mwl8k_send_fw_load_cmd()
644 dma_unmap_single(&priv->pdev->dev, dma_addr, length, DMA_TO_DEVICE); in mwl8k_send_fw_load_cmd()
646 return loops ? 0 : -ETIMEDOUT; in mwl8k_send_fw_load_cmd()
658 return -ENOMEM; in mwl8k_load_fw_image()
660 cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD); in mwl8k_load_fw_image()
661 cmd->seq_num = 0; in mwl8k_load_fw_image()
662 cmd->macid = 0; in mwl8k_load_fw_image()
663 cmd->result = 0; in mwl8k_load_fw_image()
669 memcpy(cmd->payload, data + done, block_size); in mwl8k_load_fw_image()
670 cmd->length = cpu_to_le16(block_size); in mwl8k_load_fw_image()
678 length -= block_size; in mwl8k_load_fw_image()
682 cmd->length = 0; in mwl8k_load_fw_image()
700 return -ENOMEM; in mwl8k_feed_fw_image()
708 block_size = ioread32(priv->regs + MWL8K_HIU_SCRATCH); in mwl8k_feed_fw_image()
711 may_continue--; in mwl8k_feed_fw_image()
714 length -= prev_block_size; in mwl8k_feed_fw_image()
718 rc = -EOVERFLOW; in mwl8k_feed_fw_image()
728 rc = -EPROTO; in mwl8k_feed_fw_image()
729 may_continue--; in mwl8k_feed_fw_image()
743 rc = -EREMOTEIO; in mwl8k_feed_fw_image()
752 struct mwl8k_priv *priv = hw->priv; in mwl8k_load_firmware()
753 const struct firmware *fw = priv->fw_ucode; in mwl8k_load_firmware()
757 if (!memcmp(fw->data, "\x01\x00\x00\x00", 4) && !priv->is_8764) { in mwl8k_load_firmware()
758 const struct firmware *helper = priv->fw_helper; in mwl8k_load_firmware()
762 "given\n", pci_name(priv->pdev)); in mwl8k_load_firmware()
763 return -EINVAL; in mwl8k_load_firmware()
766 rc = mwl8k_load_fw_image(priv, helper->data, helper->size); in mwl8k_load_firmware()
769 "helper image\n", pci_name(priv->pdev)); in mwl8k_load_firmware()
774 rc = mwl8k_feed_fw_image(priv, fw->data, fw->size); in mwl8k_load_firmware()
776 if (priv->is_8764) in mwl8k_load_firmware()
777 rc = mwl8k_feed_fw_image(priv, fw->data, fw->size); in mwl8k_load_firmware()
779 rc = mwl8k_load_fw_image(priv, fw->data, fw->size); in mwl8k_load_firmware()
784 pci_name(priv->pdev)); in mwl8k_load_firmware()
788 iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR); in mwl8k_load_firmware()
794 ready_code = ioread32(priv->regs + MWL8K_HIU_INT_CODE); in mwl8k_load_firmware()
796 priv->ap_fw = true; in mwl8k_load_firmware()
799 priv->ap_fw = false; in mwl8k_load_firmware()
805 } while (--loops); in mwl8k_load_firmware()
807 return loops ? 0 : -ETIMEDOUT; in mwl8k_load_firmware()
824 tr = (struct mwl8k_dma_data *)skb->data; in mwl8k_remove_dma_header()
825 hdrlen = ieee80211_hdrlen(tr->wh.frame_control); in mwl8k_remove_dma_header()
827 if (hdrlen != sizeof(tr->wh)) { in mwl8k_remove_dma_header()
828 if (ieee80211_is_data_qos(tr->wh.frame_control)) { in mwl8k_remove_dma_header()
829 memmove(tr->data - hdrlen, &tr->wh, hdrlen - 2); in mwl8k_remove_dma_header()
830 *((__le16 *)(tr->data - 2)) = qos; in mwl8k_remove_dma_header()
832 memmove(tr->data - hdrlen, &tr->wh, hdrlen); in mwl8k_remove_dma_header()
837 skb_pull(skb, sizeof(*tr) - hdrlen); in mwl8k_remove_dma_header()
853 * present a 2-byte payload length followed by a 4-address in mwl8k_add_dma_header()
857 wh = (struct ieee80211_hdr *)skb->data; in mwl8k_add_dma_header()
859 hdrlen = ieee80211_hdrlen(wh->frame_control); in mwl8k_add_dma_header()
865 if (priv->ap_fw && (hdrlen < (sizeof(struct ieee80211_cts) in mwl8k_add_dma_header()
869 wiphy_err(priv->hw->wiphy, in mwl8k_add_dma_header()
873 skb->truesize += REDUCED_TX_HEADROOM; in mwl8k_add_dma_header()
879 skb_push(skb, reqd_hdrlen - hdrlen); in mwl8k_add_dma_header()
881 if (ieee80211_is_data_qos(wh->frame_control)) in mwl8k_add_dma_header()
882 hdrlen -= IEEE80211_QOS_CTL_LEN; in mwl8k_add_dma_header()
884 tr = (struct mwl8k_dma_data *)skb->data; in mwl8k_add_dma_header()
885 if (wh != &tr->wh) in mwl8k_add_dma_header()
886 memmove(&tr->wh, wh, hdrlen); in mwl8k_add_dma_header()
887 if (hdrlen != sizeof(tr->wh)) in mwl8k_add_dma_header()
888 memset(((void *)&tr->wh) + hdrlen, 0, sizeof(tr->wh) - hdrlen); in mwl8k_add_dma_header()
895 tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad); in mwl8k_add_dma_header()
907 wh = (struct ieee80211_hdr *)skb->data; in mwl8k_encapsulate_tx_frame()
912 if (ieee80211_is_data(wh->frame_control)) in mwl8k_encapsulate_tx_frame()
913 key_conf = tx_info->control.hw_key; in mwl8k_encapsulate_tx_frame()
916 * Make sure the packet header is in the DMA header format (4-address in mwl8k_encapsulate_tx_frame()
920 * - WEP: 4 trailer bytes (ICV) in mwl8k_encapsulate_tx_frame()
921 * - TKIP: 12 trailer bytes (8 MIC + 4 ICV) in mwl8k_encapsulate_tx_frame()
922 * - CCMP: 8 trailer bytes (MIC) in mwl8k_encapsulate_tx_frame()
926 head_pad = key_conf->iv_len; in mwl8k_encapsulate_tx_frame()
927 switch (key_conf->cipher) { in mwl8k_encapsulate_tx_frame()
981 rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr); in mwl8k_rxd_ap_init()
982 rxd->rx_ctrl = MWL8K_AP_RX_CTRL_OWNED_BY_HOST; in mwl8k_rxd_ap_init()
989 rxd->pkt_len = cpu_to_le16(len); in mwl8k_rxd_ap_refill()
990 rxd->pkt_phys_addr = cpu_to_le32(addr); in mwl8k_rxd_ap_refill()
992 rxd->rx_ctrl = 0; in mwl8k_rxd_ap_refill()
1001 if (!(rxd->rx_ctrl & MWL8K_AP_RX_CTRL_OWNED_BY_HOST)) in mwl8k_rxd_ap_process()
1002 return -1; in mwl8k_rxd_ap_process()
1007 status->signal = -rxd->rssi; in mwl8k_rxd_ap_process()
1008 *noise = -rxd->noise_floor; in mwl8k_rxd_ap_process()
1010 if (rxd->rate & MWL8K_AP_RATE_INFO_MCS_FORMAT) { in mwl8k_rxd_ap_process()
1011 status->encoding = RX_ENC_HT; in mwl8k_rxd_ap_process()
1012 if (rxd->rate & MWL8K_AP_RATE_INFO_40MHZ) in mwl8k_rxd_ap_process()
1013 status->bw = RATE_INFO_BW_40; in mwl8k_rxd_ap_process()
1014 status->rate_idx = MWL8K_AP_RATE_INFO_RATEID(rxd->rate); in mwl8k_rxd_ap_process()
1019 if (mwl8k_rates_24[i].hw_value == rxd->rate) { in mwl8k_rxd_ap_process()
1020 status->rate_idx = i; in mwl8k_rxd_ap_process()
1026 if (rxd->channel > 14) { in mwl8k_rxd_ap_process()
1027 status->band = NL80211_BAND_5GHZ; in mwl8k_rxd_ap_process()
1028 if (!(status->encoding == RX_ENC_HT) && in mwl8k_rxd_ap_process()
1029 status->rate_idx >= MWL8K_LEGACY_5G_RATE_OFFSET) in mwl8k_rxd_ap_process()
1030 status->rate_idx -= MWL8K_LEGACY_5G_RATE_OFFSET; in mwl8k_rxd_ap_process()
1032 status->band = NL80211_BAND_2GHZ; in mwl8k_rxd_ap_process()
1034 status->freq = ieee80211_channel_to_frequency(rxd->channel, in mwl8k_rxd_ap_process()
1035 status->band); in mwl8k_rxd_ap_process()
1037 *qos = rxd->qos_control; in mwl8k_rxd_ap_process()
1039 if ((rxd->rx_status != MWL8K_AP_RXSTAT_GENERAL_DECRYPT_ERR) && in mwl8k_rxd_ap_process()
1040 (rxd->rx_status & MWL8K_AP_RXSTAT_DECRYPT_ERR_MASK) && in mwl8k_rxd_ap_process()
1041 (rxd->rx_status & MWL8K_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR)) in mwl8k_rxd_ap_process()
1042 status->flag |= RX_FLAG_MMIC_ERROR; in mwl8k_rxd_ap_process()
1044 return le16_to_cpu(rxd->pkt_len); in mwl8k_rxd_ap_process()
1092 rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr); in mwl8k_rxd_sta_init()
1093 rxd->rx_ctrl = MWL8K_STA_RX_CTRL_OWNED_BY_HOST; in mwl8k_rxd_sta_init()
1100 rxd->pkt_len = cpu_to_le16(len); in mwl8k_rxd_sta_refill()
1101 rxd->pkt_phys_addr = cpu_to_le32(addr); in mwl8k_rxd_sta_refill()
1103 rxd->rx_ctrl = 0; in mwl8k_rxd_sta_refill()
1113 if (!(rxd->rx_ctrl & MWL8K_STA_RX_CTRL_OWNED_BY_HOST)) in mwl8k_rxd_sta_process()
1114 return -1; in mwl8k_rxd_sta_process()
1117 rate_info = le16_to_cpu(rxd->rate_info); in mwl8k_rxd_sta_process()
1121 status->signal = -rxd->rssi; in mwl8k_rxd_sta_process()
1122 *noise = -rxd->noise_level; in mwl8k_rxd_sta_process()
1123 status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info); in mwl8k_rxd_sta_process()
1124 status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info); in mwl8k_rxd_sta_process()
1127 status->enc_flags |= RX_ENC_FLAG_SHORTPRE; in mwl8k_rxd_sta_process()
1129 status->bw = RATE_INFO_BW_40; in mwl8k_rxd_sta_process()
1131 status->enc_flags |= RX_ENC_FLAG_SHORT_GI; in mwl8k_rxd_sta_process()
1133 status->encoding = RX_ENC_HT; in mwl8k_rxd_sta_process()
1135 if (rxd->channel > 14) { in mwl8k_rxd_sta_process()
1136 status->band = NL80211_BAND_5GHZ; in mwl8k_rxd_sta_process()
1137 if (!(status->encoding == RX_ENC_HT) && in mwl8k_rxd_sta_process()
1138 status->rate_idx >= MWL8K_LEGACY_5G_RATE_OFFSET) in mwl8k_rxd_sta_process()
1139 status->rate_idx -= MWL8K_LEGACY_5G_RATE_OFFSET; in mwl8k_rxd_sta_process()
1141 status->band = NL80211_BAND_2GHZ; in mwl8k_rxd_sta_process()
1143 status->freq = ieee80211_channel_to_frequency(rxd->channel, in mwl8k_rxd_sta_process()
1144 status->band); in mwl8k_rxd_sta_process()
1146 *qos = rxd->qos_control; in mwl8k_rxd_sta_process()
1147 if ((rxd->rx_ctrl & MWL8K_STA_RX_CTRL_DECRYPT_ERROR) && in mwl8k_rxd_sta_process()
1148 (rxd->rx_ctrl & MWL8K_STA_RX_CTRL_DEC_ERR_TYPE)) in mwl8k_rxd_sta_process()
1149 status->flag |= RX_FLAG_MMIC_ERROR; in mwl8k_rxd_sta_process()
1151 return le16_to_cpu(rxd->pkt_len); in mwl8k_rxd_sta_process()
1167 struct mwl8k_priv *priv = hw->priv; in mwl8k_rxq_init()
1168 struct mwl8k_rx_queue *rxq = priv->rxq + index; in mwl8k_rxq_init()
1172 rxq->rxd_count = 0; in mwl8k_rxq_init()
1173 rxq->head = 0; in mwl8k_rxq_init()
1174 rxq->tail = 0; in mwl8k_rxq_init()
1176 size = MWL8K_RX_DESCS * priv->rxd_ops->rxd_size; in mwl8k_rxq_init()
1178 rxq->rxd = dma_alloc_coherent(&priv->pdev->dev, size, &rxq->rxd_dma, in mwl8k_rxq_init()
1180 if (rxq->rxd == NULL) { in mwl8k_rxq_init()
1181 wiphy_err(hw->wiphy, "failed to alloc RX descriptors\n"); in mwl8k_rxq_init()
1182 return -ENOMEM; in mwl8k_rxq_init()
1185 rxq->buf = kcalloc(MWL8K_RX_DESCS, sizeof(*rxq->buf), GFP_KERNEL); in mwl8k_rxq_init()
1186 if (rxq->buf == NULL) { in mwl8k_rxq_init()
1187 dma_free_coherent(&priv->pdev->dev, size, rxq->rxd, in mwl8k_rxq_init()
1188 rxq->rxd_dma); in mwl8k_rxq_init()
1189 return -ENOMEM; in mwl8k_rxq_init()
1198 desc_size = priv->rxd_ops->rxd_size; in mwl8k_rxq_init()
1199 rxd = rxq->rxd + (i * priv->rxd_ops->rxd_size); in mwl8k_rxq_init()
1204 next_dma_addr = rxq->rxd_dma + (nexti * desc_size); in mwl8k_rxq_init()
1206 priv->rxd_ops->rxd_init(rxd, next_dma_addr); in mwl8k_rxq_init()
1212 static int rxq_refill(struct ieee80211_hw *hw, int index, int limit) in rxq_refill() argument
1214 struct mwl8k_priv *priv = hw->priv; in rxq_refill()
1215 struct mwl8k_rx_queue *rxq = priv->rxq + index; in rxq_refill()
1218 while (rxq->rxd_count < MWL8K_RX_DESCS && limit--) { in rxq_refill()
1228 addr = dma_map_single(&priv->pdev->dev, skb->data, in rxq_refill()
1231 rxq->rxd_count++; in rxq_refill()
1232 rx = rxq->tail++; in rxq_refill()
1233 if (rxq->tail == MWL8K_RX_DESCS) in rxq_refill()
1234 rxq->tail = 0; in rxq_refill()
1235 rxq->buf[rx].skb = skb; in rxq_refill()
1236 dma_unmap_addr_set(&rxq->buf[rx], dma, addr); in rxq_refill()
1238 rxd = rxq->rxd + (rx * priv->rxd_ops->rxd_size); in rxq_refill()
1239 priv->rxd_ops->rxd_refill(rxd, addr, MWL8K_RX_MAXSZ); in rxq_refill()
1250 struct mwl8k_priv *priv = hw->priv; in mwl8k_rxq_deinit()
1251 struct mwl8k_rx_queue *rxq = priv->rxq + index; in mwl8k_rxq_deinit()
1254 if (rxq->rxd == NULL) in mwl8k_rxq_deinit()
1258 if (rxq->buf[i].skb != NULL) { in mwl8k_rxq_deinit()
1259 dma_unmap_single(&priv->pdev->dev, in mwl8k_rxq_deinit()
1260 dma_unmap_addr(&rxq->buf[i], dma), in mwl8k_rxq_deinit()
1262 dma_unmap_addr_set(&rxq->buf[i], dma, 0); in mwl8k_rxq_deinit()
1264 kfree_skb(rxq->buf[i].skb); in mwl8k_rxq_deinit()
1265 rxq->buf[i].skb = NULL; in mwl8k_rxq_deinit()
1269 kfree(rxq->buf); in mwl8k_rxq_deinit()
1270 rxq->buf = NULL; in mwl8k_rxq_deinit()
1272 dma_free_coherent(&priv->pdev->dev, in mwl8k_rxq_deinit()
1273 MWL8K_RX_DESCS * priv->rxd_ops->rxd_size, rxq->rxd, in mwl8k_rxq_deinit()
1274 rxq->rxd_dma); in mwl8k_rxq_deinit()
1275 rxq->rxd = NULL; in mwl8k_rxq_deinit()
1286 return priv->capture_beacon && in mwl8k_capture_bssid()
1287 ieee80211_is_beacon(wh->frame_control) && in mwl8k_capture_bssid()
1288 ether_addr_equal_64bits(wh->addr3, priv->capture_bssid); in mwl8k_capture_bssid()
1294 struct mwl8k_priv *priv = hw->priv; in mwl8k_save_beacon()
1296 priv->capture_beacon = false; in mwl8k_save_beacon()
1297 eth_zero_addr(priv->capture_bssid); in mwl8k_save_beacon()
1304 priv->beacon_skb = skb_copy(skb, GFP_ATOMIC); in mwl8k_save_beacon()
1305 if (priv->beacon_skb != NULL) in mwl8k_save_beacon()
1306 ieee80211_queue_work(hw, &priv->finalize_join_worker); in mwl8k_save_beacon()
1316 if (memcmp(bssid, mwl8k_vif->bssid, in mwl8k_find_vif_bss()
1324 static int rxq_process(struct ieee80211_hw *hw, int index, int limit) in rxq_process() argument
1326 struct mwl8k_priv *priv = hw->priv; in rxq_process()
1328 struct mwl8k_rx_queue *rxq = priv->rxq + index; in rxq_process()
1332 while (rxq->rxd_count && limit--) { in rxq_process()
1340 skb = rxq->buf[rxq->head].skb; in rxq_process()
1344 rxd = rxq->rxd + (rxq->head * priv->rxd_ops->rxd_size); in rxq_process()
1346 pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos, in rxq_process()
1347 &priv->noise); in rxq_process()
1351 rxq->buf[rxq->head].skb = NULL; in rxq_process()
1353 dma_unmap_single(&priv->pdev->dev, in rxq_process()
1354 dma_unmap_addr(&rxq->buf[rxq->head], dma), in rxq_process()
1356 dma_unmap_addr_set(&rxq->buf[rxq->head], dma, 0); in rxq_process()
1358 rxq->head++; in rxq_process()
1359 if (rxq->head == MWL8K_RX_DESCS) in rxq_process()
1360 rxq->head = 0; in rxq_process()
1362 rxq->rxd_count--; in rxq_process()
1364 wh = &((struct mwl8k_dma_data *)skb->data)->wh; in rxq_process()
1371 if (mwl8k_capture_bssid(priv, (void *)skb->data)) in rxq_process()
1374 if (ieee80211_has_protected(wh->frame_control)) { in rxq_process()
1380 mwl8k_vif = mwl8k_find_vif_bss(&priv->vif_list, in rxq_process()
1381 wh->addr1); in rxq_process()
1384 mwl8k_vif->is_hw_crypto_enabled) { in rxq_process()
1400 tr = (struct mwl8k_dma_data *)skb->data; in rxq_process()
1401 memset((void *)&(tr->data), 0, 4); in rxq_process()
1405 if (!ieee80211_is_auth(wh->frame_control)) in rxq_process()
1459 struct mwl8k_priv *priv = hw->priv; in mwl8k_txq_init()
1460 struct mwl8k_tx_queue *txq = priv->txq + index; in mwl8k_txq_init()
1464 txq->len = 0; in mwl8k_txq_init()
1465 txq->head = 0; in mwl8k_txq_init()
1466 txq->tail = 0; in mwl8k_txq_init()
1470 txq->txd = dma_alloc_coherent(&priv->pdev->dev, size, &txq->txd_dma, in mwl8k_txq_init()
1472 if (txq->txd == NULL) { in mwl8k_txq_init()
1473 wiphy_err(hw->wiphy, "failed to alloc TX descriptors\n"); in mwl8k_txq_init()
1474 return -ENOMEM; in mwl8k_txq_init()
1477 txq->skb = kcalloc(MWL8K_TX_DESCS, sizeof(*txq->skb), GFP_KERNEL); in mwl8k_txq_init()
1478 if (txq->skb == NULL) { in mwl8k_txq_init()
1479 dma_free_coherent(&priv->pdev->dev, size, txq->txd, in mwl8k_txq_init()
1480 txq->txd_dma); in mwl8k_txq_init()
1481 txq->txd = NULL; in mwl8k_txq_init()
1482 return -ENOMEM; in mwl8k_txq_init()
1489 tx_desc = txq->txd + i; in mwl8k_txq_init()
1492 tx_desc->status = 0; in mwl8k_txq_init()
1493 tx_desc->next_txd_phys_addr = in mwl8k_txq_init()
1494 cpu_to_le32(txq->txd_dma + nexti * sizeof(*tx_desc)); in mwl8k_txq_init()
1503 priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS); in mwl8k_tx_start()
1505 priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS); in mwl8k_tx_start()
1506 ioread32(priv->regs + MWL8K_HIU_INT_CODE); in mwl8k_tx_start()
1511 struct mwl8k_priv *priv = hw->priv; in mwl8k_dump_tx_rings()
1515 struct mwl8k_tx_queue *txq = priv->txq + i; in mwl8k_dump_tx_rings()
1522 struct mwl8k_tx_desc *tx_desc = txq->txd + desc; in mwl8k_dump_tx_rings()
1525 status = le32_to_cpu(tx_desc->status); in mwl8k_dump_tx_rings()
1531 if (tx_desc->pkt_len == 0) in mwl8k_dump_tx_rings()
1535 wiphy_err(hw->wiphy, in mwl8k_dump_tx_rings()
1539 txq->len, txq->head, txq->tail, in mwl8k_dump_tx_rings()
1545 * Must be called with priv->fw_mutex held and tx queues stopped.
1551 struct mwl8k_priv *priv = hw->priv; in mwl8k_tx_wait_empty()
1563 if (priv->hw_restart_in_progress) { in mwl8k_tx_wait_empty()
1564 if (priv->hw_restart_owner == current) in mwl8k_tx_wait_empty()
1567 return -EBUSY; in mwl8k_tx_wait_empty()
1570 if (atomic_read(&priv->watchdog_event_pending)) in mwl8k_tx_wait_empty()
1575 * doesn't need to take ->tx_lock. in mwl8k_tx_wait_empty()
1577 if (!priv->pending_tx_pkts) in mwl8k_tx_wait_empty()
1583 spin_lock_bh(&priv->tx_lock); in mwl8k_tx_wait_empty()
1584 priv->tx_wait = &tx_wait; in mwl8k_tx_wait_empty()
1589 oldcount = priv->pending_tx_pkts; in mwl8k_tx_wait_empty()
1591 spin_unlock_bh(&priv->tx_lock); in mwl8k_tx_wait_empty()
1595 if (atomic_read(&priv->watchdog_event_pending)) { in mwl8k_tx_wait_empty()
1596 spin_lock_bh(&priv->tx_lock); in mwl8k_tx_wait_empty()
1597 priv->tx_wait = NULL; in mwl8k_tx_wait_empty()
1598 spin_unlock_bh(&priv->tx_lock); in mwl8k_tx_wait_empty()
1602 spin_lock_bh(&priv->tx_lock); in mwl8k_tx_wait_empty()
1604 if (timeout || !priv->pending_tx_pkts) { in mwl8k_tx_wait_empty()
1605 WARN_ON(priv->pending_tx_pkts); in mwl8k_tx_wait_empty()
1607 wiphy_notice(hw->wiphy, "tx rings drained\n"); in mwl8k_tx_wait_empty()
1617 if (priv->pending_tx_pkts < oldcount) { in mwl8k_tx_wait_empty()
1618 wiphy_notice(hw->wiphy, in mwl8k_tx_wait_empty()
1619 "waiting for tx rings to drain (%d -> %d pkts)\n", in mwl8k_tx_wait_empty()
1620 oldcount, priv->pending_tx_pkts); in mwl8k_tx_wait_empty()
1625 priv->tx_wait = NULL; in mwl8k_tx_wait_empty()
1627 wiphy_err(hw->wiphy, "tx rings stuck for %d ms\n", in mwl8k_tx_wait_empty()
1630 priv->hw_restart_in_progress = true; in mwl8k_tx_wait_empty()
1631 ieee80211_queue_work(hw, &priv->fw_reload); in mwl8k_tx_wait_empty()
1633 rc = -ETIMEDOUT; in mwl8k_tx_wait_empty()
1635 priv->tx_wait = NULL; in mwl8k_tx_wait_empty()
1636 spin_unlock_bh(&priv->tx_lock); in mwl8k_tx_wait_empty()
1664 return -1; in mwl8k_tid_queue_mapping()
1677 mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) in mwl8k_txq_reclaim() argument
1679 struct mwl8k_priv *priv = hw->priv; in mwl8k_txq_reclaim()
1680 struct mwl8k_tx_queue *txq = priv->txq + index; in mwl8k_txq_reclaim()
1684 while (txq->len > 0 && limit--) { in mwl8k_txq_reclaim()
1697 tx = txq->head; in mwl8k_txq_reclaim()
1698 tx_desc = txq->txd + tx; in mwl8k_txq_reclaim()
1700 status = le32_to_cpu(tx_desc->status); in mwl8k_txq_reclaim()
1705 tx_desc->status &= in mwl8k_txq_reclaim()
1709 txq->head = (tx + 1) % MWL8K_TX_DESCS; in mwl8k_txq_reclaim()
1710 BUG_ON(txq->len == 0); in mwl8k_txq_reclaim()
1711 txq->len--; in mwl8k_txq_reclaim()
1712 priv->pending_tx_pkts--; in mwl8k_txq_reclaim()
1714 addr = le32_to_cpu(tx_desc->pkt_phys_addr); in mwl8k_txq_reclaim()
1715 size = le16_to_cpu(tx_desc->pkt_len); in mwl8k_txq_reclaim()
1716 skb = txq->skb[tx]; in mwl8k_txq_reclaim()
1717 txq->skb[tx] = NULL; in mwl8k_txq_reclaim()
1720 dma_unmap_single(&priv->pdev->dev, addr, size, DMA_TO_DEVICE); in mwl8k_txq_reclaim()
1722 mwl8k_remove_dma_header(skb, tx_desc->qos_control); in mwl8k_txq_reclaim()
1724 wh = (struct ieee80211_hdr *) skb->data; in mwl8k_txq_reclaim()
1727 tx_desc->pkt_phys_addr = 0; in mwl8k_txq_reclaim()
1728 tx_desc->pkt_len = 0; in mwl8k_txq_reclaim()
1731 if (ieee80211_is_data(wh->frame_control)) { in mwl8k_txq_reclaim()
1733 sta = ieee80211_find_sta_by_ifaddr(hw, wh->addr1, in mwl8k_txq_reclaim()
1734 wh->addr2); in mwl8k_txq_reclaim()
1738 rate_info = le16_to_cpu(tx_desc->rate_info); in mwl8k_txq_reclaim()
1746 sta_info->is_ampdu_allowed = false; in mwl8k_txq_reclaim()
1748 sta_info->is_ampdu_allowed = true; in mwl8k_txq_reclaim()
1759 info->status.rates[0].idx = -1; in mwl8k_txq_reclaim()
1760 info->status.rates[0].count = 1; in mwl8k_txq_reclaim()
1763 info->flags |= IEEE80211_TX_STAT_ACK; in mwl8k_txq_reclaim()
1776 struct mwl8k_priv *priv = hw->priv; in mwl8k_txq_deinit()
1777 struct mwl8k_tx_queue *txq = priv->txq + index; in mwl8k_txq_deinit()
1779 if (txq->txd == NULL) in mwl8k_txq_deinit()
1784 kfree(txq->skb); in mwl8k_txq_deinit()
1785 txq->skb = NULL; in mwl8k_txq_deinit()
1787 dma_free_coherent(&priv->pdev->dev, in mwl8k_txq_deinit()
1789 txq->txd, txq->txd_dma); in mwl8k_txq_deinit()
1790 txq->txd = NULL; in mwl8k_txq_deinit()
1793 /* caller must hold priv->stream_lock when calling the stream functions */
1798 struct mwl8k_priv *priv = hw->priv; in mwl8k_add_stream()
1802 stream = &priv->ampdu[i]; in mwl8k_add_stream()
1803 if (stream->state == AMPDU_NO_STREAM) { in mwl8k_add_stream()
1804 stream->sta = sta; in mwl8k_add_stream()
1805 stream->state = AMPDU_STREAM_NEW; in mwl8k_add_stream()
1806 stream->tid = tid; in mwl8k_add_stream()
1807 stream->idx = i; in mwl8k_add_stream()
1808 wiphy_debug(hw->wiphy, "Added a new stream for %pM %d", in mwl8k_add_stream()
1809 sta->addr, tid); in mwl8k_add_stream()
1822 if (stream->state != AMPDU_STREAM_NEW) in mwl8k_start_stream()
1824 ret = ieee80211_start_tx_ba_session(stream->sta, stream->tid, 0); in mwl8k_start_stream()
1826 wiphy_debug(hw->wiphy, "Failed to start stream for %pM %d: " in mwl8k_start_stream()
1827 "%d\n", stream->sta->addr, stream->tid, ret); in mwl8k_start_stream()
1829 wiphy_debug(hw->wiphy, "Started stream for %pM %d\n", in mwl8k_start_stream()
1830 stream->sta->addr, stream->tid); in mwl8k_start_stream()
1837 wiphy_debug(hw->wiphy, "Remove stream for %pM %d\n", stream->sta->addr, in mwl8k_remove_stream()
1838 stream->tid); in mwl8k_remove_stream()
1845 struct mwl8k_priv *priv = hw->priv; in mwl8k_lookup_stream()
1850 stream = &priv->ampdu[i]; in mwl8k_lookup_stream()
1851 if (stream->state == AMPDU_NO_STREAM) in mwl8k_lookup_stream()
1853 if (!memcmp(stream->sta->addr, addr, ETH_ALEN) && in mwl8k_lookup_stream()
1854 stream->tid == tid) in mwl8k_lookup_stream()
1867 tx_stats = &sta_info->tx_stats[tid]; in mwl8k_ampdu_allowed()
1869 return sta_info->is_ampdu_allowed && in mwl8k_ampdu_allowed()
1870 tx_stats->pkts > MWL8K_AMPDU_PACKET_THRESHOLD; in mwl8k_ampdu_allowed()
1879 tx_stats = &sta_info->tx_stats[tid]; in mwl8k_tx_count_packet()
1881 if (tx_stats->start_time == 0) in mwl8k_tx_count_packet()
1882 tx_stats->start_time = jiffies; in mwl8k_tx_count_packet()
1888 if (time_after(jiffies, (unsigned long)tx_stats->start_time + HZ)) { in mwl8k_tx_count_packet()
1889 tx_stats->pkts = 0; in mwl8k_tx_count_packet()
1890 tx_stats->start_time = 0; in mwl8k_tx_count_packet()
1892 tx_stats->pkts++; in mwl8k_tx_count_packet()
1908 struct mwl8k_priv *priv = hw->priv; in mwl8k_txq_xmit()
1923 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; in mwl8k_txq_xmit()
1926 wh = (struct ieee80211_hdr *)skb->data; in mwl8k_txq_xmit()
1927 if (ieee80211_is_data_qos(wh->frame_control)) in mwl8k_txq_xmit()
1932 if (skb->protocol == cpu_to_be16(ETH_P_PAE)) in mwl8k_txq_xmit()
1935 if (ieee80211_is_mgmt(wh->frame_control)) in mwl8k_txq_xmit()
1938 if (priv->ap_fw) in mwl8k_txq_xmit()
1943 wh = &((struct mwl8k_dma_data *)skb->data)->wh; in mwl8k_txq_xmit()
1946 mwl8k_vif = MWL8K_VIF(tx_info->control.vif); in mwl8k_txq_xmit()
1948 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { in mwl8k_txq_xmit()
1949 wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); in mwl8k_txq_xmit()
1950 wh->seq_ctrl |= cpu_to_le16(mwl8k_vif->seqno); in mwl8k_txq_xmit()
1951 mwl8k_vif->seqno += 0x10; in mwl8k_txq_xmit()
1957 if (ieee80211_is_mgmt(wh->frame_control) || in mwl8k_txq_xmit()
1958 ieee80211_is_ctl(wh->frame_control)) { in mwl8k_txq_xmit()
1961 } else if (ieee80211_is_data(wh->frame_control)) { in mwl8k_txq_xmit()
1963 if (is_multicast_ether_addr(wh->addr1)) in mwl8k_txq_xmit()
1967 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) in mwl8k_txq_xmit()
1982 if (unlikely(ieee80211_is_action(wh->frame_control) && in mwl8k_txq_xmit()
1983 mgmt->u.action.category == WLAN_CATEGORY_BACK && in mwl8k_txq_xmit()
1984 mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ && in mwl8k_txq_xmit()
1985 priv->ap_fw)) { in mwl8k_txq_xmit()
1986 u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab); in mwl8k_txq_xmit()
1993 if (priv->ap_fw && sta && sta->deflink.ht_cap.ht_supported && !eapol_frame && in mwl8k_txq_xmit()
1994 ieee80211_is_data_qos(wh->frame_control)) { in mwl8k_txq_xmit()
1997 spin_lock(&priv->stream_lock); in mwl8k_txq_xmit()
1998 stream = mwl8k_lookup_stream(hw, sta->addr, tid); in mwl8k_txq_xmit()
2000 if (stream->state == AMPDU_STREAM_ACTIVE) { in mwl8k_txq_xmit()
2002 txpriority = (BA_QUEUE + stream->idx) % in mwl8k_txq_xmit()
2004 if (stream->idx <= 1) in mwl8k_txq_xmit()
2005 index = stream->idx + in mwl8k_txq_xmit()
2008 } else if (stream->state == AMPDU_STREAM_NEW) { in mwl8k_txq_xmit()
2029 wiphy_warn(hw->wiphy, in mwl8k_txq_xmit()
2032 spin_unlock(&priv->stream_lock); in mwl8k_txq_xmit()
2048 spin_unlock(&priv->stream_lock); in mwl8k_txq_xmit()
2054 dma = dma_map_single(&priv->pdev->dev, skb->data, skb->len, in mwl8k_txq_xmit()
2057 if (dma_mapping_error(&priv->pdev->dev, dma)) { in mwl8k_txq_xmit()
2058 wiphy_debug(hw->wiphy, in mwl8k_txq_xmit()
2061 spin_lock(&priv->stream_lock); in mwl8k_txq_xmit()
2063 spin_unlock(&priv->stream_lock); in mwl8k_txq_xmit()
2069 spin_lock_bh(&priv->tx_lock); in mwl8k_txq_xmit()
2071 txq = priv->txq + index; in mwl8k_txq_xmit()
2081 if (txq->len >= MWL8K_TX_DESCS - 2) { in mwl8k_txq_xmit()
2082 if (!mgmtframe || txq->len == MWL8K_TX_DESCS) { in mwl8k_txq_xmit()
2084 spin_lock(&priv->stream_lock); in mwl8k_txq_xmit()
2086 spin_unlock(&priv->stream_lock); in mwl8k_txq_xmit()
2089 spin_unlock_bh(&priv->tx_lock); in mwl8k_txq_xmit()
2090 dma_unmap_single(&priv->pdev->dev, dma, skb->len, in mwl8k_txq_xmit()
2097 BUG_ON(txq->skb[txq->tail] != NULL); in mwl8k_txq_xmit()
2098 txq->skb[txq->tail] = skb; in mwl8k_txq_xmit()
2100 tx = txq->txd + txq->tail; in mwl8k_txq_xmit()
2101 tx->data_rate = txdatarate; in mwl8k_txq_xmit()
2102 tx->tx_priority = txpriority; in mwl8k_txq_xmit()
2103 tx->qos_control = cpu_to_le16(qos); in mwl8k_txq_xmit()
2104 tx->pkt_phys_addr = cpu_to_le32(dma); in mwl8k_txq_xmit()
2105 tx->pkt_len = cpu_to_le16(skb->len); in mwl8k_txq_xmit()
2106 tx->rate_info = 0; in mwl8k_txq_xmit()
2107 if (!priv->ap_fw && sta != NULL) in mwl8k_txq_xmit()
2108 tx->peer_id = MWL8K_STA(sta)->peer_id; in mwl8k_txq_xmit()
2110 tx->peer_id = 0; in mwl8k_txq_xmit()
2112 if (priv->ap_fw && ieee80211_is_data(wh->frame_control) && !eapol_frame) in mwl8k_txq_xmit()
2113 tx->timestamp = cpu_to_le32(ioread32(priv->regs + in mwl8k_txq_xmit()
2116 tx->timestamp = 0; in mwl8k_txq_xmit()
2119 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); in mwl8k_txq_xmit()
2121 txq->len++; in mwl8k_txq_xmit()
2122 priv->pending_tx_pkts++; in mwl8k_txq_xmit()
2124 txq->tail++; in mwl8k_txq_xmit()
2125 if (txq->tail == MWL8K_TX_DESCS) in mwl8k_txq_xmit()
2126 txq->tail = 0; in mwl8k_txq_xmit()
2130 spin_unlock_bh(&priv->tx_lock); in mwl8k_txq_xmit()
2134 spin_lock(&priv->stream_lock); in mwl8k_txq_xmit()
2137 spin_unlock(&priv->stream_lock); in mwl8k_txq_xmit()
2146 * - Some commands require that the packet transmit path is idle when
2149 * - There are certain sequences of commands that need to be issued to
2153 * can be taken recursively, and which is taken by both the low-level
2160 struct mwl8k_priv *priv = hw->priv; in mwl8k_fw_lock()
2162 if (priv->fw_mutex_owner != current) { in mwl8k_fw_lock()
2165 mutex_lock(&priv->fw_mutex); in mwl8k_fw_lock()
2170 if (!priv->hw_restart_in_progress) in mwl8k_fw_lock()
2173 mutex_unlock(&priv->fw_mutex); in mwl8k_fw_lock()
2178 priv->fw_mutex_owner = current; in mwl8k_fw_lock()
2181 priv->fw_mutex_depth++; in mwl8k_fw_lock()
2188 struct mwl8k_priv *priv = hw->priv; in mwl8k_fw_unlock()
2190 if (!--priv->fw_mutex_depth) { in mwl8k_fw_unlock()
2191 if (!priv->hw_restart_in_progress) in mwl8k_fw_unlock()
2194 priv->fw_mutex_owner = NULL; in mwl8k_fw_unlock()
2195 mutex_unlock(&priv->fw_mutex); in mwl8k_fw_unlock()
2212 struct mwl8k_priv *priv = hw->priv; in mwl8k_post_cmd()
2213 void __iomem *regs = priv->regs; in mwl8k_post_cmd()
2221 wiphy_dbg(hw->wiphy, "Posting %s [%d]\n", in mwl8k_post_cmd()
2222 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), cmd->macid); in mwl8k_post_cmd()
2233 if (priv->ap_fw && priv->running_bsses) { in mwl8k_post_cmd()
2234 switch (le16_to_cpu(cmd->code)) { in mwl8k_post_cmd()
2242 bitmap = priv->running_bsses; in mwl8k_post_cmd()
2248 cmd->result = (__force __le16) 0xffff; in mwl8k_post_cmd()
2249 dma_size = le16_to_cpu(cmd->length); in mwl8k_post_cmd()
2250 dma_addr = dma_map_single(&priv->pdev->dev, cmd, dma_size, in mwl8k_post_cmd()
2252 if (dma_mapping_error(&priv->pdev->dev, dma_addr)) { in mwl8k_post_cmd()
2253 rc = -ENOMEM; in mwl8k_post_cmd()
2257 priv->hostcmd_wait = &cmd_wait; in mwl8k_post_cmd()
2267 priv->hostcmd_wait = NULL; in mwl8k_post_cmd()
2270 dma_unmap_single(&priv->pdev->dev, dma_addr, dma_size, in mwl8k_post_cmd()
2274 wiphy_err(hw->wiphy, "Command %s timeout after %u ms\n", in mwl8k_post_cmd()
2275 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), in mwl8k_post_cmd()
2277 rc = -ETIMEDOUT; in mwl8k_post_cmd()
2281 ms = MWL8K_CMD_TIMEOUT_MS - jiffies_to_msecs(time_left); in mwl8k_post_cmd()
2283 rc = cmd->result ? -EINVAL : 0; in mwl8k_post_cmd()
2285 wiphy_err(hw->wiphy, "Command %s error 0x%x\n", in mwl8k_post_cmd()
2286 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), in mwl8k_post_cmd()
2287 le16_to_cpu(cmd->result)); in mwl8k_post_cmd()
2289 wiphy_notice(hw->wiphy, "Command %s took %d ms\n", in mwl8k_post_cmd()
2290 mwl8k_cmd_name(cmd->code, in mwl8k_post_cmd()
2309 cmd->macid = MWL8K_VIF(vif)->macid; in mwl8k_post_pervif_cmd()
2318 struct mwl8k_priv *priv = hw->priv; in mwl8k_setup_2ghz_band()
2320 BUILD_BUG_ON(sizeof(priv->channels_24) != sizeof(mwl8k_channels_24)); in mwl8k_setup_2ghz_band()
2321 memcpy(priv->channels_24, mwl8k_channels_24, sizeof(mwl8k_channels_24)); in mwl8k_setup_2ghz_band()
2323 BUILD_BUG_ON(sizeof(priv->rates_24) != sizeof(mwl8k_rates_24)); in mwl8k_setup_2ghz_band()
2324 memcpy(priv->rates_24, mwl8k_rates_24, sizeof(mwl8k_rates_24)); in mwl8k_setup_2ghz_band()
2326 priv->band_24.band = NL80211_BAND_2GHZ; in mwl8k_setup_2ghz_band()
2327 priv->band_24.channels = priv->channels_24; in mwl8k_setup_2ghz_band()
2328 priv->band_24.n_channels = ARRAY_SIZE(mwl8k_channels_24); in mwl8k_setup_2ghz_band()
2329 priv->band_24.bitrates = priv->rates_24; in mwl8k_setup_2ghz_band()
2330 priv->band_24.n_bitrates = ARRAY_SIZE(mwl8k_rates_24); in mwl8k_setup_2ghz_band()
2332 hw->wiphy->bands[NL80211_BAND_2GHZ] = &priv->band_24; in mwl8k_setup_2ghz_band()
2337 struct mwl8k_priv *priv = hw->priv; in mwl8k_setup_5ghz_band()
2339 BUILD_BUG_ON(sizeof(priv->channels_50) != sizeof(mwl8k_channels_50)); in mwl8k_setup_5ghz_band()
2340 memcpy(priv->channels_50, mwl8k_channels_50, sizeof(mwl8k_channels_50)); in mwl8k_setup_5ghz_band()
2342 BUILD_BUG_ON(sizeof(priv->rates_50) != sizeof(mwl8k_rates_50)); in mwl8k_setup_5ghz_band()
2343 memcpy(priv->rates_50, mwl8k_rates_50, sizeof(mwl8k_rates_50)); in mwl8k_setup_5ghz_band()
2345 priv->band_50.band = NL80211_BAND_5GHZ; in mwl8k_setup_5ghz_band()
2346 priv->band_50.channels = priv->channels_50; in mwl8k_setup_5ghz_band()
2347 priv->band_50.n_channels = ARRAY_SIZE(mwl8k_channels_50); in mwl8k_setup_5ghz_band()
2348 priv->band_50.bitrates = priv->rates_50; in mwl8k_setup_5ghz_band()
2349 priv->band_50.n_bitrates = ARRAY_SIZE(mwl8k_rates_50); in mwl8k_setup_5ghz_band()
2351 hw->wiphy->bands[NL80211_BAND_5GHZ] = &priv->band_50; in mwl8k_setup_5ghz_band()
2399 band->ht_cap.ht_supported = 1; in mwl8k_set_ht_caps()
2402 band->ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU; in mwl8k_set_ht_caps()
2404 band->ht_cap.cap |= IEEE80211_HT_CAP_GRN_FLD; in mwl8k_set_ht_caps()
2407 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; in mwl8k_set_ht_caps()
2408 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; in mwl8k_set_ht_caps()
2411 band->ht_cap.cap |= IEEE80211_HT_CAP_RX_STBC; in mwl8k_set_ht_caps()
2413 band->ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC; in mwl8k_set_ht_caps()
2415 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; in mwl8k_set_ht_caps()
2417 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; in mwl8k_set_ht_caps()
2419 band->ht_cap.cap |= IEEE80211_HT_CAP_DELAY_BA; in mwl8k_set_ht_caps()
2421 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; in mwl8k_set_ht_caps()
2426 band->ht_cap.mcs.rx_mask[0] = 0xff; in mwl8k_set_ht_caps()
2428 band->ht_cap.mcs.rx_mask[1] = 0xff; in mwl8k_set_ht_caps()
2430 band->ht_cap.mcs.rx_mask[2] = 0xff; in mwl8k_set_ht_caps()
2431 band->ht_cap.mcs.rx_mask[4] = 0x01; in mwl8k_set_ht_caps()
2432 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; in mwl8k_set_ht_caps()
2435 band->ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; in mwl8k_set_ht_caps()
2436 band->ht_cap.mcs.tx_params |= (tx_streams - 1) << in mwl8k_set_ht_caps()
2444 struct mwl8k_priv *priv = hw->priv; in mwl8k_set_caps()
2446 if (priv->caps) in mwl8k_set_caps()
2452 mwl8k_set_ht_caps(hw, &priv->band_24, caps); in mwl8k_set_caps()
2458 mwl8k_set_ht_caps(hw, &priv->band_50, caps); in mwl8k_set_caps()
2461 priv->caps = caps; in mwl8k_set_caps()
2466 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_get_hw_spec_sta()
2473 return -ENOMEM; in mwl8k_cmd_get_hw_spec_sta()
2475 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_HW_SPEC); in mwl8k_cmd_get_hw_spec_sta()
2476 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_get_hw_spec_sta()
2478 memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr)); in mwl8k_cmd_get_hw_spec_sta()
2479 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); in mwl8k_cmd_get_hw_spec_sta()
2480 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma); in mwl8k_cmd_get_hw_spec_sta()
2481 cmd->num_tx_queues = cpu_to_le32(mwl8k_tx_queues(priv)); in mwl8k_cmd_get_hw_spec_sta()
2483 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma); in mwl8k_cmd_get_hw_spec_sta()
2484 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); in mwl8k_cmd_get_hw_spec_sta()
2485 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS); in mwl8k_cmd_get_hw_spec_sta()
2487 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_get_hw_spec_sta()
2490 SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr); in mwl8k_cmd_get_hw_spec_sta()
2491 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); in mwl8k_cmd_get_hw_spec_sta()
2492 priv->fw_rev = le32_to_cpu(cmd->fw_rev); in mwl8k_cmd_get_hw_spec_sta()
2493 priv->hw_rev = cmd->hw_rev; in mwl8k_cmd_get_hw_spec_sta()
2494 mwl8k_set_caps(hw, le32_to_cpu(cmd->caps)); in mwl8k_cmd_get_hw_spec_sta()
2495 priv->ap_macids_supported = 0x00000000; in mwl8k_cmd_get_hw_spec_sta()
2496 priv->sta_macids_supported = 0x00000001; in mwl8k_cmd_get_hw_spec_sta()
2531 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_get_hw_spec_ap()
2538 return -ENOMEM; in mwl8k_cmd_get_hw_spec_ap()
2540 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_HW_SPEC); in mwl8k_cmd_get_hw_spec_ap()
2541 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_get_hw_spec_ap()
2543 memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr)); in mwl8k_cmd_get_hw_spec_ap()
2544 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); in mwl8k_cmd_get_hw_spec_ap()
2546 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_get_hw_spec_ap()
2551 api_version = le32_to_cpu(cmd->fw_api_version); in mwl8k_cmd_get_hw_spec_ap()
2552 if (priv->device_info->fw_api_ap != api_version) { in mwl8k_cmd_get_hw_spec_ap()
2555 priv->device_info->part_name, in mwl8k_cmd_get_hw_spec_ap()
2556 priv->device_info->fw_api_ap, in mwl8k_cmd_get_hw_spec_ap()
2558 rc = -EINVAL; in mwl8k_cmd_get_hw_spec_ap()
2561 SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr); in mwl8k_cmd_get_hw_spec_ap()
2562 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); in mwl8k_cmd_get_hw_spec_ap()
2563 priv->fw_rev = le32_to_cpu(cmd->fw_rev); in mwl8k_cmd_get_hw_spec_ap()
2564 priv->hw_rev = cmd->hw_rev; in mwl8k_cmd_get_hw_spec_ap()
2565 mwl8k_set_caps(hw, le32_to_cpu(cmd->caps)); in mwl8k_cmd_get_hw_spec_ap()
2566 priv->ap_macids_supported = 0x000000ff; in mwl8k_cmd_get_hw_spec_ap()
2567 priv->sta_macids_supported = 0x00000100; in mwl8k_cmd_get_hw_spec_ap()
2568 priv->num_ampdu_queues = le32_to_cpu(cmd->num_of_ampdu_queues); in mwl8k_cmd_get_hw_spec_ap()
2569 if (priv->num_ampdu_queues > MWL8K_MAX_AMPDU_QUEUES) { in mwl8k_cmd_get_hw_spec_ap()
2570 wiphy_warn(hw->wiphy, "fw reported %d ampdu queues" in mwl8k_cmd_get_hw_spec_ap()
2572 priv->num_ampdu_queues, in mwl8k_cmd_get_hw_spec_ap()
2574 priv->num_ampdu_queues = MWL8K_MAX_AMPDU_QUEUES; in mwl8k_cmd_get_hw_spec_ap()
2576 off = le32_to_cpu(cmd->rxwrptr) & 0xffff; in mwl8k_cmd_get_hw_spec_ap()
2577 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); in mwl8k_cmd_get_hw_spec_ap()
2579 off = le32_to_cpu(cmd->rxrdptr) & 0xffff; in mwl8k_cmd_get_hw_spec_ap()
2580 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); in mwl8k_cmd_get_hw_spec_ap()
2582 priv->txq_offset[0] = le32_to_cpu(cmd->wcbbase0) & 0xffff; in mwl8k_cmd_get_hw_spec_ap()
2583 priv->txq_offset[1] = le32_to_cpu(cmd->wcbbase1) & 0xffff; in mwl8k_cmd_get_hw_spec_ap()
2584 priv->txq_offset[2] = le32_to_cpu(cmd->wcbbase2) & 0xffff; in mwl8k_cmd_get_hw_spec_ap()
2585 priv->txq_offset[3] = le32_to_cpu(cmd->wcbbase3) & 0xffff; in mwl8k_cmd_get_hw_spec_ap()
2587 for (i = 0; i < priv->num_ampdu_queues; i++) in mwl8k_cmd_get_hw_spec_ap()
2588 priv->txq_offset[i + MWL8K_TX_WMM_QUEUES] = in mwl8k_cmd_get_hw_spec_ap()
2589 le32_to_cpu(cmd->wcbbase_ampdu[i]) & 0xffff; in mwl8k_cmd_get_hw_spec_ap()
2621 * hardware. This helps minimizing the issues caused due to head-of-line
2633 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_set_hw_spec()
2640 return -ENOMEM; in mwl8k_cmd_set_hw_spec()
2642 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_HW_SPEC); in mwl8k_cmd_set_hw_spec()
2643 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_hw_spec()
2645 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); in mwl8k_cmd_set_hw_spec()
2646 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma); in mwl8k_cmd_set_hw_spec()
2647 cmd->num_tx_queues = cpu_to_le32(mwl8k_tx_queues(priv)); in mwl8k_cmd_set_hw_spec()
2656 int j = mwl8k_tx_queues(priv) - 1 - i; in mwl8k_cmd_set_hw_spec()
2657 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[j].txd_dma); in mwl8k_cmd_set_hw_spec()
2660 cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT | in mwl8k_cmd_set_hw_spec()
2665 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); in mwl8k_cmd_set_hw_spec()
2666 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS); in mwl8k_cmd_set_hw_spec()
2668 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_hw_spec()
2693 struct mwl8k_priv *priv = hw->priv; in __mwl8k_cmd_mac_multicast_adr()
2701 if (allmulti || mc_count > priv->num_mcaddrs) { in __mwl8k_cmd_mac_multicast_adr()
2712 cmd->header.code = cpu_to_le16(MWL8K_CMD_MAC_MULTICAST_ADR); in __mwl8k_cmd_mac_multicast_adr()
2713 cmd->header.length = cpu_to_le16(size); in __mwl8k_cmd_mac_multicast_adr()
2714 cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_DIRECTED | in __mwl8k_cmd_mac_multicast_adr()
2718 cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_ALL_MULTICAST); in __mwl8k_cmd_mac_multicast_adr()
2723 cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST); in __mwl8k_cmd_mac_multicast_adr()
2724 cmd->numaddr = cpu_to_le16(mc_count); in __mwl8k_cmd_mac_multicast_adr()
2726 memcpy(cmd->addr[i++], ha->addr, ETH_ALEN); in __mwl8k_cmd_mac_multicast_adr()
2730 return &cmd->header; in __mwl8k_cmd_mac_multicast_adr()
2754 return -ENOMEM; in mwl8k_cmd_get_stat()
2756 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_STAT); in mwl8k_cmd_get_stat()
2757 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_get_stat()
2759 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_get_stat()
2761 stats->dot11ACKFailureCount = in mwl8k_cmd_get_stat()
2762 le32_to_cpu(cmd->stats[MWL8K_STAT_ACK_FAILURE]); in mwl8k_cmd_get_stat()
2763 stats->dot11RTSFailureCount = in mwl8k_cmd_get_stat()
2764 le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_FAILURE]); in mwl8k_cmd_get_stat()
2765 stats->dot11FCSErrorCount = in mwl8k_cmd_get_stat()
2766 le32_to_cpu(cmd->stats[MWL8K_STAT_FCS_ERROR]); in mwl8k_cmd_get_stat()
2767 stats->dot11RTSSuccessCount = in mwl8k_cmd_get_stat()
2768 le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_SUCCESS]); in mwl8k_cmd_get_stat()
2788 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_radio_control()
2792 if (enable == priv->radio_on && !force) in mwl8k_cmd_radio_control()
2797 return -ENOMEM; in mwl8k_cmd_radio_control()
2799 cmd->header.code = cpu_to_le16(MWL8K_CMD_RADIO_CONTROL); in mwl8k_cmd_radio_control()
2800 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_radio_control()
2801 cmd->action = cpu_to_le16(MWL8K_CMD_SET); in mwl8k_cmd_radio_control()
2802 cmd->control = cpu_to_le16(priv->radio_short_preamble ? 3 : 1); in mwl8k_cmd_radio_control()
2803 cmd->radio_on = cpu_to_le16(enable ? 0x0001 : 0x0000); in mwl8k_cmd_radio_control()
2805 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_radio_control()
2809 priv->radio_on = enable; in mwl8k_cmd_radio_control()
2827 struct mwl8k_priv *priv = hw->priv; in mwl8k_set_radio_preamble()
2829 priv->radio_short_preamble = short_preamble; in mwl8k_set_radio_preamble()
2855 return -ENOMEM; in mwl8k_cmd_rf_tx_power()
2857 cmd->header.code = cpu_to_le16(MWL8K_CMD_RF_TX_POWER); in mwl8k_cmd_rf_tx_power()
2858 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_rf_tx_power()
2859 cmd->action = cpu_to_le16(MWL8K_CMD_SET); in mwl8k_cmd_rf_tx_power()
2860 cmd->support_level = cpu_to_le16(dBm); in mwl8k_cmd_rf_tx_power()
2862 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_rf_tx_power()
2887 struct ieee80211_channel *channel = conf->chandef.chan; in mwl8k_cmd_tx_power()
2889 cfg80211_get_chandef_type(&conf->chandef); in mwl8k_cmd_tx_power()
2896 return -ENOMEM; in mwl8k_cmd_tx_power()
2898 cmd->header.code = cpu_to_le16(MWL8K_CMD_TX_POWER); in mwl8k_cmd_tx_power()
2899 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_tx_power()
2900 cmd->action = cpu_to_le16(MWL8K_CMD_SET_LIST); in mwl8k_cmd_tx_power()
2902 if (channel->band == NL80211_BAND_2GHZ) in mwl8k_cmd_tx_power()
2903 cmd->band = cpu_to_le16(0x1); in mwl8k_cmd_tx_power()
2904 else if (channel->band == NL80211_BAND_5GHZ) in mwl8k_cmd_tx_power()
2905 cmd->band = cpu_to_le16(0x4); in mwl8k_cmd_tx_power()
2907 cmd->channel = cpu_to_le16(channel->hw_value); in mwl8k_cmd_tx_power()
2911 cmd->bw = cpu_to_le16(0x2); in mwl8k_cmd_tx_power()
2913 cmd->bw = cpu_to_le16(0x4); in mwl8k_cmd_tx_power()
2915 cmd->sub_ch = cpu_to_le16(0x3); in mwl8k_cmd_tx_power()
2917 cmd->sub_ch = cpu_to_le16(0x1); in mwl8k_cmd_tx_power()
2921 cmd->power_level_list[i] = cpu_to_le16(pwr); in mwl8k_cmd_tx_power()
2923 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_tx_power()
2949 return -ENOMEM; in mwl8k_cmd_rf_antenna()
2951 cmd->header.code = cpu_to_le16(MWL8K_CMD_RF_ANTENNA); in mwl8k_cmd_rf_antenna()
2952 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_rf_antenna()
2953 cmd->antenna = cpu_to_le16(antenna); in mwl8k_cmd_rf_antenna()
2954 cmd->mode = cpu_to_le16(mask); in mwl8k_cmd_rf_antenna()
2956 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_rf_antenna()
2979 return -ENOMEM; in mwl8k_cmd_set_beacon()
2981 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_BEACON); in mwl8k_cmd_set_beacon()
2982 cmd->header.length = cpu_to_le16(sizeof(*cmd) + len); in mwl8k_cmd_set_beacon()
2983 cmd->beacon_len = cpu_to_le16(len); in mwl8k_cmd_set_beacon()
2984 memcpy(cmd->beacon, beacon, len); in mwl8k_cmd_set_beacon()
2986 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_set_beacon()
3006 return -ENOMEM; in mwl8k_cmd_set_pre_scan()
3008 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_PRE_SCAN); in mwl8k_cmd_set_pre_scan()
3009 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_pre_scan()
3011 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_pre_scan()
3039 return -ENOMEM; in mwl8k_cmd_bbp_reg_access()
3041 cmd->header.code = cpu_to_le16(MWL8K_CMD_BBP_REG_ACCESS); in mwl8k_cmd_bbp_reg_access()
3042 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_bbp_reg_access()
3043 cmd->action = cpu_to_le16(action); in mwl8k_cmd_bbp_reg_access()
3044 cmd->offset = cpu_to_le16(offset); in mwl8k_cmd_bbp_reg_access()
3046 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_bbp_reg_access()
3049 *value = cmd->value; in mwl8k_cmd_bbp_reg_access()
3075 return -ENOMEM; in mwl8k_cmd_set_post_scan()
3077 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_POST_SCAN); in mwl8k_cmd_set_post_scan()
3078 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_post_scan()
3079 cmd->isibss = 0; in mwl8k_cmd_set_post_scan()
3080 memcpy(cmd->bssid, mac, ETH_ALEN); in mwl8k_cmd_set_post_scan()
3082 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_post_scan()
3088 static int freq_to_idx(struct mwl8k_priv *priv, int freq) in freq_to_idx() argument
3094 sband = priv->hw->wiphy->bands[band]; in freq_to_idx()
3098 for (ch = 0; ch < sband->n_channels; ch++, idx++) in freq_to_idx()
3099 if (sband->channels[ch].center_freq == freq) in freq_to_idx()
3114 idx = freq_to_idx(priv, priv->acs_chan->center_freq); in mwl8k_update_survey()
3116 wiphy_err(priv->hw->wiphy, "Failed to update survey\n"); in mwl8k_update_survey()
3120 survey = &priv->survey[idx]; in mwl8k_update_survey()
3122 cca_cnt = ioread32(priv->regs + NOK_CCA_CNT_REG); in mwl8k_update_survey()
3124 survey->time_busy = (u64) cca_cnt; in mwl8k_update_survey()
3126 rx_rdy = ioread32(priv->regs + BBU_RXRDY_CNT_REG); in mwl8k_update_survey()
3128 survey->time_rx = (u64) rx_rdy; in mwl8k_update_survey()
3130 priv->channel_time = jiffies - priv->channel_time; in mwl8k_update_survey()
3131 survey->time = jiffies_to_msecs(priv->channel_time); in mwl8k_update_survey()
3133 survey->channel = channel; in mwl8k_update_survey()
3135 mwl8k_cmd_bbp_reg_access(priv->hw, 0, BBU_AVG_NOISE_VAL, &nf); in mwl8k_update_survey()
3138 survey->noise = nf * -1; in mwl8k_update_survey()
3140 survey->filled = SURVEY_INFO_NOISE_DBM | in mwl8k_update_survey()
3159 struct ieee80211_channel *channel = conf->chandef.chan; in mwl8k_cmd_set_rf_channel()
3161 cfg80211_get_chandef_type(&conf->chandef); in mwl8k_cmd_set_rf_channel()
3163 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_set_rf_channel()
3168 return -ENOMEM; in mwl8k_cmd_set_rf_channel()
3170 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RF_CHANNEL); in mwl8k_cmd_set_rf_channel()
3171 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_rf_channel()
3172 cmd->action = cpu_to_le16(MWL8K_CMD_SET); in mwl8k_cmd_set_rf_channel()
3173 cmd->current_channel = channel->hw_value; in mwl8k_cmd_set_rf_channel()
3175 if (channel->band == NL80211_BAND_2GHZ) in mwl8k_cmd_set_rf_channel()
3176 cmd->channel_flags |= cpu_to_le32(0x00000001); in mwl8k_cmd_set_rf_channel()
3177 else if (channel->band == NL80211_BAND_5GHZ) in mwl8k_cmd_set_rf_channel()
3178 cmd->channel_flags |= cpu_to_le32(0x00000004); in mwl8k_cmd_set_rf_channel()
3180 if (!priv->sw_scan_start) { in mwl8k_cmd_set_rf_channel()
3183 cmd->channel_flags |= cpu_to_le32(0x00000080); in mwl8k_cmd_set_rf_channel()
3185 cmd->channel_flags |= cpu_to_le32(0x000001900); in mwl8k_cmd_set_rf_channel()
3187 cmd->channel_flags |= cpu_to_le32(0x000000900); in mwl8k_cmd_set_rf_channel()
3189 cmd->channel_flags |= cpu_to_le32(0x00000080); in mwl8k_cmd_set_rf_channel()
3192 if (priv->sw_scan_start) { in mwl8k_cmd_set_rf_channel()
3197 if (priv->channel_time != 0) in mwl8k_cmd_set_rf_channel()
3198 mwl8k_update_survey(priv, priv->acs_chan); in mwl8k_cmd_set_rf_channel()
3200 priv->channel_time = jiffies; in mwl8k_cmd_set_rf_channel()
3201 priv->acs_chan = channel; in mwl8k_cmd_set_rf_channel()
3204 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_rf_channel()
3254 return -ENOMEM; in mwl8k_cmd_set_aid()
3256 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_AID); in mwl8k_cmd_set_aid()
3257 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_aid()
3258 cmd->aid = cpu_to_le16(vif->cfg.aid); in mwl8k_cmd_set_aid()
3259 memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN); in mwl8k_cmd_set_aid()
3261 if (vif->bss_conf.use_cts_prot) { in mwl8k_cmd_set_aid()
3264 switch (vif->bss_conf.ht_operation_mode & in mwl8k_cmd_set_aid()
3277 cmd->protection_mode = cpu_to_le16(prot_mode); in mwl8k_cmd_set_aid()
3279 legacy_rate_mask_to_array(cmd->supp_rates, legacy_rate_mask); in mwl8k_cmd_set_aid()
3281 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_aid()
3308 return -ENOMEM; in mwl8k_cmd_set_rate()
3310 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE); in mwl8k_cmd_set_rate()
3311 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_rate()
3312 legacy_rate_mask_to_array(cmd->legacy_rates, legacy_rate_mask); in mwl8k_cmd_set_rate()
3313 memcpy(cmd->mcs_set, mcs_rates, 16); in mwl8k_cmd_set_rate()
3315 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_rate()
3342 return -ENOMEM; in mwl8k_cmd_finalize_join()
3344 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN); in mwl8k_cmd_finalize_join()
3345 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_finalize_join()
3346 cmd->sleep_interval = cpu_to_le32(dtim ? dtim : 1); in mwl8k_cmd_finalize_join()
3348 payload_len = framelen - ieee80211_hdrlen(payload->frame_control); in mwl8k_cmd_finalize_join()
3354 memcpy(cmd->beacon_data, &payload->u.beacon, payload_len); in mwl8k_cmd_finalize_join()
3356 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_finalize_join()
3379 return -ENOMEM; in mwl8k_cmd_set_rts_threshold()
3381 cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD); in mwl8k_cmd_set_rts_threshold()
3382 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_rts_threshold()
3383 cmd->action = cpu_to_le16(MWL8K_CMD_SET); in mwl8k_cmd_set_rts_threshold()
3384 cmd->threshold = cpu_to_le16(rts_thresh); in mwl8k_cmd_set_rts_threshold()
3386 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_rts_threshold()
3408 return -ENOMEM; in mwl8k_cmd_set_slot()
3410 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_SLOT); in mwl8k_cmd_set_slot()
3411 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_slot()
3412 cmd->action = cpu_to_le16(MWL8K_CMD_SET); in mwl8k_cmd_set_slot()
3413 cmd->short_slot = short_slot_time; in mwl8k_cmd_set_slot()
3415 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_slot()
3476 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_set_edca_params()
3482 return -ENOMEM; in mwl8k_cmd_set_edca_params()
3484 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS); in mwl8k_cmd_set_edca_params()
3485 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_edca_params()
3486 cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL); in mwl8k_cmd_set_edca_params()
3487 cmd->txop = cpu_to_le16(txop); in mwl8k_cmd_set_edca_params()
3488 if (priv->ap_fw) { in mwl8k_cmd_set_edca_params()
3489 cmd->ap.log_cw_max = cpu_to_le32(ilog2(cw_max + 1)); in mwl8k_cmd_set_edca_params()
3490 cmd->ap.log_cw_min = cpu_to_le32(ilog2(cw_min + 1)); in mwl8k_cmd_set_edca_params()
3491 cmd->ap.aifs = aifs; in mwl8k_cmd_set_edca_params()
3492 cmd->ap.txq = qnum; in mwl8k_cmd_set_edca_params()
3494 cmd->sta.log_cw_max = (u8)ilog2(cw_max + 1); in mwl8k_cmd_set_edca_params()
3495 cmd->sta.log_cw_min = (u8)ilog2(cw_min + 1); in mwl8k_cmd_set_edca_params()
3496 cmd->sta.aifs = aifs; in mwl8k_cmd_set_edca_params()
3497 cmd->sta.txq = qnum; in mwl8k_cmd_set_edca_params()
3500 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_edca_params()
3516 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_set_wmm_mode()
3522 return -ENOMEM; in mwl8k_cmd_set_wmm_mode()
3524 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_WMM_MODE); in mwl8k_cmd_set_wmm_mode()
3525 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_wmm_mode()
3526 cmd->action = cpu_to_le16(!!enable); in mwl8k_cmd_set_wmm_mode()
3528 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_wmm_mode()
3532 priv->wmm_enabled = enable; in mwl8k_cmd_set_wmm_mode()
3554 return -ENOMEM; in mwl8k_cmd_mimo_config()
3556 cmd->header.code = cpu_to_le16(MWL8K_CMD_MIMO_CONFIG); in mwl8k_cmd_mimo_config()
3557 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_mimo_config()
3558 cmd->action = cpu_to_le32((u32)MWL8K_CMD_SET); in mwl8k_cmd_mimo_config()
3559 cmd->rx_antenna_map = rx; in mwl8k_cmd_mimo_config()
3560 cmd->tx_antenna_map = tx; in mwl8k_cmd_mimo_config()
3562 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_mimo_config()
3597 return -ENOMEM; in mwl8k_cmd_use_fixed_rate_sta()
3599 cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE); in mwl8k_cmd_use_fixed_rate_sta()
3600 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_use_fixed_rate_sta()
3601 cmd->action = cpu_to_le32(MWL8K_USE_AUTO_RATE); in mwl8k_cmd_use_fixed_rate_sta()
3602 cmd->rate_type = cpu_to_le32(MWL8K_UCAST_RATE); in mwl8k_cmd_use_fixed_rate_sta()
3604 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_use_fixed_rate_sta()
3637 return -ENOMEM; in mwl8k_cmd_use_fixed_rate_ap()
3639 cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE); in mwl8k_cmd_use_fixed_rate_ap()
3640 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_use_fixed_rate_ap()
3641 cmd->action = cpu_to_le32(MWL8K_USE_AUTO_RATE); in mwl8k_cmd_use_fixed_rate_ap()
3642 cmd->multicast_rate = mcast; in mwl8k_cmd_use_fixed_rate_ap()
3643 cmd->management_rate = mgmt; in mwl8k_cmd_use_fixed_rate_ap()
3645 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_use_fixed_rate_ap()
3666 return -ENOMEM; in mwl8k_cmd_enable_sniffer()
3668 cmd->header.code = cpu_to_le16(MWL8K_CMD_ENABLE_SNIFFER); in mwl8k_cmd_enable_sniffer()
3669 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_enable_sniffer()
3670 cmd->action = cpu_to_le32(!!enable); in mwl8k_cmd_enable_sniffer()
3672 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_enable_sniffer()
3697 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_update_mac_addr()
3704 if (vif != NULL && vif->type == NL80211_IFTYPE_STATION) { in mwl8k_cmd_update_mac_addr()
3705 if (mwl8k_vif->macid + 1 == ffs(priv->sta_macids_supported)) in mwl8k_cmd_update_mac_addr()
3706 if (priv->ap_fw) in mwl8k_cmd_update_mac_addr()
3712 } else if (vif != NULL && vif->type == NL80211_IFTYPE_AP) { in mwl8k_cmd_update_mac_addr()
3713 if (mwl8k_vif->macid + 1 == ffs(priv->ap_macids_supported)) in mwl8k_cmd_update_mac_addr()
3721 return -ENOMEM; in mwl8k_cmd_update_mac_addr()
3724 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR); in mwl8k_cmd_update_mac_addr()
3726 cmd->header.code = cpu_to_le16(MWL8K_CMD_DEL_MAC_ADDR); in mwl8k_cmd_update_mac_addr()
3728 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_update_mac_addr()
3729 if (priv->ap_fw) { in mwl8k_cmd_update_mac_addr()
3730 cmd->mbss.mac_type = cpu_to_le16(mac_type); in mwl8k_cmd_update_mac_addr()
3731 memcpy(cmd->mbss.mac_addr, mac, ETH_ALEN); in mwl8k_cmd_update_mac_addr()
3733 memcpy(cmd->mac_addr, mac, ETH_ALEN); in mwl8k_cmd_update_mac_addr()
3736 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_update_mac_addr()
3776 return -ENOMEM; in mwl8k_cmd_set_rateadapt_mode()
3778 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATEADAPT_MODE); in mwl8k_cmd_set_rateadapt_mode()
3779 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_rateadapt_mode()
3780 cmd->action = cpu_to_le16(MWL8K_CMD_SET); in mwl8k_cmd_set_rateadapt_mode()
3781 cmd->mode = cpu_to_le16(mode); in mwl8k_cmd_set_rateadapt_mode()
3783 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_rateadapt_mode()
3804 return -ENOMEM; in mwl8k_cmd_get_watchdog_bitmap()
3806 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_WATCHDOG_BITMAP); in mwl8k_cmd_get_watchdog_bitmap()
3807 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_get_watchdog_bitmap()
3809 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_get_watchdog_bitmap()
3811 *bitmap = cmd->bitmap; in mwl8k_cmd_get_watchdog_bitmap()
3830 struct ieee80211_hw *hw = priv->hw; in mwl8k_watchdog_ba_events()
3836 rc = mwl8k_cmd_get_watchdog_bitmap(priv->hw, &bitmap); in mwl8k_watchdog_ba_events()
3840 spin_lock(&priv->stream_lock); in mwl8k_watchdog_ba_events()
3847 streams = &priv->ampdu[stream_index]; in mwl8k_watchdog_ba_events()
3848 if (streams->state == AMPDU_STREAM_ACTIVE) { in mwl8k_watchdog_ba_events()
3849 ieee80211_stop_tx_ba_session(streams->sta, in mwl8k_watchdog_ba_events()
3850 streams->tid); in mwl8k_watchdog_ba_events()
3851 spin_unlock(&priv->stream_lock); in mwl8k_watchdog_ba_events()
3853 spin_lock(&priv->stream_lock); in mwl8k_watchdog_ba_events()
3858 spin_unlock(&priv->stream_lock); in mwl8k_watchdog_ba_events()
3860 atomic_dec(&priv->watchdog_event_pending); in mwl8k_watchdog_ba_events()
3861 status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); in mwl8k_watchdog_ba_events()
3863 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); in mwl8k_watchdog_ba_events()
3882 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_bss_start()
3885 if (enable && (priv->running_bsses & (1 << mwl8k_vif->macid))) in mwl8k_cmd_bss_start()
3888 if (!enable && !(priv->running_bsses & (1 << mwl8k_vif->macid))) in mwl8k_cmd_bss_start()
3893 return -ENOMEM; in mwl8k_cmd_bss_start()
3895 cmd->header.code = cpu_to_le16(MWL8K_CMD_BSS_START); in mwl8k_cmd_bss_start()
3896 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_bss_start()
3897 cmd->enable = cpu_to_le32(enable); in mwl8k_cmd_bss_start()
3899 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_bss_start()
3904 priv->running_bsses |= (1 << mwl8k_vif->macid); in mwl8k_cmd_bss_start()
3906 priv->running_bsses &= ~(1 << mwl8k_vif->macid); in mwl8k_cmd_bss_start()
3913 struct mwl8k_priv *priv = hw->priv; in mwl8k_enable_bsses()
3917 list_for_each_entry_safe(mwl8k_vif, tmp_vif, &priv->vif_list, list) { in mwl8k_enable_bsses()
3918 vif = mwl8k_vif->vif; in mwl8k_enable_bsses()
3920 if (!(bitmap & (1 << mwl8k_vif->macid))) in mwl8k_enable_bsses()
3923 if (vif->type == NL80211_IFTYPE_AP) in mwl8k_enable_bsses()
3985 return -ENOMEM; in mwl8k_check_ba()
3987 cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM); in mwl8k_check_ba()
3988 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_check_ba()
3990 cmd->action = cpu_to_le32(MWL8K_BA_CHECK); in mwl8k_check_ba()
3992 cmd->create_params.queue_id = stream->idx; in mwl8k_check_ba()
3993 memcpy(&cmd->create_params.peer_mac_addr[0], stream->sta->addr, in mwl8k_check_ba()
3995 cmd->create_params.tid = stream->tid; in mwl8k_check_ba()
3997 cmd->create_params.flags = in mwl8k_check_ba()
4001 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_check_ba()
4017 return -ENOMEM; in mwl8k_create_ba()
4020 cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM); in mwl8k_create_ba()
4021 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_create_ba()
4023 cmd->action = cpu_to_le32(MWL8K_BA_CREATE); in mwl8k_create_ba()
4025 cmd->create_params.bar_thrs = cpu_to_le32((u32)buf_size); in mwl8k_create_ba()
4026 cmd->create_params.window_size = cpu_to_le32((u32)buf_size); in mwl8k_create_ba()
4027 cmd->create_params.queue_id = stream->idx; in mwl8k_create_ba()
4029 memcpy(cmd->create_params.peer_mac_addr, stream->sta->addr, ETH_ALEN); in mwl8k_create_ba()
4030 cmd->create_params.tid = stream->tid; in mwl8k_create_ba()
4031 cmd->create_params.curr_seq_no = cpu_to_le16(0); in mwl8k_create_ba()
4032 cmd->create_params.reset_seq_no_flag = 1; in mwl8k_create_ba()
4034 cmd->create_params.param_info = in mwl8k_create_ba()
4035 (stream->sta->deflink.ht_cap.ampdu_factor & in mwl8k_create_ba()
4037 ((stream->sta->deflink.ht_cap.ampdu_density << 2) & in mwl8k_create_ba()
4040 cmd->create_params.flags = in mwl8k_create_ba()
4044 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_create_ba()
4046 wiphy_debug(hw->wiphy, "Created a BA stream for %pM : tid %d\n", in mwl8k_create_ba()
4047 stream->sta->addr, stream->tid); in mwl8k_create_ba()
4062 cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM); in mwl8k_destroy_ba()
4063 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_destroy_ba()
4064 cmd->action = cpu_to_le32(MWL8K_BA_DESTROY); in mwl8k_destroy_ba()
4066 cmd->destroy_params.ba_context = cpu_to_le32(idx); in mwl8k_destroy_ba()
4067 mwl8k_post_cmd(hw, &cmd->header); in mwl8k_destroy_ba()
4069 wiphy_debug(hw->wiphy, "Deleted BA stream index %d\n", idx); in mwl8k_destroy_ba()
4112 return -ENOMEM; in mwl8k_cmd_set_new_stn_add()
4114 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN); in mwl8k_cmd_set_new_stn_add()
4115 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_new_stn_add()
4116 cmd->aid = cpu_to_le16(sta->aid); in mwl8k_cmd_set_new_stn_add()
4117 memcpy(cmd->mac_addr, sta->addr, ETH_ALEN); in mwl8k_cmd_set_new_stn_add()
4118 cmd->stn_id = cpu_to_le16(sta->aid); in mwl8k_cmd_set_new_stn_add()
4119 cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD); in mwl8k_cmd_set_new_stn_add()
4120 if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) in mwl8k_cmd_set_new_stn_add()
4121 rates = sta->deflink.supp_rates[NL80211_BAND_2GHZ]; in mwl8k_cmd_set_new_stn_add()
4123 rates = sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 5; in mwl8k_cmd_set_new_stn_add()
4124 cmd->legacy_rates = cpu_to_le32(rates); in mwl8k_cmd_set_new_stn_add()
4125 if (sta->deflink.ht_cap.ht_supported) { in mwl8k_cmd_set_new_stn_add()
4126 cmd->ht_rates[0] = sta->deflink.ht_cap.mcs.rx_mask[0]; in mwl8k_cmd_set_new_stn_add()
4127 cmd->ht_rates[1] = sta->deflink.ht_cap.mcs.rx_mask[1]; in mwl8k_cmd_set_new_stn_add()
4128 cmd->ht_rates[2] = sta->deflink.ht_cap.mcs.rx_mask[2]; in mwl8k_cmd_set_new_stn_add()
4129 cmd->ht_rates[3] = sta->deflink.ht_cap.mcs.rx_mask[3]; in mwl8k_cmd_set_new_stn_add()
4130 cmd->ht_capabilities_info = cpu_to_le16(sta->deflink.ht_cap.cap); in mwl8k_cmd_set_new_stn_add()
4131 cmd->mac_ht_param_info = (sta->deflink.ht_cap.ampdu_factor & 3) | in mwl8k_cmd_set_new_stn_add()
4132 ((sta->deflink.ht_cap.ampdu_density & 7) << 2); in mwl8k_cmd_set_new_stn_add()
4133 cmd->is_qos_sta = 1; in mwl8k_cmd_set_new_stn_add()
4136 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_set_new_stn_add()
4150 return -ENOMEM; in mwl8k_cmd_set_new_stn_add_self()
4152 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN); in mwl8k_cmd_set_new_stn_add_self()
4153 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_new_stn_add_self()
4154 memcpy(cmd->mac_addr, vif->addr, ETH_ALEN); in mwl8k_cmd_set_new_stn_add_self()
4156 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_set_new_stn_add_self()
4166 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_set_new_stn_del()
4170 spin_lock(&priv->stream_lock); in mwl8k_cmd_set_new_stn_del()
4174 s = &priv->ampdu[i]; in mwl8k_cmd_set_new_stn_del()
4175 if (s->state != AMPDU_NO_STREAM) { in mwl8k_cmd_set_new_stn_del()
4176 if (memcmp(s->sta->addr, addr, ETH_ALEN) == 0) { in mwl8k_cmd_set_new_stn_del()
4177 if (s->state == AMPDU_STREAM_ACTIVE) { in mwl8k_cmd_set_new_stn_del()
4178 idx = s->idx; in mwl8k_cmd_set_new_stn_del()
4179 spin_unlock(&priv->stream_lock); in mwl8k_cmd_set_new_stn_del()
4181 spin_lock(&priv->stream_lock); in mwl8k_cmd_set_new_stn_del()
4182 } else if (s->state == AMPDU_STREAM_NEW) { in mwl8k_cmd_set_new_stn_del()
4189 spin_unlock(&priv->stream_lock); in mwl8k_cmd_set_new_stn_del()
4193 return -ENOMEM; in mwl8k_cmd_set_new_stn_del()
4195 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN); in mwl8k_cmd_set_new_stn_del()
4196 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_new_stn_del()
4197 memcpy(cmd->mac_addr, addr, ETH_ALEN); in mwl8k_cmd_set_new_stn_del()
4198 cmd->action = cpu_to_le16(MWL8K_STA_ACTION_REMOVE); in mwl8k_cmd_set_new_stn_del()
4200 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_set_new_stn_del()
4280 return -ENOMEM; in mwl8k_cmd_update_encryption_enable()
4282 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_ENCRYPTION); in mwl8k_cmd_update_encryption_enable()
4283 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_update_encryption_enable()
4284 cmd->action = cpu_to_le32(MWL8K_ENCR_ENABLE); in mwl8k_cmd_update_encryption_enable()
4285 memcpy(cmd->mac_addr, addr, ETH_ALEN); in mwl8k_cmd_update_encryption_enable()
4286 cmd->encr_type = encr_type; in mwl8k_cmd_update_encryption_enable()
4288 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_update_encryption_enable()
4298 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_ENCRYPTION); in mwl8k_encryption_set_cmd_info()
4299 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_encryption_set_cmd_info()
4300 cmd->length = cpu_to_le16(sizeof(*cmd) - in mwl8k_encryption_set_cmd_info()
4302 cmd->key_id = cpu_to_le32(key->keyidx); in mwl8k_encryption_set_cmd_info()
4303 cmd->key_len = cpu_to_le16(key->keylen); in mwl8k_encryption_set_cmd_info()
4304 memcpy(cmd->mac_addr, addr, ETH_ALEN); in mwl8k_encryption_set_cmd_info()
4306 switch (key->cipher) { in mwl8k_encryption_set_cmd_info()
4309 cmd->key_type_id = cpu_to_le16(MWL8K_ALG_WEP); in mwl8k_encryption_set_cmd_info()
4310 if (key->keyidx == 0) in mwl8k_encryption_set_cmd_info()
4311 cmd->key_info = cpu_to_le32(MWL8K_KEY_FLAG_WEP_TXKEY); in mwl8k_encryption_set_cmd_info()
4315 cmd->key_type_id = cpu_to_le16(MWL8K_ALG_TKIP); in mwl8k_encryption_set_cmd_info()
4316 cmd->key_info = (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) in mwl8k_encryption_set_cmd_info()
4319 cmd->key_info |= cpu_to_le32(MWL8K_KEY_FLAG_MICKEY_VALID in mwl8k_encryption_set_cmd_info()
4323 cmd->key_type_id = cpu_to_le16(MWL8K_ALG_CCMP); in mwl8k_encryption_set_cmd_info()
4324 cmd->key_info = (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) in mwl8k_encryption_set_cmd_info()
4329 return -ENOTSUPP; in mwl8k_encryption_set_cmd_info()
4349 return -ENOMEM; in mwl8k_cmd_encryption_set_key()
4355 idx = key->keyidx; in mwl8k_cmd_encryption_set_key()
4357 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) in mwl8k_cmd_encryption_set_key()
4362 switch (key->cipher) { in mwl8k_cmd_encryption_set_key()
4365 if (!mwl8k_vif->wep_key_conf[idx].enabled) { in mwl8k_cmd_encryption_set_key()
4366 memcpy(mwl8k_vif->wep_key_conf[idx].key, key, in mwl8k_cmd_encryption_set_key()
4367 sizeof(*key) + key->keylen); in mwl8k_cmd_encryption_set_key()
4368 mwl8k_vif->wep_key_conf[idx].enabled = 1; in mwl8k_cmd_encryption_set_key()
4371 keymlen = key->keylen; in mwl8k_cmd_encryption_set_key()
4378 keymlen = key->keylen; in mwl8k_cmd_encryption_set_key()
4381 rc = -ENOTSUPP; in mwl8k_cmd_encryption_set_key()
4385 memcpy(&cmd->tkip, key->key, keymlen); in mwl8k_cmd_encryption_set_key()
4386 cmd->action = cpu_to_le32(action); in mwl8k_cmd_encryption_set_key()
4388 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_encryption_set_key()
4406 return -ENOMEM; in mwl8k_cmd_encryption_remove_key()
4412 if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || in mwl8k_cmd_encryption_remove_key()
4413 key->cipher == WLAN_CIPHER_SUITE_WEP104) in mwl8k_cmd_encryption_remove_key()
4414 mwl8k_vif->wep_key_conf[key->keyidx].enabled = 0; in mwl8k_cmd_encryption_remove_key()
4416 cmd->action = cpu_to_le32(MWL8K_ENCR_REMOVE_KEY); in mwl8k_cmd_encryption_remove_key()
4418 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_encryption_remove_key()
4435 struct mwl8k_priv *priv = hw->priv; in mwl8k_set_key()
4437 if (vif->type == NL80211_IFTYPE_STATION && !priv->ap_fw) in mwl8k_set_key()
4438 return -EOPNOTSUPP; in mwl8k_set_key()
4441 addr = vif->addr; in mwl8k_set_key()
4443 addr = sta->addr; in mwl8k_set_key()
4450 if ((key->cipher == WLAN_CIPHER_SUITE_WEP40) in mwl8k_set_key()
4451 || (key->cipher == WLAN_CIPHER_SUITE_WEP104)) in mwl8k_set_key()
4461 mwl8k_vif->is_hw_crypto_enabled = true; in mwl8k_set_key()
4483 /* Peer type - AP vs. STA. */
4522 /* Peer info - valid during add/update. */
4529 /* Peer Entry flags - used to define the type of the peer node */
4543 return -ENOMEM; in mwl8k_cmd_update_stadb_add()
4545 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB); in mwl8k_cmd_update_stadb_add()
4546 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_update_stadb_add()
4547 cmd->action = cpu_to_le32(MWL8K_STA_DB_MODIFY_ENTRY); in mwl8k_cmd_update_stadb_add()
4548 memcpy(cmd->peer_addr, sta->addr, ETH_ALEN); in mwl8k_cmd_update_stadb_add()
4550 p = &cmd->peer_info; in mwl8k_cmd_update_stadb_add()
4551 p->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT; in mwl8k_cmd_update_stadb_add()
4552 p->basic_caps = cpu_to_le16(vif->bss_conf.assoc_capability); in mwl8k_cmd_update_stadb_add()
4553 p->ht_support = sta->deflink.ht_cap.ht_supported; in mwl8k_cmd_update_stadb_add()
4554 p->ht_caps = cpu_to_le16(sta->deflink.ht_cap.cap); in mwl8k_cmd_update_stadb_add()
4555 p->extended_ht_caps = (sta->deflink.ht_cap.ampdu_factor & 3) | in mwl8k_cmd_update_stadb_add()
4556 ((sta->deflink.ht_cap.ampdu_density & 7) << 2); in mwl8k_cmd_update_stadb_add()
4557 if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) in mwl8k_cmd_update_stadb_add()
4558 rates = sta->deflink.supp_rates[NL80211_BAND_2GHZ]; in mwl8k_cmd_update_stadb_add()
4560 rates = sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 5; in mwl8k_cmd_update_stadb_add()
4561 legacy_rate_mask_to_array(p->legacy_rates, rates); in mwl8k_cmd_update_stadb_add()
4562 memcpy(p->ht_rates, &sta->deflink.ht_cap.mcs, 16); in mwl8k_cmd_update_stadb_add()
4563 p->interop = 1; in mwl8k_cmd_update_stadb_add()
4564 p->amsdu_enabled = 0; in mwl8k_cmd_update_stadb_add()
4566 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_update_stadb_add()
4568 rc = p->station_id; in mwl8k_cmd_update_stadb_add()
4582 return -ENOMEM; in mwl8k_cmd_update_stadb_del()
4584 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB); in mwl8k_cmd_update_stadb_del()
4585 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_update_stadb_del()
4586 cmd->action = cpu_to_le32(MWL8K_STA_DB_DEL_ENTRY); in mwl8k_cmd_update_stadb_del()
4587 memcpy(cmd->peer_addr, addr, ETH_ALEN); in mwl8k_cmd_update_stadb_del()
4589 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_update_stadb_del()
4602 struct mwl8k_priv *priv = hw->priv; in mwl8k_interrupt()
4605 status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); in mwl8k_interrupt()
4611 tasklet_schedule(&priv->poll_tx_task); in mwl8k_interrupt()
4616 tasklet_schedule(&priv->poll_rx_task); in mwl8k_interrupt()
4621 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); in mwl8k_interrupt()
4623 atomic_inc(&priv->watchdog_event_pending); in mwl8k_interrupt()
4625 ieee80211_queue_work(hw, &priv->watchdog_ba_handle); in mwl8k_interrupt()
4629 iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); in mwl8k_interrupt()
4632 if (priv->hostcmd_wait != NULL) in mwl8k_interrupt()
4633 complete(priv->hostcmd_wait); in mwl8k_interrupt()
4637 if (!mutex_is_locked(&priv->fw_mutex) && in mwl8k_interrupt()
4638 priv->radio_on && priv->pending_tx_pkts) in mwl8k_interrupt()
4648 struct ieee80211_hw *hw = pci_get_drvdata(priv->pdev); in mwl8k_tx_poll()
4649 int limit; in mwl8k_tx_poll() local
4652 limit = 32; in mwl8k_tx_poll()
4654 spin_lock(&priv->tx_lock); in mwl8k_tx_poll()
4657 limit -= mwl8k_txq_reclaim(hw, i, limit, 0); in mwl8k_tx_poll()
4659 if (!priv->pending_tx_pkts && priv->tx_wait != NULL) { in mwl8k_tx_poll()
4660 complete(priv->tx_wait); in mwl8k_tx_poll()
4661 priv->tx_wait = NULL; in mwl8k_tx_poll()
4664 spin_unlock(&priv->tx_lock); in mwl8k_tx_poll()
4666 if (limit) { in mwl8k_tx_poll()
4668 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); in mwl8k_tx_poll()
4670 tasklet_schedule(&priv->poll_tx_task); in mwl8k_tx_poll()
4677 struct ieee80211_hw *hw = pci_get_drvdata(priv->pdev); in mwl8k_rx_poll()
4678 int limit; in mwl8k_rx_poll() local
4680 limit = 32; in mwl8k_rx_poll()
4681 limit -= rxq_process(hw, 0, limit); in mwl8k_rx_poll()
4682 limit -= rxq_refill(hw, 0, limit); in mwl8k_rx_poll()
4684 if (limit) { in mwl8k_rx_poll()
4686 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); in mwl8k_rx_poll()
4688 tasklet_schedule(&priv->poll_rx_task); in mwl8k_rx_poll()
4700 struct mwl8k_priv *priv = hw->priv; in mwl8k_tx()
4703 if (!priv->radio_on) { in mwl8k_tx()
4704 wiphy_debug(hw->wiphy, in mwl8k_tx()
4710 mwl8k_txq_xmit(hw, index, control->sta, skb); in mwl8k_tx()
4715 struct mwl8k_priv *priv = hw->priv; in mwl8k_start()
4718 rc = request_irq(priv->pdev->irq, mwl8k_interrupt, in mwl8k_start()
4721 priv->irq = -1; in mwl8k_start()
4722 wiphy_err(hw->wiphy, "failed to register IRQ handler\n"); in mwl8k_start()
4723 return -EIO; in mwl8k_start()
4725 priv->irq = priv->pdev->irq; in mwl8k_start()
4728 tasklet_enable(&priv->poll_tx_task); in mwl8k_start()
4729 tasklet_enable(&priv->poll_rx_task); in mwl8k_start()
4732 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_start()
4734 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); in mwl8k_start()
4740 if (!priv->ap_fw) { in mwl8k_start()
4762 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_start()
4763 free_irq(priv->pdev->irq, hw); in mwl8k_start()
4764 priv->irq = -1; in mwl8k_start()
4765 tasklet_disable(&priv->poll_tx_task); in mwl8k_start()
4766 tasklet_disable(&priv->poll_rx_task); in mwl8k_start()
4776 struct mwl8k_priv *priv = hw->priv; in mwl8k_stop()
4779 if (!priv->hw_restart_in_progress) in mwl8k_stop()
4785 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_stop()
4786 if (priv->irq != -1) { in mwl8k_stop()
4787 free_irq(priv->pdev->irq, hw); in mwl8k_stop()
4788 priv->irq = -1; in mwl8k_stop()
4792 cancel_work_sync(&priv->finalize_join_worker); in mwl8k_stop()
4793 cancel_work_sync(&priv->watchdog_ba_handle); in mwl8k_stop()
4794 if (priv->beacon_skb != NULL) in mwl8k_stop()
4795 dev_kfree_skb(priv->beacon_skb); in mwl8k_stop()
4798 tasklet_disable(&priv->poll_tx_task); in mwl8k_stop()
4799 tasklet_disable(&priv->poll_rx_task); in mwl8k_stop()
4811 struct mwl8k_priv *priv = hw->priv; in mwl8k_add_interface()
4822 if (priv->sniffer_enabled) { in mwl8k_add_interface()
4823 wiphy_info(hw->wiphy, in mwl8k_add_interface()
4825 return -EINVAL; in mwl8k_add_interface()
4828 di = priv->device_info; in mwl8k_add_interface()
4829 switch (vif->type) { in mwl8k_add_interface()
4831 if (!priv->ap_fw && di->fw_image_ap) { in mwl8k_add_interface()
4833 if (!list_empty(&priv->vif_list)) in mwl8k_add_interface()
4834 return -EBUSY; in mwl8k_add_interface()
4835 rc = mwl8k_reload_firmware(hw, di->fw_image_ap); in mwl8k_add_interface()
4839 macids_supported = priv->ap_macids_supported; in mwl8k_add_interface()
4842 if (priv->ap_fw && di->fw_image_sta) { in mwl8k_add_interface()
4843 if (!list_empty(&priv->vif_list)) { in mwl8k_add_interface()
4844 wiphy_warn(hw->wiphy, "AP interface is running.\n" in mwl8k_add_interface()
4851 di->fw_image_sta); in mwl8k_add_interface()
4856 macids_supported = priv->sta_macids_supported; in mwl8k_add_interface()
4859 return -EINVAL; in mwl8k_add_interface()
4862 macid = ffs(macids_supported & ~priv->macids_used); in mwl8k_add_interface()
4863 if (!macid--) in mwl8k_add_interface()
4864 return -EBUSY; in mwl8k_add_interface()
4869 mwl8k_vif->vif = vif; in mwl8k_add_interface()
4870 mwl8k_vif->macid = macid; in mwl8k_add_interface()
4871 mwl8k_vif->seqno = 0; in mwl8k_add_interface()
4872 memcpy(mwl8k_vif->bssid, vif->addr, ETH_ALEN); in mwl8k_add_interface()
4873 mwl8k_vif->is_hw_crypto_enabled = false; in mwl8k_add_interface()
4876 mwl8k_cmd_set_mac_addr(hw, vif, vif->addr); in mwl8k_add_interface()
4878 if (vif->type == NL80211_IFTYPE_AP) in mwl8k_add_interface()
4881 priv->macids_used |= 1 << mwl8k_vif->macid; in mwl8k_add_interface()
4882 list_add_tail(&mwl8k_vif->list, &priv->vif_list); in mwl8k_add_interface()
4889 /* Has ieee80211_restart_hw re-added the removed interfaces? */ in mwl8k_remove_vif()
4890 if (!priv->macids_used) in mwl8k_remove_vif()
4893 priv->macids_used &= ~(1 << vif->macid); in mwl8k_remove_vif()
4894 list_del(&vif->list); in mwl8k_remove_vif()
4900 struct mwl8k_priv *priv = hw->priv; in mwl8k_remove_interface()
4903 if (vif->type == NL80211_IFTYPE_AP) in mwl8k_remove_interface()
4904 mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr); in mwl8k_remove_interface()
4906 mwl8k_cmd_del_mac_addr(hw, vif, vif->addr); in mwl8k_remove_interface()
4915 struct ieee80211_hw *hw = priv->hw; in mwl8k_hw_restart_work()
4920 if (priv->hostcmd_wait != NULL) { in mwl8k_hw_restart_work()
4921 complete(priv->hostcmd_wait); in mwl8k_hw_restart_work()
4922 priv->hostcmd_wait = NULL; in mwl8k_hw_restart_work()
4925 priv->hw_restart_owner = current; in mwl8k_hw_restart_work()
4926 di = priv->device_info; in mwl8k_hw_restart_work()
4929 if (priv->ap_fw) in mwl8k_hw_restart_work()
4930 rc = mwl8k_reload_firmware(hw, di->fw_image_ap); in mwl8k_hw_restart_work()
4932 rc = mwl8k_reload_firmware(hw, di->fw_image_sta); in mwl8k_hw_restart_work()
4937 priv->hw_restart_owner = NULL; in mwl8k_hw_restart_work()
4938 priv->hw_restart_in_progress = false; in mwl8k_hw_restart_work()
4949 wiphy_err(hw->wiphy, "Firmware restarted successfully\n"); in mwl8k_hw_restart_work()
4955 wiphy_err(hw->wiphy, "Firmware restart failed\n"); in mwl8k_hw_restart_work()
4960 struct ieee80211_conf *conf = &hw->conf; in mwl8k_config()
4961 struct mwl8k_priv *priv = hw->priv; in mwl8k_config()
4968 if (conf->flags & IEEE80211_CONF_IDLE) in mwl8k_config()
4981 if (conf->power_level > 18) in mwl8k_config()
4982 conf->power_level = 18; in mwl8k_config()
4984 if (priv->ap_fw) { in mwl8k_config()
4986 if (conf->flags & IEEE80211_CONF_CHANGE_POWER) { in mwl8k_config()
4987 rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level); in mwl8k_config()
4994 rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level); in mwl8k_config()
5010 struct mwl8k_priv *priv = hw->priv; in mwl8k_bss_info_changed_sta()
5021 if ((changed & BSS_CHANGED_ASSOC) && !vif->cfg.assoc) in mwl8k_bss_info_changed_sta()
5022 priv->capture_beacon = false; in mwl8k_bss_info_changed_sta()
5027 if (vif->cfg.assoc) { in mwl8k_bss_info_changed_sta()
5032 ap = ieee80211_find_sta(vif, vif->bss_conf.bssid); in mwl8k_bss_info_changed_sta()
5038 if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) { in mwl8k_bss_info_changed_sta()
5039 ap_legacy_rates = ap->deflink.supp_rates[NL80211_BAND_2GHZ]; in mwl8k_bss_info_changed_sta()
5042 ap->deflink.supp_rates[NL80211_BAND_5GHZ] << 5; in mwl8k_bss_info_changed_sta()
5044 memcpy(ap_mcs_rates, &ap->deflink.ht_cap.mcs, 16); in mwl8k_bss_info_changed_sta()
5049 if (!priv->ap_fw) { in mwl8k_bss_info_changed_sta()
5065 idx = ffs(vif->bss_conf.basic_rates); in mwl8k_bss_info_changed_sta()
5067 idx--; in mwl8k_bss_info_changed_sta()
5069 if (hw->conf.chandef.chan->band == in mwl8k_bss_info_changed_sta()
5082 vif->bss_conf.use_short_preamble); in mwl8k_bss_info_changed_sta()
5087 if ((changed & BSS_CHANGED_ERP_SLOT) && !priv->ap_fw) { in mwl8k_bss_info_changed_sta()
5088 rc = mwl8k_cmd_set_slot(hw, vif->bss_conf.use_short_slot); in mwl8k_bss_info_changed_sta()
5093 if (vif->cfg.assoc && !priv->ap_fw && in mwl8k_bss_info_changed_sta()
5101 if (vif->cfg.assoc && in mwl8k_bss_info_changed_sta()
5107 memcpy(priv->capture_bssid, vif->bss_conf.bssid, ETH_ALEN); in mwl8k_bss_info_changed_sta()
5108 priv->capture_beacon = true; in mwl8k_bss_info_changed_sta()
5126 vif->bss_conf.use_short_preamble); in mwl8k_bss_info_changed_ap()
5137 * and management frames (such as probe responses -- in mwl8k_bss_info_changed_ap()
5140 idx = ffs(vif->bss_conf.basic_rates); in mwl8k_bss_info_changed_ap()
5142 idx--; in mwl8k_bss_info_changed_ap()
5144 if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) in mwl8k_bss_info_changed_ap()
5157 mwl8k_cmd_set_beacon(hw, vif, skb->data, skb->len); in mwl8k_bss_info_changed_ap()
5163 mwl8k_cmd_bss_start(hw, vif, info->enable_beacon); in mwl8k_bss_info_changed_ap()
5173 if (vif->type == NL80211_IFTYPE_STATION) in mwl8k_bss_info_changed()
5175 if (vif->type == NL80211_IFTYPE_AP) in mwl8k_bss_info_changed()
5201 struct mwl8k_priv *priv = hw->priv; in mwl8k_configure_filter_sniffer()
5208 if (!list_empty(&priv->vif_list)) { in mwl8k_configure_filter_sniffer()
5210 wiphy_info(hw->wiphy, in mwl8k_configure_filter_sniffer()
5215 if (!priv->sniffer_enabled) { in mwl8k_configure_filter_sniffer()
5218 priv->sniffer_enabled = true; in mwl8k_configure_filter_sniffer()
5230 if (!list_empty(&priv->vif_list)) in mwl8k_first_vif()
5231 return list_entry(priv->vif_list.next, struct mwl8k_vif, list); in mwl8k_first_vif()
5241 struct mwl8k_priv *priv = hw->priv; in mwl8k_configure_filter()
5245 * AP firmware doesn't allow fine-grained control over in mwl8k_configure_filter()
5248 if (priv->ap_fw) { in mwl8k_configure_filter()
5272 if (priv->sniffer_enabled) { in mwl8k_configure_filter()
5274 priv->sniffer_enabled = false; in mwl8k_configure_filter()
5297 bssid = mwl8k_vif->vif->bss_conf.bssid; in mwl8k_configure_filter()
5307 * packet that ->prepare_multicast() built and replace it with in mwl8k_configure_filter()
5333 struct mwl8k_priv *priv = hw->priv; in mwl8k_sta_remove()
5335 if (priv->ap_fw) in mwl8k_sta_remove()
5336 return mwl8k_cmd_set_new_stn_del(hw, vif, sta->addr); in mwl8k_sta_remove()
5338 return mwl8k_cmd_update_stadb_del(hw, vif, sta->addr); in mwl8k_sta_remove()
5345 struct mwl8k_priv *priv = hw->priv; in mwl8k_sta_add()
5351 if (!priv->ap_fw) { in mwl8k_sta_add()
5354 MWL8K_STA(sta)->peer_id = ret; in mwl8k_sta_add()
5355 if (sta->deflink.ht_cap.ht_supported) in mwl8k_sta_add()
5356 MWL8K_STA(sta)->is_ampdu_allowed = true; in mwl8k_sta_add()
5365 key = IEEE80211_KEY_CONF(mwl8k_vif->wep_key_conf[i].key); in mwl8k_sta_add()
5366 if (mwl8k_vif->wep_key_conf[i].enabled) in mwl8k_sta_add()
5377 struct mwl8k_priv *priv = hw->priv; in mwl8k_conf_tx()
5382 BUG_ON(queue > MWL8K_TX_WMM_QUEUES - 1); in mwl8k_conf_tx()
5383 memcpy(&priv->wmm_params[queue], params, sizeof(*params)); in mwl8k_conf_tx()
5385 if (!priv->wmm_enabled) in mwl8k_conf_tx()
5389 int q = MWL8K_TX_WMM_QUEUES - 1 - queue; in mwl8k_conf_tx()
5391 params->cw_min, in mwl8k_conf_tx()
5392 params->cw_max, in mwl8k_conf_tx()
5393 params->aifs, in mwl8k_conf_tx()
5394 params->txop); in mwl8k_conf_tx()
5412 struct mwl8k_priv *priv = hw->priv; in mwl8k_get_survey()
5413 struct ieee80211_conf *conf = &hw->conf; in mwl8k_get_survey()
5416 if (priv->ap_fw) { in mwl8k_get_survey()
5417 sband = hw->wiphy->bands[NL80211_BAND_2GHZ]; in mwl8k_get_survey()
5419 if (sband && idx >= sband->n_channels) { in mwl8k_get_survey()
5420 idx -= sband->n_channels; in mwl8k_get_survey()
5425 sband = hw->wiphy->bands[NL80211_BAND_5GHZ]; in mwl8k_get_survey()
5427 if (!sband || idx >= sband->n_channels) in mwl8k_get_survey()
5428 return -ENOENT; in mwl8k_get_survey()
5430 memcpy(survey, &priv->survey[idx], sizeof(*survey)); in mwl8k_get_survey()
5431 survey->channel = &sband->channels[idx]; in mwl8k_get_survey()
5437 return -ENOENT; in mwl8k_get_survey()
5439 survey->channel = conf->chandef.chan; in mwl8k_get_survey()
5440 survey->filled = SURVEY_INFO_NOISE_DBM; in mwl8k_get_survey()
5441 survey->noise = priv->noise; in mwl8k_get_survey()
5452 struct ieee80211_sta *sta = params->sta; in mwl8k_ampdu_action()
5453 enum ieee80211_ampdu_mlme_action action = params->action; in mwl8k_ampdu_action()
5454 u16 tid = params->tid; in mwl8k_ampdu_action()
5455 u16 *ssn = ¶ms->ssn; in mwl8k_ampdu_action()
5456 u8 buf_size = params->buf_size; in mwl8k_ampdu_action()
5458 struct mwl8k_priv *priv = hw->priv; in mwl8k_ampdu_action()
5460 u8 *addr = sta->addr, idx; in mwl8k_ampdu_action()
5464 return -ENOTSUPP; in mwl8k_ampdu_action()
5466 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5490 wiphy_warn(hw->wiphy, "Unexpected call to %s. " in mwl8k_ampdu_action()
5495 wiphy_debug(hw->wiphy, "no free AMPDU streams\n"); in mwl8k_ampdu_action()
5496 rc = -EBUSY; in mwl8k_ampdu_action()
5499 stream->state = AMPDU_STREAM_IN_PROGRESS; in mwl8k_ampdu_action()
5502 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5506 if (!sta_info->is_ampdu_allowed) { in mwl8k_ampdu_action()
5507 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5509 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5510 return -EBUSY; in mwl8k_ampdu_action()
5516 * return -EBUSY. Avoid retrying mwl8k_check_ba in in mwl8k_ampdu_action()
5519 if (!rc || rc == -EBUSY) in mwl8k_ampdu_action()
5528 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5530 wiphy_err(hw->wiphy, "Stream for tid %d busy after %d" in mwl8k_ampdu_action()
5533 rc = -EBUSY; in mwl8k_ampdu_action()
5542 if (stream->state == AMPDU_STREAM_ACTIVE) { in mwl8k_ampdu_action()
5543 idx = stream->idx; in mwl8k_ampdu_action()
5544 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5546 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5554 BUG_ON(stream->state != AMPDU_STREAM_IN_PROGRESS); in mwl8k_ampdu_action()
5555 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5557 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5559 stream->state = AMPDU_STREAM_ACTIVE; in mwl8k_ampdu_action()
5561 idx = stream->idx; in mwl8k_ampdu_action()
5562 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5564 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5565 wiphy_debug(hw->wiphy, in mwl8k_ampdu_action()
5573 rc = -ENOTSUPP; in mwl8k_ampdu_action()
5576 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5584 struct mwl8k_priv *priv = hw->priv; in mwl8k_sw_scan_start()
5587 if (!priv->ap_fw) in mwl8k_sw_scan_start()
5591 priv->channel_time = 0; in mwl8k_sw_scan_start()
5592 ioread32(priv->regs + BBU_RXRDY_CNT_REG); in mwl8k_sw_scan_start()
5593 ioread32(priv->regs + NOK_CCA_CNT_REG); in mwl8k_sw_scan_start()
5594 mwl8k_cmd_bbp_reg_access(priv->hw, 0, BBU_AVG_NOISE_VAL, &tmp); in mwl8k_sw_scan_start()
5596 priv->sw_scan_start = true; in mwl8k_sw_scan_start()
5602 struct mwl8k_priv *priv = hw->priv; in mwl8k_sw_scan_complete()
5605 if (!priv->ap_fw) in mwl8k_sw_scan_complete()
5608 priv->sw_scan_start = false; in mwl8k_sw_scan_complete()
5611 priv->channel_time = 0; in mwl8k_sw_scan_complete()
5612 ioread32(priv->regs + BBU_RXRDY_CNT_REG); in mwl8k_sw_scan_complete()
5613 ioread32(priv->regs + NOK_CCA_CNT_REG); in mwl8k_sw_scan_complete()
5614 mwl8k_cmd_bbp_reg_access(priv->hw, 0, BBU_AVG_NOISE_VAL, &tmp); in mwl8k_sw_scan_complete()
5648 struct sk_buff *skb = priv->beacon_skb; in mwl8k_finalize_join_worker()
5649 struct ieee80211_mgmt *mgmt = (void *)skb->data; in mwl8k_finalize_join_worker()
5650 int len = skb->len - offsetof(struct ieee80211_mgmt, u.beacon.variable); in mwl8k_finalize_join_worker()
5652 mgmt->u.beacon.variable, len); in mwl8k_finalize_join_worker()
5658 mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, dtim_period); in mwl8k_finalize_join_worker()
5661 priv->beacon_skb = NULL; in mwl8k_finalize_join_worker()
5672 #define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw"
5676 #define _MWL8K_8764_AP_FW(api) "mwl8k/fmimage_8764_ap-" #api ".fw"
5733 "Trying alternative firmware %s\n", pci_name(priv->pdev), in mwl8k_request_alt_fw()
5734 priv->fw_pref, priv->fw_alt); in mwl8k_request_alt_fw()
5735 rc = mwl8k_request_fw(priv, priv->fw_alt, &priv->fw_ucode, true); in mwl8k_request_alt_fw()
5738 pci_name(priv->pdev), priv->fw_alt); in mwl8k_request_alt_fw()
5748 struct mwl8k_device_info *di = priv->device_info; in mwl8k_fw_state_machine()
5751 switch (priv->fw_state) { in mwl8k_fw_state_machine()
5755 pci_name(priv->pdev), di->helper_image); in mwl8k_fw_state_machine()
5758 priv->fw_helper = fw; in mwl8k_fw_state_machine()
5759 rc = mwl8k_request_fw(priv, priv->fw_pref, &priv->fw_ucode, in mwl8k_fw_state_machine()
5761 if (rc && priv->fw_alt) { in mwl8k_fw_state_machine()
5765 priv->fw_state = FW_STATE_LOADING_ALT; in mwl8k_fw_state_machine()
5769 priv->fw_state = FW_STATE_LOADING_PREF; in mwl8k_fw_state_machine()
5774 if (priv->fw_alt) { in mwl8k_fw_state_machine()
5778 priv->fw_state = FW_STATE_LOADING_ALT; in mwl8k_fw_state_machine()
5782 priv->fw_ucode = fw; in mwl8k_fw_state_machine()
5787 complete(&priv->firmware_loading_complete); in mwl8k_fw_state_machine()
5794 pci_name(priv->pdev), di->helper_image); in mwl8k_fw_state_machine()
5797 priv->fw_ucode = fw; in mwl8k_fw_state_machine()
5802 complete(&priv->firmware_loading_complete); in mwl8k_fw_state_machine()
5807 MWL8K_NAME, priv->fw_state); in mwl8k_fw_state_machine()
5814 priv->fw_state = FW_STATE_ERROR; in mwl8k_fw_state_machine()
5815 complete(&priv->firmware_loading_complete); in mwl8k_fw_state_machine()
5817 device_release_driver(&priv->pdev->dev); in mwl8k_fw_state_machine()
5824 struct mwl8k_priv *priv = hw->priv; in mwl8k_init_firmware()
5835 wiphy_err(hw->wiphy, "Firmware files not found\n"); in mwl8k_init_firmware()
5845 wiphy_err(hw->wiphy, "Cannot start firmware\n"); in mwl8k_init_firmware()
5854 count--; in mwl8k_init_firmware()
5855 wiphy_err(hw->wiphy, "Trying to reload the firmware again\n"); in mwl8k_init_firmware()
5865 struct mwl8k_priv *priv = hw->priv; in mwl8k_init_txqs()
5873 if (priv->ap_fw) in mwl8k_init_txqs()
5874 iowrite32(priv->txq[i].txd_dma, in mwl8k_init_txqs()
5875 priv->sram + priv->txq_offset[i]); in mwl8k_init_txqs()
5883 struct mwl8k_priv *priv = hw->priv; in mwl8k_probe_hw()
5887 if (priv->ap_fw) { in mwl8k_probe_hw()
5888 priv->rxd_ops = priv->device_info->ap_rxd_ops; in mwl8k_probe_hw()
5889 if (priv->rxd_ops == NULL) { in mwl8k_probe_hw()
5890 wiphy_err(hw->wiphy, in mwl8k_probe_hw()
5892 rc = -ENOENT; in mwl8k_probe_hw()
5896 priv->rxd_ops = &rxd_sta_ops; in mwl8k_probe_hw()
5899 priv->sniffer_enabled = false; in mwl8k_probe_hw()
5900 priv->wmm_enabled = false; in mwl8k_probe_hw()
5901 priv->pending_tx_pkts = 0; in mwl8k_probe_hw()
5902 atomic_set(&priv->watchdog_event_pending, 0); in mwl8k_probe_hw()
5915 priv->num_ampdu_queues = 0; in mwl8k_probe_hw()
5916 if (!priv->ap_fw) { in mwl8k_probe_hw()
5922 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); in mwl8k_probe_hw()
5923 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_probe_hw()
5926 priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); in mwl8k_probe_hw()
5928 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); in mwl8k_probe_hw()
5930 rc = request_irq(priv->pdev->irq, mwl8k_interrupt, in mwl8k_probe_hw()
5933 wiphy_err(hw->wiphy, "failed to register IRQ handler\n"); in mwl8k_probe_hw()
5943 if (!priv->hw_restart_in_progress) in mwl8k_probe_hw()
5944 memset(priv->ampdu, 0, sizeof(priv->ampdu)); in mwl8k_probe_hw()
5951 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_probe_hw()
5954 if (priv->ap_fw) { in mwl8k_probe_hw()
5964 wiphy_err(hw->wiphy, "Cannot initialise firmware\n"); in mwl8k_probe_hw()
5971 wiphy_err(hw->wiphy, "Cannot disable\n"); in mwl8k_probe_hw()
5978 wiphy_err(hw->wiphy, "Cannot clear MAC address\n"); in mwl8k_probe_hw()
5985 wiphy_warn(hw->wiphy, "failed to set # of RX antennas"); in mwl8k_probe_hw()
5988 wiphy_warn(hw->wiphy, "failed to set # of TX antennas"); in mwl8k_probe_hw()
5992 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_probe_hw()
5993 free_irq(priv->pdev->irq, hw); in mwl8k_probe_hw()
5995 wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n", in mwl8k_probe_hw()
5996 priv->device_info->part_name, in mwl8k_probe_hw()
5997 priv->hw_rev, hw->wiphy->perm_addr, in mwl8k_probe_hw()
5998 priv->ap_fw ? "AP" : "STA", in mwl8k_probe_hw()
5999 (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff, in mwl8k_probe_hw()
6000 (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff); in mwl8k_probe_hw()
6005 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_probe_hw()
6006 free_irq(priv->pdev->irq, hw); in mwl8k_probe_hw()
6026 struct mwl8k_priv *priv = hw->priv; in mwl8k_reload_firmware()
6033 * All the existing interfaces are re-added by the ieee80211_reconfig; in mwl8k_reload_firmware()
6037 if (priv->hw_restart_in_progress) in mwl8k_reload_firmware()
6038 list_for_each_entry_safe(vif, tmp_vif, &priv->vif_list, list) in mwl8k_reload_firmware()
6052 if (priv->hw_restart_in_progress) in mwl8k_reload_firmware()
6064 rc = mwl8k_conf_tx(hw, NULL, 0, i, &priv->wmm_params[i]); in mwl8k_reload_firmware()
6091 struct ieee80211_hw *hw = priv->hw; in mwl8k_firmware_load_success()
6097 wiphy_err(hw->wiphy, "Cannot start firmware\n"); in mwl8k_firmware_load_success()
6105 hw->extra_tx_headroom = in mwl8k_firmware_load_success()
6106 sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts); in mwl8k_firmware_load_success()
6108 hw->extra_tx_headroom -= priv->ap_fw ? REDUCED_TX_HEADROOM : 0; in mwl8k_firmware_load_success()
6110 hw->queues = MWL8K_TX_WMM_QUEUES; in mwl8k_firmware_load_success()
6120 if (priv->ap_fw) in mwl8k_firmware_load_success()
6123 hw->vif_data_size = sizeof(struct mwl8k_vif); in mwl8k_firmware_load_success()
6124 hw->sta_data_size = sizeof(struct mwl8k_sta); in mwl8k_firmware_load_success()
6126 priv->macids_used = 0; in mwl8k_firmware_load_success()
6127 INIT_LIST_HEAD(&priv->vif_list); in mwl8k_firmware_load_success()
6130 priv->radio_on = false; in mwl8k_firmware_load_success()
6131 priv->radio_short_preamble = false; in mwl8k_firmware_load_success()
6134 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); in mwl8k_firmware_load_success()
6136 INIT_WORK(&priv->watchdog_ba_handle, mwl8k_watchdog_ba_events); in mwl8k_firmware_load_success()
6138 INIT_WORK(&priv->fw_reload, mwl8k_hw_restart_work); in mwl8k_firmware_load_success()
6141 tasklet_setup(&priv->poll_tx_task, mwl8k_tx_poll); in mwl8k_firmware_load_success()
6142 tasklet_disable(&priv->poll_tx_task); in mwl8k_firmware_load_success()
6143 tasklet_setup(&priv->poll_rx_task, mwl8k_rx_poll); in mwl8k_firmware_load_success()
6144 tasklet_disable(&priv->poll_rx_task); in mwl8k_firmware_load_success()
6147 priv->cookie = dma_alloc_coherent(&priv->pdev->dev, 4, in mwl8k_firmware_load_success()
6148 &priv->cookie_dma, GFP_KERNEL); in mwl8k_firmware_load_success()
6149 if (priv->cookie == NULL) in mwl8k_firmware_load_success()
6150 return -ENOMEM; in mwl8k_firmware_load_success()
6152 mutex_init(&priv->fw_mutex); in mwl8k_firmware_load_success()
6153 priv->fw_mutex_owner = NULL; in mwl8k_firmware_load_success()
6154 priv->fw_mutex_depth = 0; in mwl8k_firmware_load_success()
6155 priv->hostcmd_wait = NULL; in mwl8k_firmware_load_success()
6157 spin_lock_init(&priv->tx_lock); in mwl8k_firmware_load_success()
6159 spin_lock_init(&priv->stream_lock); in mwl8k_firmware_load_success()
6161 priv->tx_wait = NULL; in mwl8k_firmware_load_success()
6167 hw->wiphy->interface_modes = 0; in mwl8k_firmware_load_success()
6169 if (priv->ap_macids_supported || priv->device_info->fw_image_ap) { in mwl8k_firmware_load_success()
6170 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); in mwl8k_firmware_load_success()
6171 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); in mwl8k_firmware_load_success()
6172 hw->wiphy->iface_combinations = &ap_if_comb; in mwl8k_firmware_load_success()
6173 hw->wiphy->n_iface_combinations = 1; in mwl8k_firmware_load_success()
6176 if (priv->sta_macids_supported || priv->device_info->fw_image_sta) in mwl8k_firmware_load_success()
6177 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); in mwl8k_firmware_load_success()
6179 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); in mwl8k_firmware_load_success()
6183 wiphy_err(hw->wiphy, "Cannot register device\n"); in mwl8k_firmware_load_success()
6195 if (priv->cookie != NULL) in mwl8k_firmware_load_success()
6196 dma_free_coherent(&priv->pdev->dev, 4, priv->cookie, in mwl8k_firmware_load_success()
6197 priv->cookie_dma); in mwl8k_firmware_load_success()
6235 printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME); in mwl8k_probe()
6236 rc = -ENOMEM; in mwl8k_probe()
6240 SET_IEEE80211_DEV(hw, &pdev->dev); in mwl8k_probe()
6243 priv = hw->priv; in mwl8k_probe()
6244 priv->hw = hw; in mwl8k_probe()
6245 priv->pdev = pdev; in mwl8k_probe()
6246 priv->device_info = &mwl8k_info_tbl[id->driver_data]; in mwl8k_probe()
6248 if (id->driver_data == MWL8764) in mwl8k_probe()
6249 priv->is_8764 = true; in mwl8k_probe()
6251 priv->sram = pci_iomap(pdev, 0, 0x10000); in mwl8k_probe()
6252 if (priv->sram == NULL) { in mwl8k_probe()
6253 wiphy_err(hw->wiphy, "Cannot map device SRAM\n"); in mwl8k_probe()
6254 rc = -EIO; in mwl8k_probe()
6262 priv->regs = pci_iomap(pdev, 1, 0x10000); in mwl8k_probe()
6263 if (priv->regs == NULL) { in mwl8k_probe()
6264 priv->regs = pci_iomap(pdev, 2, 0x10000); in mwl8k_probe()
6265 if (priv->regs == NULL) { in mwl8k_probe()
6266 wiphy_err(hw->wiphy, "Cannot map device registers\n"); in mwl8k_probe()
6267 rc = -EIO; in mwl8k_probe()
6277 init_completion(&priv->firmware_loading_complete); in mwl8k_probe()
6278 di = priv->device_info; in mwl8k_probe()
6279 if (ap_mode_default && di->fw_image_ap) { in mwl8k_probe()
6280 priv->fw_pref = di->fw_image_ap; in mwl8k_probe()
6281 priv->fw_alt = di->fw_image_sta; in mwl8k_probe()
6282 } else if (!ap_mode_default && di->fw_image_sta) { in mwl8k_probe()
6283 priv->fw_pref = di->fw_image_sta; in mwl8k_probe()
6284 priv->fw_alt = di->fw_image_ap; in mwl8k_probe()
6285 } else if (ap_mode_default && !di->fw_image_ap && di->fw_image_sta) { in mwl8k_probe()
6287 priv->fw_pref = di->fw_image_sta; in mwl8k_probe()
6288 } else if (!ap_mode_default && !di->fw_image_sta && di->fw_image_ap) { in mwl8k_probe()
6290 priv->fw_pref = di->fw_image_ap; in mwl8k_probe()
6292 rc = mwl8k_init_firmware(hw, priv->fw_pref, true); in mwl8k_probe()
6296 priv->hw_restart_in_progress = false; in mwl8k_probe()
6298 priv->running_bsses = 0; in mwl8k_probe()
6306 if (priv->regs != NULL) in mwl8k_probe()
6307 pci_iounmap(pdev, priv->regs); in mwl8k_probe()
6309 if (priv->sram != NULL) in mwl8k_probe()
6310 pci_iounmap(pdev, priv->sram); in mwl8k_probe()
6331 priv = hw->priv; in mwl8k_remove()
6333 wait_for_completion(&priv->firmware_loading_complete); in mwl8k_remove()
6335 if (priv->fw_state == FW_STATE_ERROR) { in mwl8k_remove()
6345 tasklet_kill(&priv->poll_tx_task); in mwl8k_remove()
6346 tasklet_kill(&priv->poll_rx_task); in mwl8k_remove()
6360 dma_free_coherent(&priv->pdev->dev, 4, priv->cookie, priv->cookie_dma); in mwl8k_remove()
6363 pci_iounmap(pdev, priv->regs); in mwl8k_remove()
6364 pci_iounmap(pdev, priv->sram); in mwl8k_remove()