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()
604 void __iomem *regs = priv->regs; in mwl8k_send_fw_load_cmd()
608 dma_addr = dma_map_single(&priv->pdev->dev, data, length, in mwl8k_send_fw_load_cmd()
610 if (dma_mapping_error(&priv->pdev->dev, dma_addr)) in mwl8k_send_fw_load_cmd()
611 return -ENOMEM; in mwl8k_send_fw_load_cmd()
623 if (priv->is_8764) { in mwl8k_send_fw_load_cmd()
637 } while (--loops); in mwl8k_send_fw_load_cmd()
639 dma_unmap_single(&priv->pdev->dev, dma_addr, length, DMA_TO_DEVICE); in mwl8k_send_fw_load_cmd()
641 return loops ? 0 : -ETIMEDOUT; in mwl8k_send_fw_load_cmd()
653 return -ENOMEM; in mwl8k_load_fw_image()
655 cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD); in mwl8k_load_fw_image()
656 cmd->seq_num = 0; in mwl8k_load_fw_image()
657 cmd->macid = 0; in mwl8k_load_fw_image()
658 cmd->result = 0; in mwl8k_load_fw_image()
664 memcpy(cmd->payload, data + done, block_size); in mwl8k_load_fw_image()
665 cmd->length = cpu_to_le16(block_size); in mwl8k_load_fw_image()
673 length -= block_size; in mwl8k_load_fw_image()
677 cmd->length = 0; in mwl8k_load_fw_image()
695 return -ENOMEM; in mwl8k_feed_fw_image()
703 block_size = ioread32(priv->regs + MWL8K_HIU_SCRATCH); in mwl8k_feed_fw_image()
706 may_continue--; in mwl8k_feed_fw_image()
709 length -= prev_block_size; in mwl8k_feed_fw_image()
713 rc = -EOVERFLOW; in mwl8k_feed_fw_image()
723 rc = -EPROTO; in mwl8k_feed_fw_image()
724 may_continue--; in mwl8k_feed_fw_image()
738 rc = -EREMOTEIO; in mwl8k_feed_fw_image()
747 struct mwl8k_priv *priv = hw->priv; in mwl8k_load_firmware()
748 const struct firmware *fw = priv->fw_ucode; in mwl8k_load_firmware()
752 if (!memcmp(fw->data, "\x01\x00\x00\x00", 4) && !priv->is_8764) { in mwl8k_load_firmware()
753 const struct firmware *helper = priv->fw_helper; in mwl8k_load_firmware()
757 "given\n", pci_name(priv->pdev)); in mwl8k_load_firmware()
758 return -EINVAL; in mwl8k_load_firmware()
761 rc = mwl8k_load_fw_image(priv, helper->data, helper->size); in mwl8k_load_firmware()
764 "helper image\n", pci_name(priv->pdev)); in mwl8k_load_firmware()
769 rc = mwl8k_feed_fw_image(priv, fw->data, fw->size); in mwl8k_load_firmware()
771 if (priv->is_8764) in mwl8k_load_firmware()
772 rc = mwl8k_feed_fw_image(priv, fw->data, fw->size); in mwl8k_load_firmware()
774 rc = mwl8k_load_fw_image(priv, fw->data, fw->size); in mwl8k_load_firmware()
779 pci_name(priv->pdev)); in mwl8k_load_firmware()
783 iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR); in mwl8k_load_firmware()
789 ready_code = ioread32(priv->regs + MWL8K_HIU_INT_CODE); in mwl8k_load_firmware()
791 priv->ap_fw = true; in mwl8k_load_firmware()
794 priv->ap_fw = false; in mwl8k_load_firmware()
800 } while (--loops); in mwl8k_load_firmware()
802 return loops ? 0 : -ETIMEDOUT; in mwl8k_load_firmware()
819 tr = (struct mwl8k_dma_data *)skb->data; in mwl8k_remove_dma_header()
820 hdrlen = ieee80211_hdrlen(tr->wh.frame_control); in mwl8k_remove_dma_header()
822 if (hdrlen != sizeof(tr->wh)) { in mwl8k_remove_dma_header()
823 if (ieee80211_is_data_qos(tr->wh.frame_control)) { in mwl8k_remove_dma_header()
824 memmove(tr->data - hdrlen, &tr->wh, hdrlen - 2); in mwl8k_remove_dma_header()
825 *((__le16 *)(tr->data - 2)) = qos; in mwl8k_remove_dma_header()
827 memmove(tr->data - hdrlen, &tr->wh, hdrlen); in mwl8k_remove_dma_header()
832 skb_pull(skb, sizeof(*tr) - hdrlen); in mwl8k_remove_dma_header()
848 * present a 2-byte payload length followed by a 4-address in mwl8k_add_dma_header()
852 wh = (struct ieee80211_hdr *)skb->data; in mwl8k_add_dma_header()
854 hdrlen = ieee80211_hdrlen(wh->frame_control); in mwl8k_add_dma_header()
860 if (priv->ap_fw && (hdrlen < (sizeof(struct ieee80211_cts) in mwl8k_add_dma_header()
864 wiphy_err(priv->hw->wiphy, in mwl8k_add_dma_header()
868 skb->truesize += REDUCED_TX_HEADROOM; in mwl8k_add_dma_header()
874 skb_push(skb, reqd_hdrlen - hdrlen); in mwl8k_add_dma_header()
876 if (ieee80211_is_data_qos(wh->frame_control)) in mwl8k_add_dma_header()
877 hdrlen -= IEEE80211_QOS_CTL_LEN; in mwl8k_add_dma_header()
879 tr = (struct mwl8k_dma_data *)skb->data; in mwl8k_add_dma_header()
880 if (wh != &tr->wh) in mwl8k_add_dma_header()
881 memmove(&tr->wh, wh, hdrlen); in mwl8k_add_dma_header()
882 if (hdrlen != sizeof(tr->wh)) in mwl8k_add_dma_header()
883 memset(((void *)&tr->wh) + hdrlen, 0, sizeof(tr->wh) - hdrlen); in mwl8k_add_dma_header()
890 tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad); in mwl8k_add_dma_header()
902 wh = (struct ieee80211_hdr *)skb->data; in mwl8k_encapsulate_tx_frame()
907 if (ieee80211_is_data(wh->frame_control)) in mwl8k_encapsulate_tx_frame()
908 key_conf = tx_info->control.hw_key; in mwl8k_encapsulate_tx_frame()
911 * Make sure the packet header is in the DMA header format (4-address in mwl8k_encapsulate_tx_frame()
915 * - WEP: 4 trailer bytes (ICV) in mwl8k_encapsulate_tx_frame()
916 * - TKIP: 12 trailer bytes (8 MIC + 4 ICV) in mwl8k_encapsulate_tx_frame()
917 * - CCMP: 8 trailer bytes (MIC) in mwl8k_encapsulate_tx_frame()
921 head_pad = key_conf->iv_len; in mwl8k_encapsulate_tx_frame()
922 switch (key_conf->cipher) { in mwl8k_encapsulate_tx_frame()
976 rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr); in mwl8k_rxd_ap_init()
977 rxd->rx_ctrl = MWL8K_AP_RX_CTRL_OWNED_BY_HOST; in mwl8k_rxd_ap_init()
984 rxd->pkt_len = cpu_to_le16(len); in mwl8k_rxd_ap_refill()
985 rxd->pkt_phys_addr = cpu_to_le32(addr); in mwl8k_rxd_ap_refill()
987 rxd->rx_ctrl = 0; in mwl8k_rxd_ap_refill()
996 if (!(rxd->rx_ctrl & MWL8K_AP_RX_CTRL_OWNED_BY_HOST)) in mwl8k_rxd_ap_process()
997 return -1; in mwl8k_rxd_ap_process()
1002 status->signal = -rxd->rssi; in mwl8k_rxd_ap_process()
1003 *noise = -rxd->noise_floor; in mwl8k_rxd_ap_process()
1005 if (rxd->rate & MWL8K_AP_RATE_INFO_MCS_FORMAT) { in mwl8k_rxd_ap_process()
1006 status->encoding = RX_ENC_HT; in mwl8k_rxd_ap_process()
1007 if (rxd->rate & MWL8K_AP_RATE_INFO_40MHZ) in mwl8k_rxd_ap_process()
1008 status->bw = RATE_INFO_BW_40; in mwl8k_rxd_ap_process()
1009 status->rate_idx = MWL8K_AP_RATE_INFO_RATEID(rxd->rate); in mwl8k_rxd_ap_process()
1014 if (mwl8k_rates_24[i].hw_value == rxd->rate) { in mwl8k_rxd_ap_process()
1015 status->rate_idx = i; in mwl8k_rxd_ap_process()
1021 if (rxd->channel > 14) { in mwl8k_rxd_ap_process()
1022 status->band = NL80211_BAND_5GHZ; in mwl8k_rxd_ap_process()
1023 if (!(status->encoding == RX_ENC_HT) && in mwl8k_rxd_ap_process()
1024 status->rate_idx >= MWL8K_LEGACY_5G_RATE_OFFSET) in mwl8k_rxd_ap_process()
1025 status->rate_idx -= MWL8K_LEGACY_5G_RATE_OFFSET; in mwl8k_rxd_ap_process()
1027 status->band = NL80211_BAND_2GHZ; in mwl8k_rxd_ap_process()
1029 status->freq = ieee80211_channel_to_frequency(rxd->channel, in mwl8k_rxd_ap_process()
1030 status->band); in mwl8k_rxd_ap_process()
1032 *qos = rxd->qos_control; in mwl8k_rxd_ap_process()
1034 if ((rxd->rx_status != MWL8K_AP_RXSTAT_GENERAL_DECRYPT_ERR) && in mwl8k_rxd_ap_process()
1035 (rxd->rx_status & MWL8K_AP_RXSTAT_DECRYPT_ERR_MASK) && in mwl8k_rxd_ap_process()
1036 (rxd->rx_status & MWL8K_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR)) in mwl8k_rxd_ap_process()
1037 status->flag |= RX_FLAG_MMIC_ERROR; in mwl8k_rxd_ap_process()
1039 return le16_to_cpu(rxd->pkt_len); in mwl8k_rxd_ap_process()
1087 rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr); in mwl8k_rxd_sta_init()
1088 rxd->rx_ctrl = MWL8K_STA_RX_CTRL_OWNED_BY_HOST; in mwl8k_rxd_sta_init()
1095 rxd->pkt_len = cpu_to_le16(len); in mwl8k_rxd_sta_refill()
1096 rxd->pkt_phys_addr = cpu_to_le32(addr); in mwl8k_rxd_sta_refill()
1098 rxd->rx_ctrl = 0; in mwl8k_rxd_sta_refill()
1108 if (!(rxd->rx_ctrl & MWL8K_STA_RX_CTRL_OWNED_BY_HOST)) in mwl8k_rxd_sta_process()
1109 return -1; in mwl8k_rxd_sta_process()
1112 rate_info = le16_to_cpu(rxd->rate_info); in mwl8k_rxd_sta_process()
1116 status->signal = -rxd->rssi; in mwl8k_rxd_sta_process()
1117 *noise = -rxd->noise_level; in mwl8k_rxd_sta_process()
1118 status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info); in mwl8k_rxd_sta_process()
1119 status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info); in mwl8k_rxd_sta_process()
1122 status->enc_flags |= RX_ENC_FLAG_SHORTPRE; in mwl8k_rxd_sta_process()
1124 status->bw = RATE_INFO_BW_40; in mwl8k_rxd_sta_process()
1126 status->enc_flags |= RX_ENC_FLAG_SHORT_GI; in mwl8k_rxd_sta_process()
1128 status->encoding = RX_ENC_HT; in mwl8k_rxd_sta_process()
1130 if (rxd->channel > 14) { in mwl8k_rxd_sta_process()
1131 status->band = NL80211_BAND_5GHZ; in mwl8k_rxd_sta_process()
1132 if (!(status->encoding == RX_ENC_HT) && in mwl8k_rxd_sta_process()
1133 status->rate_idx >= MWL8K_LEGACY_5G_RATE_OFFSET) in mwl8k_rxd_sta_process()
1134 status->rate_idx -= MWL8K_LEGACY_5G_RATE_OFFSET; in mwl8k_rxd_sta_process()
1136 status->band = NL80211_BAND_2GHZ; in mwl8k_rxd_sta_process()
1138 status->freq = ieee80211_channel_to_frequency(rxd->channel, in mwl8k_rxd_sta_process()
1139 status->band); in mwl8k_rxd_sta_process()
1141 *qos = rxd->qos_control; in mwl8k_rxd_sta_process()
1142 if ((rxd->rx_ctrl & MWL8K_STA_RX_CTRL_DECRYPT_ERROR) && in mwl8k_rxd_sta_process()
1143 (rxd->rx_ctrl & MWL8K_STA_RX_CTRL_DEC_ERR_TYPE)) in mwl8k_rxd_sta_process()
1144 status->flag |= RX_FLAG_MMIC_ERROR; in mwl8k_rxd_sta_process()
1146 return le16_to_cpu(rxd->pkt_len); in mwl8k_rxd_sta_process()
1162 struct mwl8k_priv *priv = hw->priv; in mwl8k_rxq_init()
1163 struct mwl8k_rx_queue *rxq = priv->rxq + index; in mwl8k_rxq_init()
1167 rxq->rxd_count = 0; in mwl8k_rxq_init()
1168 rxq->head = 0; in mwl8k_rxq_init()
1169 rxq->tail = 0; in mwl8k_rxq_init()
1171 size = MWL8K_RX_DESCS * priv->rxd_ops->rxd_size; in mwl8k_rxq_init()
1173 rxq->rxd = dma_alloc_coherent(&priv->pdev->dev, size, &rxq->rxd_dma, in mwl8k_rxq_init()
1175 if (rxq->rxd == NULL) { in mwl8k_rxq_init()
1176 wiphy_err(hw->wiphy, "failed to alloc RX descriptors\n"); in mwl8k_rxq_init()
1177 return -ENOMEM; in mwl8k_rxq_init()
1180 rxq->buf = kcalloc(MWL8K_RX_DESCS, sizeof(*rxq->buf), GFP_KERNEL); in mwl8k_rxq_init()
1181 if (rxq->buf == NULL) { in mwl8k_rxq_init()
1182 dma_free_coherent(&priv->pdev->dev, size, rxq->rxd, in mwl8k_rxq_init()
1183 rxq->rxd_dma); in mwl8k_rxq_init()
1184 return -ENOMEM; in mwl8k_rxq_init()
1193 desc_size = priv->rxd_ops->rxd_size; in mwl8k_rxq_init()
1194 rxd = rxq->rxd + (i * priv->rxd_ops->rxd_size); in mwl8k_rxq_init()
1199 next_dma_addr = rxq->rxd_dma + (nexti * desc_size); in mwl8k_rxq_init()
1201 priv->rxd_ops->rxd_init(rxd, next_dma_addr); in mwl8k_rxq_init()
1207 static int rxq_refill(struct ieee80211_hw *hw, int index, int limit) in rxq_refill() argument
1209 struct mwl8k_priv *priv = hw->priv; in rxq_refill()
1210 struct mwl8k_rx_queue *rxq = priv->rxq + index; in rxq_refill()
1213 while (rxq->rxd_count < MWL8K_RX_DESCS && limit--) { in rxq_refill()
1223 addr = dma_map_single(&priv->pdev->dev, skb->data, in rxq_refill()
1226 rxq->rxd_count++; in rxq_refill()
1227 rx = rxq->tail++; in rxq_refill()
1228 if (rxq->tail == MWL8K_RX_DESCS) in rxq_refill()
1229 rxq->tail = 0; in rxq_refill()
1230 rxq->buf[rx].skb = skb; in rxq_refill()
1231 dma_unmap_addr_set(&rxq->buf[rx], dma, addr); in rxq_refill()
1233 rxd = rxq->rxd + (rx * priv->rxd_ops->rxd_size); in rxq_refill()
1234 priv->rxd_ops->rxd_refill(rxd, addr, MWL8K_RX_MAXSZ); in rxq_refill()
1245 struct mwl8k_priv *priv = hw->priv; in mwl8k_rxq_deinit()
1246 struct mwl8k_rx_queue *rxq = priv->rxq + index; in mwl8k_rxq_deinit()
1249 if (rxq->rxd == NULL) in mwl8k_rxq_deinit()
1253 if (rxq->buf[i].skb != NULL) { in mwl8k_rxq_deinit()
1254 dma_unmap_single(&priv->pdev->dev, in mwl8k_rxq_deinit()
1255 dma_unmap_addr(&rxq->buf[i], dma), in mwl8k_rxq_deinit()
1257 dma_unmap_addr_set(&rxq->buf[i], dma, 0); in mwl8k_rxq_deinit()
1259 kfree_skb(rxq->buf[i].skb); in mwl8k_rxq_deinit()
1260 rxq->buf[i].skb = NULL; in mwl8k_rxq_deinit()
1264 kfree(rxq->buf); in mwl8k_rxq_deinit()
1265 rxq->buf = NULL; in mwl8k_rxq_deinit()
1267 dma_free_coherent(&priv->pdev->dev, in mwl8k_rxq_deinit()
1268 MWL8K_RX_DESCS * priv->rxd_ops->rxd_size, rxq->rxd, in mwl8k_rxq_deinit()
1269 rxq->rxd_dma); in mwl8k_rxq_deinit()
1270 rxq->rxd = NULL; in mwl8k_rxq_deinit()
1281 return priv->capture_beacon && in mwl8k_capture_bssid()
1282 ieee80211_is_beacon(wh->frame_control) && in mwl8k_capture_bssid()
1283 ether_addr_equal_64bits(wh->addr3, priv->capture_bssid); in mwl8k_capture_bssid()
1289 struct mwl8k_priv *priv = hw->priv; in mwl8k_save_beacon()
1291 priv->capture_beacon = false; in mwl8k_save_beacon()
1292 eth_zero_addr(priv->capture_bssid); in mwl8k_save_beacon()
1299 priv->beacon_skb = skb_copy(skb, GFP_ATOMIC); in mwl8k_save_beacon()
1300 if (priv->beacon_skb != NULL) in mwl8k_save_beacon()
1301 ieee80211_queue_work(hw, &priv->finalize_join_worker); in mwl8k_save_beacon()
1311 if (memcmp(bssid, mwl8k_vif->bssid, in mwl8k_find_vif_bss()
1319 static int rxq_process(struct ieee80211_hw *hw, int index, int limit) in rxq_process() argument
1321 struct mwl8k_priv *priv = hw->priv; in rxq_process()
1323 struct mwl8k_rx_queue *rxq = priv->rxq + index; in rxq_process()
1327 while (rxq->rxd_count && limit--) { in rxq_process()
1335 skb = rxq->buf[rxq->head].skb; in rxq_process()
1339 rxd = rxq->rxd + (rxq->head * priv->rxd_ops->rxd_size); in rxq_process()
1341 pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos, in rxq_process()
1342 &priv->noise); in rxq_process()
1346 rxq->buf[rxq->head].skb = NULL; in rxq_process()
1348 dma_unmap_single(&priv->pdev->dev, in rxq_process()
1349 dma_unmap_addr(&rxq->buf[rxq->head], dma), in rxq_process()
1351 dma_unmap_addr_set(&rxq->buf[rxq->head], dma, 0); in rxq_process()
1353 rxq->head++; in rxq_process()
1354 if (rxq->head == MWL8K_RX_DESCS) in rxq_process()
1355 rxq->head = 0; in rxq_process()
1357 rxq->rxd_count--; in rxq_process()
1359 wh = &((struct mwl8k_dma_data *)skb->data)->wh; in rxq_process()
1366 if (mwl8k_capture_bssid(priv, (void *)skb->data)) in rxq_process()
1369 if (ieee80211_has_protected(wh->frame_control)) { in rxq_process()
1375 mwl8k_vif = mwl8k_find_vif_bss(&priv->vif_list, in rxq_process()
1376 wh->addr1); in rxq_process()
1379 mwl8k_vif->is_hw_crypto_enabled) { in rxq_process()
1395 tr = (struct mwl8k_dma_data *)skb->data; in rxq_process()
1396 memset((void *)&(tr->data), 0, 4); in rxq_process()
1400 if (!ieee80211_is_auth(wh->frame_control)) in rxq_process()
1454 struct mwl8k_priv *priv = hw->priv; in mwl8k_txq_init()
1455 struct mwl8k_tx_queue *txq = priv->txq + index; in mwl8k_txq_init()
1459 txq->len = 0; in mwl8k_txq_init()
1460 txq->head = 0; in mwl8k_txq_init()
1461 txq->tail = 0; in mwl8k_txq_init()
1465 txq->txd = dma_alloc_coherent(&priv->pdev->dev, size, &txq->txd_dma, in mwl8k_txq_init()
1467 if (txq->txd == NULL) { in mwl8k_txq_init()
1468 wiphy_err(hw->wiphy, "failed to alloc TX descriptors\n"); in mwl8k_txq_init()
1469 return -ENOMEM; in mwl8k_txq_init()
1472 txq->skb = kcalloc(MWL8K_TX_DESCS, sizeof(*txq->skb), GFP_KERNEL); in mwl8k_txq_init()
1473 if (txq->skb == NULL) { in mwl8k_txq_init()
1474 dma_free_coherent(&priv->pdev->dev, size, txq->txd, in mwl8k_txq_init()
1475 txq->txd_dma); in mwl8k_txq_init()
1476 txq->txd = NULL; in mwl8k_txq_init()
1477 return -ENOMEM; in mwl8k_txq_init()
1484 tx_desc = txq->txd + i; in mwl8k_txq_init()
1487 tx_desc->status = 0; in mwl8k_txq_init()
1488 tx_desc->next_txd_phys_addr = in mwl8k_txq_init()
1489 cpu_to_le32(txq->txd_dma + nexti * sizeof(*tx_desc)); in mwl8k_txq_init()
1498 priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS); in mwl8k_tx_start()
1500 priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS); in mwl8k_tx_start()
1501 ioread32(priv->regs + MWL8K_HIU_INT_CODE); in mwl8k_tx_start()
1506 struct mwl8k_priv *priv = hw->priv; in mwl8k_dump_tx_rings()
1510 struct mwl8k_tx_queue *txq = priv->txq + i; in mwl8k_dump_tx_rings()
1517 struct mwl8k_tx_desc *tx_desc = txq->txd + desc; in mwl8k_dump_tx_rings()
1520 status = le32_to_cpu(tx_desc->status); in mwl8k_dump_tx_rings()
1526 if (tx_desc->pkt_len == 0) in mwl8k_dump_tx_rings()
1530 wiphy_err(hw->wiphy, in mwl8k_dump_tx_rings()
1534 txq->len, txq->head, txq->tail, in mwl8k_dump_tx_rings()
1540 * Must be called with priv->fw_mutex held and tx queues stopped.
1546 struct mwl8k_priv *priv = hw->priv; in mwl8k_tx_wait_empty()
1558 if (priv->hw_restart_in_progress) { in mwl8k_tx_wait_empty()
1559 if (priv->hw_restart_owner == current) in mwl8k_tx_wait_empty()
1562 return -EBUSY; in mwl8k_tx_wait_empty()
1565 if (atomic_read(&priv->watchdog_event_pending)) in mwl8k_tx_wait_empty()
1570 * doesn't need to take ->tx_lock. in mwl8k_tx_wait_empty()
1572 if (!priv->pending_tx_pkts) in mwl8k_tx_wait_empty()
1578 spin_lock_bh(&priv->tx_lock); in mwl8k_tx_wait_empty()
1579 priv->tx_wait = &tx_wait; in mwl8k_tx_wait_empty()
1584 oldcount = priv->pending_tx_pkts; in mwl8k_tx_wait_empty()
1586 spin_unlock_bh(&priv->tx_lock); in mwl8k_tx_wait_empty()
1590 if (atomic_read(&priv->watchdog_event_pending)) { in mwl8k_tx_wait_empty()
1591 spin_lock_bh(&priv->tx_lock); in mwl8k_tx_wait_empty()
1592 priv->tx_wait = NULL; in mwl8k_tx_wait_empty()
1593 spin_unlock_bh(&priv->tx_lock); in mwl8k_tx_wait_empty()
1597 spin_lock_bh(&priv->tx_lock); in mwl8k_tx_wait_empty()
1599 if (timeout || !priv->pending_tx_pkts) { in mwl8k_tx_wait_empty()
1600 WARN_ON(priv->pending_tx_pkts); in mwl8k_tx_wait_empty()
1602 wiphy_notice(hw->wiphy, "tx rings drained\n"); in mwl8k_tx_wait_empty()
1612 if (priv->pending_tx_pkts < oldcount) { in mwl8k_tx_wait_empty()
1613 wiphy_notice(hw->wiphy, in mwl8k_tx_wait_empty()
1614 "waiting for tx rings to drain (%d -> %d pkts)\n", in mwl8k_tx_wait_empty()
1615 oldcount, priv->pending_tx_pkts); in mwl8k_tx_wait_empty()
1620 priv->tx_wait = NULL; in mwl8k_tx_wait_empty()
1622 wiphy_err(hw->wiphy, "tx rings stuck for %d ms\n", in mwl8k_tx_wait_empty()
1625 priv->hw_restart_in_progress = true; in mwl8k_tx_wait_empty()
1626 ieee80211_queue_work(hw, &priv->fw_reload); in mwl8k_tx_wait_empty()
1628 rc = -ETIMEDOUT; in mwl8k_tx_wait_empty()
1630 priv->tx_wait = NULL; in mwl8k_tx_wait_empty()
1631 spin_unlock_bh(&priv->tx_lock); in mwl8k_tx_wait_empty()
1659 return -1; in mwl8k_tid_queue_mapping()
1672 mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) in mwl8k_txq_reclaim() argument
1674 struct mwl8k_priv *priv = hw->priv; in mwl8k_txq_reclaim()
1675 struct mwl8k_tx_queue *txq = priv->txq + index; in mwl8k_txq_reclaim()
1679 while (txq->len > 0 && limit--) { in mwl8k_txq_reclaim()
1692 tx = txq->head; in mwl8k_txq_reclaim()
1693 tx_desc = txq->txd + tx; in mwl8k_txq_reclaim()
1695 status = le32_to_cpu(tx_desc->status); in mwl8k_txq_reclaim()
1700 tx_desc->status &= in mwl8k_txq_reclaim()
1704 txq->head = (tx + 1) % MWL8K_TX_DESCS; in mwl8k_txq_reclaim()
1705 BUG_ON(txq->len == 0); in mwl8k_txq_reclaim()
1706 txq->len--; in mwl8k_txq_reclaim()
1707 priv->pending_tx_pkts--; in mwl8k_txq_reclaim()
1709 addr = le32_to_cpu(tx_desc->pkt_phys_addr); in mwl8k_txq_reclaim()
1710 size = le16_to_cpu(tx_desc->pkt_len); in mwl8k_txq_reclaim()
1711 skb = txq->skb[tx]; in mwl8k_txq_reclaim()
1712 txq->skb[tx] = NULL; in mwl8k_txq_reclaim()
1715 dma_unmap_single(&priv->pdev->dev, addr, size, DMA_TO_DEVICE); in mwl8k_txq_reclaim()
1717 mwl8k_remove_dma_header(skb, tx_desc->qos_control); in mwl8k_txq_reclaim()
1719 wh = (struct ieee80211_hdr *) skb->data; in mwl8k_txq_reclaim()
1722 tx_desc->pkt_phys_addr = 0; in mwl8k_txq_reclaim()
1723 tx_desc->pkt_len = 0; in mwl8k_txq_reclaim()
1726 if (ieee80211_is_data(wh->frame_control)) { in mwl8k_txq_reclaim()
1728 sta = ieee80211_find_sta_by_ifaddr(hw, wh->addr1, in mwl8k_txq_reclaim()
1729 wh->addr2); in mwl8k_txq_reclaim()
1733 rate_info = le16_to_cpu(tx_desc->rate_info); in mwl8k_txq_reclaim()
1741 sta_info->is_ampdu_allowed = false; in mwl8k_txq_reclaim()
1743 sta_info->is_ampdu_allowed = true; in mwl8k_txq_reclaim()
1754 info->status.rates[0].idx = -1; in mwl8k_txq_reclaim()
1755 info->status.rates[0].count = 1; in mwl8k_txq_reclaim()
1758 info->flags |= IEEE80211_TX_STAT_ACK; in mwl8k_txq_reclaim()
1771 struct mwl8k_priv *priv = hw->priv; in mwl8k_txq_deinit()
1772 struct mwl8k_tx_queue *txq = priv->txq + index; in mwl8k_txq_deinit()
1774 if (txq->txd == NULL) in mwl8k_txq_deinit()
1779 kfree(txq->skb); in mwl8k_txq_deinit()
1780 txq->skb = NULL; in mwl8k_txq_deinit()
1782 dma_free_coherent(&priv->pdev->dev, in mwl8k_txq_deinit()
1784 txq->txd, txq->txd_dma); in mwl8k_txq_deinit()
1785 txq->txd = NULL; in mwl8k_txq_deinit()
1788 /* caller must hold priv->stream_lock when calling the stream functions */
1793 struct mwl8k_priv *priv = hw->priv; in mwl8k_add_stream()
1797 stream = &priv->ampdu[i]; in mwl8k_add_stream()
1798 if (stream->state == AMPDU_NO_STREAM) { in mwl8k_add_stream()
1799 stream->sta = sta; in mwl8k_add_stream()
1800 stream->state = AMPDU_STREAM_NEW; in mwl8k_add_stream()
1801 stream->tid = tid; in mwl8k_add_stream()
1802 stream->idx = i; in mwl8k_add_stream()
1803 wiphy_debug(hw->wiphy, "Added a new stream for %pM %d", in mwl8k_add_stream()
1804 sta->addr, tid); in mwl8k_add_stream()
1817 if (stream->state != AMPDU_STREAM_NEW) in mwl8k_start_stream()
1819 ret = ieee80211_start_tx_ba_session(stream->sta, stream->tid, 0); in mwl8k_start_stream()
1821 wiphy_debug(hw->wiphy, "Failed to start stream for %pM %d: " in mwl8k_start_stream()
1822 "%d\n", stream->sta->addr, stream->tid, ret); in mwl8k_start_stream()
1824 wiphy_debug(hw->wiphy, "Started stream for %pM %d\n", in mwl8k_start_stream()
1825 stream->sta->addr, stream->tid); in mwl8k_start_stream()
1832 wiphy_debug(hw->wiphy, "Remove stream for %pM %d\n", stream->sta->addr, in mwl8k_remove_stream()
1833 stream->tid); in mwl8k_remove_stream()
1840 struct mwl8k_priv *priv = hw->priv; in mwl8k_lookup_stream()
1845 stream = &priv->ampdu[i]; in mwl8k_lookup_stream()
1846 if (stream->state == AMPDU_NO_STREAM) in mwl8k_lookup_stream()
1848 if (!memcmp(stream->sta->addr, addr, ETH_ALEN) && in mwl8k_lookup_stream()
1849 stream->tid == tid) in mwl8k_lookup_stream()
1862 tx_stats = &sta_info->tx_stats[tid]; in mwl8k_ampdu_allowed()
1864 return sta_info->is_ampdu_allowed && in mwl8k_ampdu_allowed()
1865 tx_stats->pkts > MWL8K_AMPDU_PACKET_THRESHOLD; in mwl8k_ampdu_allowed()
1874 tx_stats = &sta_info->tx_stats[tid]; in mwl8k_tx_count_packet()
1876 if (tx_stats->start_time == 0) in mwl8k_tx_count_packet()
1877 tx_stats->start_time = jiffies; in mwl8k_tx_count_packet()
1883 if (time_after(jiffies, (unsigned long)tx_stats->start_time + HZ)) { in mwl8k_tx_count_packet()
1884 tx_stats->pkts = 0; in mwl8k_tx_count_packet()
1885 tx_stats->start_time = 0; in mwl8k_tx_count_packet()
1887 tx_stats->pkts++; in mwl8k_tx_count_packet()
1903 struct mwl8k_priv *priv = hw->priv; in mwl8k_txq_xmit()
1918 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; in mwl8k_txq_xmit()
1921 wh = (struct ieee80211_hdr *)skb->data; in mwl8k_txq_xmit()
1922 if (ieee80211_is_data_qos(wh->frame_control)) in mwl8k_txq_xmit()
1927 if (skb->protocol == cpu_to_be16(ETH_P_PAE)) in mwl8k_txq_xmit()
1930 if (ieee80211_is_mgmt(wh->frame_control)) in mwl8k_txq_xmit()
1933 if (priv->ap_fw) in mwl8k_txq_xmit()
1938 wh = &((struct mwl8k_dma_data *)skb->data)->wh; in mwl8k_txq_xmit()
1941 mwl8k_vif = MWL8K_VIF(tx_info->control.vif); in mwl8k_txq_xmit()
1943 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { in mwl8k_txq_xmit()
1944 wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); in mwl8k_txq_xmit()
1945 wh->seq_ctrl |= cpu_to_le16(mwl8k_vif->seqno); in mwl8k_txq_xmit()
1946 mwl8k_vif->seqno += 0x10; in mwl8k_txq_xmit()
1952 if (ieee80211_is_mgmt(wh->frame_control) || in mwl8k_txq_xmit()
1953 ieee80211_is_ctl(wh->frame_control)) { in mwl8k_txq_xmit()
1956 } else if (ieee80211_is_data(wh->frame_control)) { in mwl8k_txq_xmit()
1958 if (is_multicast_ether_addr(wh->addr1)) in mwl8k_txq_xmit()
1962 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) in mwl8k_txq_xmit()
1977 if (unlikely(ieee80211_is_action(wh->frame_control) && in mwl8k_txq_xmit()
1978 mgmt->u.action.category == WLAN_CATEGORY_BACK && in mwl8k_txq_xmit()
1979 mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ && in mwl8k_txq_xmit()
1980 priv->ap_fw)) { in mwl8k_txq_xmit()
1981 u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab); in mwl8k_txq_xmit()
1988 if (priv->ap_fw && sta && sta->deflink.ht_cap.ht_supported && !eapol_frame && in mwl8k_txq_xmit()
1989 ieee80211_is_data_qos(wh->frame_control)) { in mwl8k_txq_xmit()
1992 spin_lock(&priv->stream_lock); in mwl8k_txq_xmit()
1993 stream = mwl8k_lookup_stream(hw, sta->addr, tid); in mwl8k_txq_xmit()
1995 if (stream->state == AMPDU_STREAM_ACTIVE) { in mwl8k_txq_xmit()
1997 txpriority = (BA_QUEUE + stream->idx) % in mwl8k_txq_xmit()
1999 if (stream->idx <= 1) in mwl8k_txq_xmit()
2000 index = stream->idx + in mwl8k_txq_xmit()
2003 } else if (stream->state == AMPDU_STREAM_NEW) { in mwl8k_txq_xmit()
2024 wiphy_warn(hw->wiphy, in mwl8k_txq_xmit()
2027 spin_unlock(&priv->stream_lock); in mwl8k_txq_xmit()
2043 spin_unlock(&priv->stream_lock); in mwl8k_txq_xmit()
2049 dma = dma_map_single(&priv->pdev->dev, skb->data, skb->len, in mwl8k_txq_xmit()
2052 if (dma_mapping_error(&priv->pdev->dev, dma)) { in mwl8k_txq_xmit()
2053 wiphy_debug(hw->wiphy, in mwl8k_txq_xmit()
2056 spin_lock(&priv->stream_lock); in mwl8k_txq_xmit()
2058 spin_unlock(&priv->stream_lock); in mwl8k_txq_xmit()
2064 spin_lock_bh(&priv->tx_lock); in mwl8k_txq_xmit()
2066 txq = priv->txq + index; in mwl8k_txq_xmit()
2076 if (txq->len >= MWL8K_TX_DESCS - 2) { in mwl8k_txq_xmit()
2077 if (!mgmtframe || txq->len == MWL8K_TX_DESCS) { in mwl8k_txq_xmit()
2079 spin_lock(&priv->stream_lock); in mwl8k_txq_xmit()
2081 spin_unlock(&priv->stream_lock); in mwl8k_txq_xmit()
2084 spin_unlock_bh(&priv->tx_lock); in mwl8k_txq_xmit()
2085 dma_unmap_single(&priv->pdev->dev, dma, skb->len, in mwl8k_txq_xmit()
2092 BUG_ON(txq->skb[txq->tail] != NULL); in mwl8k_txq_xmit()
2093 txq->skb[txq->tail] = skb; in mwl8k_txq_xmit()
2095 tx = txq->txd + txq->tail; in mwl8k_txq_xmit()
2096 tx->data_rate = txdatarate; in mwl8k_txq_xmit()
2097 tx->tx_priority = txpriority; in mwl8k_txq_xmit()
2098 tx->qos_control = cpu_to_le16(qos); in mwl8k_txq_xmit()
2099 tx->pkt_phys_addr = cpu_to_le32(dma); in mwl8k_txq_xmit()
2100 tx->pkt_len = cpu_to_le16(skb->len); in mwl8k_txq_xmit()
2101 tx->rate_info = 0; in mwl8k_txq_xmit()
2102 if (!priv->ap_fw && sta != NULL) in mwl8k_txq_xmit()
2103 tx->peer_id = MWL8K_STA(sta)->peer_id; in mwl8k_txq_xmit()
2105 tx->peer_id = 0; in mwl8k_txq_xmit()
2107 if (priv->ap_fw && ieee80211_is_data(wh->frame_control) && !eapol_frame) in mwl8k_txq_xmit()
2108 tx->timestamp = cpu_to_le32(ioread32(priv->regs + in mwl8k_txq_xmit()
2111 tx->timestamp = 0; in mwl8k_txq_xmit()
2114 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); in mwl8k_txq_xmit()
2116 txq->len++; in mwl8k_txq_xmit()
2117 priv->pending_tx_pkts++; in mwl8k_txq_xmit()
2119 txq->tail++; in mwl8k_txq_xmit()
2120 if (txq->tail == MWL8K_TX_DESCS) in mwl8k_txq_xmit()
2121 txq->tail = 0; in mwl8k_txq_xmit()
2125 spin_unlock_bh(&priv->tx_lock); in mwl8k_txq_xmit()
2129 spin_lock(&priv->stream_lock); in mwl8k_txq_xmit()
2132 spin_unlock(&priv->stream_lock); in mwl8k_txq_xmit()
2141 * - Some commands require that the packet transmit path is idle when
2144 * - There are certain sequences of commands that need to be issued to
2148 * can be taken recursively, and which is taken by both the low-level
2155 struct mwl8k_priv *priv = hw->priv; in mwl8k_fw_lock()
2157 if (priv->fw_mutex_owner != current) { in mwl8k_fw_lock()
2160 mutex_lock(&priv->fw_mutex); in mwl8k_fw_lock()
2165 if (!priv->hw_restart_in_progress) in mwl8k_fw_lock()
2168 mutex_unlock(&priv->fw_mutex); in mwl8k_fw_lock()
2173 priv->fw_mutex_owner = current; in mwl8k_fw_lock()
2176 priv->fw_mutex_depth++; in mwl8k_fw_lock()
2183 struct mwl8k_priv *priv = hw->priv; in mwl8k_fw_unlock()
2185 if (!--priv->fw_mutex_depth) { in mwl8k_fw_unlock()
2186 if (!priv->hw_restart_in_progress) in mwl8k_fw_unlock()
2189 priv->fw_mutex_owner = NULL; in mwl8k_fw_unlock()
2190 mutex_unlock(&priv->fw_mutex); in mwl8k_fw_unlock()
2207 struct mwl8k_priv *priv = hw->priv; in mwl8k_post_cmd()
2208 void __iomem *regs = priv->regs; in mwl8k_post_cmd()
2216 wiphy_dbg(hw->wiphy, "Posting %s [%d]\n", in mwl8k_post_cmd()
2217 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), cmd->macid); in mwl8k_post_cmd()
2228 if (priv->ap_fw && priv->running_bsses) { in mwl8k_post_cmd()
2229 switch (le16_to_cpu(cmd->code)) { in mwl8k_post_cmd()
2237 bitmap = priv->running_bsses; in mwl8k_post_cmd()
2243 cmd->result = (__force __le16) 0xffff; in mwl8k_post_cmd()
2244 dma_size = le16_to_cpu(cmd->length); in mwl8k_post_cmd()
2245 dma_addr = dma_map_single(&priv->pdev->dev, cmd, dma_size, in mwl8k_post_cmd()
2247 if (dma_mapping_error(&priv->pdev->dev, dma_addr)) { in mwl8k_post_cmd()
2248 rc = -ENOMEM; in mwl8k_post_cmd()
2252 priv->hostcmd_wait = &cmd_wait; in mwl8k_post_cmd()
2262 priv->hostcmd_wait = NULL; in mwl8k_post_cmd()
2265 dma_unmap_single(&priv->pdev->dev, dma_addr, dma_size, in mwl8k_post_cmd()
2269 wiphy_err(hw->wiphy, "Command %s timeout after %u ms\n", in mwl8k_post_cmd()
2270 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), in mwl8k_post_cmd()
2272 rc = -ETIMEDOUT; in mwl8k_post_cmd()
2276 ms = MWL8K_CMD_TIMEOUT_MS - jiffies_to_msecs(timeout); in mwl8k_post_cmd()
2278 rc = cmd->result ? -EINVAL : 0; in mwl8k_post_cmd()
2280 wiphy_err(hw->wiphy, "Command %s error 0x%x\n", in mwl8k_post_cmd()
2281 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), in mwl8k_post_cmd()
2282 le16_to_cpu(cmd->result)); in mwl8k_post_cmd()
2284 wiphy_notice(hw->wiphy, "Command %s took %d ms\n", in mwl8k_post_cmd()
2285 mwl8k_cmd_name(cmd->code, in mwl8k_post_cmd()
2304 cmd->macid = MWL8K_VIF(vif)->macid; in mwl8k_post_pervif_cmd()
2313 struct mwl8k_priv *priv = hw->priv; in mwl8k_setup_2ghz_band()
2315 BUILD_BUG_ON(sizeof(priv->channels_24) != sizeof(mwl8k_channels_24)); in mwl8k_setup_2ghz_band()
2316 memcpy(priv->channels_24, mwl8k_channels_24, sizeof(mwl8k_channels_24)); in mwl8k_setup_2ghz_band()
2318 BUILD_BUG_ON(sizeof(priv->rates_24) != sizeof(mwl8k_rates_24)); in mwl8k_setup_2ghz_band()
2319 memcpy(priv->rates_24, mwl8k_rates_24, sizeof(mwl8k_rates_24)); in mwl8k_setup_2ghz_band()
2321 priv->band_24.band = NL80211_BAND_2GHZ; in mwl8k_setup_2ghz_band()
2322 priv->band_24.channels = priv->channels_24; in mwl8k_setup_2ghz_band()
2323 priv->band_24.n_channels = ARRAY_SIZE(mwl8k_channels_24); in mwl8k_setup_2ghz_band()
2324 priv->band_24.bitrates = priv->rates_24; in mwl8k_setup_2ghz_band()
2325 priv->band_24.n_bitrates = ARRAY_SIZE(mwl8k_rates_24); in mwl8k_setup_2ghz_band()
2327 hw->wiphy->bands[NL80211_BAND_2GHZ] = &priv->band_24; in mwl8k_setup_2ghz_band()
2332 struct mwl8k_priv *priv = hw->priv; in mwl8k_setup_5ghz_band()
2334 BUILD_BUG_ON(sizeof(priv->channels_50) != sizeof(mwl8k_channels_50)); in mwl8k_setup_5ghz_band()
2335 memcpy(priv->channels_50, mwl8k_channels_50, sizeof(mwl8k_channels_50)); in mwl8k_setup_5ghz_band()
2337 BUILD_BUG_ON(sizeof(priv->rates_50) != sizeof(mwl8k_rates_50)); in mwl8k_setup_5ghz_band()
2338 memcpy(priv->rates_50, mwl8k_rates_50, sizeof(mwl8k_rates_50)); in mwl8k_setup_5ghz_band()
2340 priv->band_50.band = NL80211_BAND_5GHZ; in mwl8k_setup_5ghz_band()
2341 priv->band_50.channels = priv->channels_50; in mwl8k_setup_5ghz_band()
2342 priv->band_50.n_channels = ARRAY_SIZE(mwl8k_channels_50); in mwl8k_setup_5ghz_band()
2343 priv->band_50.bitrates = priv->rates_50; in mwl8k_setup_5ghz_band()
2344 priv->band_50.n_bitrates = ARRAY_SIZE(mwl8k_rates_50); in mwl8k_setup_5ghz_band()
2346 hw->wiphy->bands[NL80211_BAND_5GHZ] = &priv->band_50; in mwl8k_setup_5ghz_band()
2394 band->ht_cap.ht_supported = 1; in mwl8k_set_ht_caps()
2397 band->ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU; in mwl8k_set_ht_caps()
2399 band->ht_cap.cap |= IEEE80211_HT_CAP_GRN_FLD; in mwl8k_set_ht_caps()
2402 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; in mwl8k_set_ht_caps()
2403 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; in mwl8k_set_ht_caps()
2406 band->ht_cap.cap |= IEEE80211_HT_CAP_RX_STBC; in mwl8k_set_ht_caps()
2408 band->ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC; in mwl8k_set_ht_caps()
2410 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; in mwl8k_set_ht_caps()
2412 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; in mwl8k_set_ht_caps()
2414 band->ht_cap.cap |= IEEE80211_HT_CAP_DELAY_BA; in mwl8k_set_ht_caps()
2416 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; in mwl8k_set_ht_caps()
2421 band->ht_cap.mcs.rx_mask[0] = 0xff; in mwl8k_set_ht_caps()
2423 band->ht_cap.mcs.rx_mask[1] = 0xff; in mwl8k_set_ht_caps()
2425 band->ht_cap.mcs.rx_mask[2] = 0xff; in mwl8k_set_ht_caps()
2426 band->ht_cap.mcs.rx_mask[4] = 0x01; in mwl8k_set_ht_caps()
2427 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; in mwl8k_set_ht_caps()
2430 band->ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; in mwl8k_set_ht_caps()
2431 band->ht_cap.mcs.tx_params |= (tx_streams - 1) << in mwl8k_set_ht_caps()
2439 struct mwl8k_priv *priv = hw->priv; in mwl8k_set_caps()
2441 if (priv->caps) in mwl8k_set_caps()
2447 mwl8k_set_ht_caps(hw, &priv->band_24, caps); in mwl8k_set_caps()
2453 mwl8k_set_ht_caps(hw, &priv->band_50, caps); in mwl8k_set_caps()
2456 priv->caps = caps; in mwl8k_set_caps()
2461 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_get_hw_spec_sta()
2468 return -ENOMEM; in mwl8k_cmd_get_hw_spec_sta()
2470 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_HW_SPEC); in mwl8k_cmd_get_hw_spec_sta()
2471 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_get_hw_spec_sta()
2473 memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr)); in mwl8k_cmd_get_hw_spec_sta()
2474 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); in mwl8k_cmd_get_hw_spec_sta()
2475 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma); in mwl8k_cmd_get_hw_spec_sta()
2476 cmd->num_tx_queues = cpu_to_le32(mwl8k_tx_queues(priv)); in mwl8k_cmd_get_hw_spec_sta()
2478 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma); in mwl8k_cmd_get_hw_spec_sta()
2479 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); in mwl8k_cmd_get_hw_spec_sta()
2480 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS); in mwl8k_cmd_get_hw_spec_sta()
2482 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_get_hw_spec_sta()
2485 SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr); in mwl8k_cmd_get_hw_spec_sta()
2486 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); in mwl8k_cmd_get_hw_spec_sta()
2487 priv->fw_rev = le32_to_cpu(cmd->fw_rev); in mwl8k_cmd_get_hw_spec_sta()
2488 priv->hw_rev = cmd->hw_rev; in mwl8k_cmd_get_hw_spec_sta()
2489 mwl8k_set_caps(hw, le32_to_cpu(cmd->caps)); in mwl8k_cmd_get_hw_spec_sta()
2490 priv->ap_macids_supported = 0x00000000; in mwl8k_cmd_get_hw_spec_sta()
2491 priv->sta_macids_supported = 0x00000001; in mwl8k_cmd_get_hw_spec_sta()
2526 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_get_hw_spec_ap()
2533 return -ENOMEM; in mwl8k_cmd_get_hw_spec_ap()
2535 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_HW_SPEC); in mwl8k_cmd_get_hw_spec_ap()
2536 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_get_hw_spec_ap()
2538 memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr)); in mwl8k_cmd_get_hw_spec_ap()
2539 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); in mwl8k_cmd_get_hw_spec_ap()
2541 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_get_hw_spec_ap()
2546 api_version = le32_to_cpu(cmd->fw_api_version); in mwl8k_cmd_get_hw_spec_ap()
2547 if (priv->device_info->fw_api_ap != api_version) { in mwl8k_cmd_get_hw_spec_ap()
2550 priv->device_info->part_name, in mwl8k_cmd_get_hw_spec_ap()
2551 priv->device_info->fw_api_ap, in mwl8k_cmd_get_hw_spec_ap()
2553 rc = -EINVAL; in mwl8k_cmd_get_hw_spec_ap()
2556 SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr); in mwl8k_cmd_get_hw_spec_ap()
2557 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); in mwl8k_cmd_get_hw_spec_ap()
2558 priv->fw_rev = le32_to_cpu(cmd->fw_rev); in mwl8k_cmd_get_hw_spec_ap()
2559 priv->hw_rev = cmd->hw_rev; in mwl8k_cmd_get_hw_spec_ap()
2560 mwl8k_set_caps(hw, le32_to_cpu(cmd->caps)); in mwl8k_cmd_get_hw_spec_ap()
2561 priv->ap_macids_supported = 0x000000ff; in mwl8k_cmd_get_hw_spec_ap()
2562 priv->sta_macids_supported = 0x00000100; in mwl8k_cmd_get_hw_spec_ap()
2563 priv->num_ampdu_queues = le32_to_cpu(cmd->num_of_ampdu_queues); in mwl8k_cmd_get_hw_spec_ap()
2564 if (priv->num_ampdu_queues > MWL8K_MAX_AMPDU_QUEUES) { in mwl8k_cmd_get_hw_spec_ap()
2565 wiphy_warn(hw->wiphy, "fw reported %d ampdu queues" in mwl8k_cmd_get_hw_spec_ap()
2567 priv->num_ampdu_queues, in mwl8k_cmd_get_hw_spec_ap()
2569 priv->num_ampdu_queues = MWL8K_MAX_AMPDU_QUEUES; in mwl8k_cmd_get_hw_spec_ap()
2571 off = le32_to_cpu(cmd->rxwrptr) & 0xffff; in mwl8k_cmd_get_hw_spec_ap()
2572 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); in mwl8k_cmd_get_hw_spec_ap()
2574 off = le32_to_cpu(cmd->rxrdptr) & 0xffff; in mwl8k_cmd_get_hw_spec_ap()
2575 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); in mwl8k_cmd_get_hw_spec_ap()
2577 priv->txq_offset[0] = le32_to_cpu(cmd->wcbbase0) & 0xffff; in mwl8k_cmd_get_hw_spec_ap()
2578 priv->txq_offset[1] = le32_to_cpu(cmd->wcbbase1) & 0xffff; in mwl8k_cmd_get_hw_spec_ap()
2579 priv->txq_offset[2] = le32_to_cpu(cmd->wcbbase2) & 0xffff; in mwl8k_cmd_get_hw_spec_ap()
2580 priv->txq_offset[3] = le32_to_cpu(cmd->wcbbase3) & 0xffff; in mwl8k_cmd_get_hw_spec_ap()
2582 for (i = 0; i < priv->num_ampdu_queues; i++) in mwl8k_cmd_get_hw_spec_ap()
2583 priv->txq_offset[i + MWL8K_TX_WMM_QUEUES] = in mwl8k_cmd_get_hw_spec_ap()
2584 le32_to_cpu(cmd->wcbbase_ampdu[i]) & 0xffff; in mwl8k_cmd_get_hw_spec_ap()
2616 * hardware. This helps minimizing the issues caused due to head-of-line
2628 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_set_hw_spec()
2635 return -ENOMEM; in mwl8k_cmd_set_hw_spec()
2637 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_HW_SPEC); in mwl8k_cmd_set_hw_spec()
2638 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_hw_spec()
2640 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); in mwl8k_cmd_set_hw_spec()
2641 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma); in mwl8k_cmd_set_hw_spec()
2642 cmd->num_tx_queues = cpu_to_le32(mwl8k_tx_queues(priv)); in mwl8k_cmd_set_hw_spec()
2651 int j = mwl8k_tx_queues(priv) - 1 - i; in mwl8k_cmd_set_hw_spec()
2652 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[j].txd_dma); in mwl8k_cmd_set_hw_spec()
2655 cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT | in mwl8k_cmd_set_hw_spec()
2660 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); in mwl8k_cmd_set_hw_spec()
2661 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS); in mwl8k_cmd_set_hw_spec()
2663 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_hw_spec()
2688 struct mwl8k_priv *priv = hw->priv; in __mwl8k_cmd_mac_multicast_adr()
2696 if (allmulti || mc_count > priv->num_mcaddrs) { in __mwl8k_cmd_mac_multicast_adr()
2707 cmd->header.code = cpu_to_le16(MWL8K_CMD_MAC_MULTICAST_ADR); in __mwl8k_cmd_mac_multicast_adr()
2708 cmd->header.length = cpu_to_le16(size); in __mwl8k_cmd_mac_multicast_adr()
2709 cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_DIRECTED | in __mwl8k_cmd_mac_multicast_adr()
2713 cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_ALL_MULTICAST); in __mwl8k_cmd_mac_multicast_adr()
2718 cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST); in __mwl8k_cmd_mac_multicast_adr()
2719 cmd->numaddr = cpu_to_le16(mc_count); in __mwl8k_cmd_mac_multicast_adr()
2721 memcpy(cmd->addr[i], ha->addr, ETH_ALEN); in __mwl8k_cmd_mac_multicast_adr()
2725 return &cmd->header; in __mwl8k_cmd_mac_multicast_adr()
2749 return -ENOMEM; in mwl8k_cmd_get_stat()
2751 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_STAT); in mwl8k_cmd_get_stat()
2752 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_get_stat()
2754 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_get_stat()
2756 stats->dot11ACKFailureCount = in mwl8k_cmd_get_stat()
2757 le32_to_cpu(cmd->stats[MWL8K_STAT_ACK_FAILURE]); in mwl8k_cmd_get_stat()
2758 stats->dot11RTSFailureCount = in mwl8k_cmd_get_stat()
2759 le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_FAILURE]); in mwl8k_cmd_get_stat()
2760 stats->dot11FCSErrorCount = in mwl8k_cmd_get_stat()
2761 le32_to_cpu(cmd->stats[MWL8K_STAT_FCS_ERROR]); in mwl8k_cmd_get_stat()
2762 stats->dot11RTSSuccessCount = in mwl8k_cmd_get_stat()
2763 le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_SUCCESS]); in mwl8k_cmd_get_stat()
2783 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_radio_control()
2787 if (enable == priv->radio_on && !force) in mwl8k_cmd_radio_control()
2792 return -ENOMEM; in mwl8k_cmd_radio_control()
2794 cmd->header.code = cpu_to_le16(MWL8K_CMD_RADIO_CONTROL); in mwl8k_cmd_radio_control()
2795 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_radio_control()
2796 cmd->action = cpu_to_le16(MWL8K_CMD_SET); in mwl8k_cmd_radio_control()
2797 cmd->control = cpu_to_le16(priv->radio_short_preamble ? 3 : 1); in mwl8k_cmd_radio_control()
2798 cmd->radio_on = cpu_to_le16(enable ? 0x0001 : 0x0000); in mwl8k_cmd_radio_control()
2800 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_radio_control()
2804 priv->radio_on = enable; in mwl8k_cmd_radio_control()
2822 struct mwl8k_priv *priv = hw->priv; in mwl8k_set_radio_preamble()
2824 priv->radio_short_preamble = short_preamble; in mwl8k_set_radio_preamble()
2850 return -ENOMEM; in mwl8k_cmd_rf_tx_power()
2852 cmd->header.code = cpu_to_le16(MWL8K_CMD_RF_TX_POWER); in mwl8k_cmd_rf_tx_power()
2853 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_rf_tx_power()
2854 cmd->action = cpu_to_le16(MWL8K_CMD_SET); in mwl8k_cmd_rf_tx_power()
2855 cmd->support_level = cpu_to_le16(dBm); in mwl8k_cmd_rf_tx_power()
2857 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_rf_tx_power()
2882 struct ieee80211_channel *channel = conf->chandef.chan; in mwl8k_cmd_tx_power()
2884 cfg80211_get_chandef_type(&conf->chandef); in mwl8k_cmd_tx_power()
2891 return -ENOMEM; in mwl8k_cmd_tx_power()
2893 cmd->header.code = cpu_to_le16(MWL8K_CMD_TX_POWER); in mwl8k_cmd_tx_power()
2894 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_tx_power()
2895 cmd->action = cpu_to_le16(MWL8K_CMD_SET_LIST); in mwl8k_cmd_tx_power()
2897 if (channel->band == NL80211_BAND_2GHZ) in mwl8k_cmd_tx_power()
2898 cmd->band = cpu_to_le16(0x1); in mwl8k_cmd_tx_power()
2899 else if (channel->band == NL80211_BAND_5GHZ) in mwl8k_cmd_tx_power()
2900 cmd->band = cpu_to_le16(0x4); in mwl8k_cmd_tx_power()
2902 cmd->channel = cpu_to_le16(channel->hw_value); in mwl8k_cmd_tx_power()
2906 cmd->bw = cpu_to_le16(0x2); in mwl8k_cmd_tx_power()
2908 cmd->bw = cpu_to_le16(0x4); in mwl8k_cmd_tx_power()
2910 cmd->sub_ch = cpu_to_le16(0x3); in mwl8k_cmd_tx_power()
2912 cmd->sub_ch = cpu_to_le16(0x1); in mwl8k_cmd_tx_power()
2916 cmd->power_level_list[i] = cpu_to_le16(pwr); in mwl8k_cmd_tx_power()
2918 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_tx_power()
2944 return -ENOMEM; in mwl8k_cmd_rf_antenna()
2946 cmd->header.code = cpu_to_le16(MWL8K_CMD_RF_ANTENNA); in mwl8k_cmd_rf_antenna()
2947 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_rf_antenna()
2948 cmd->antenna = cpu_to_le16(antenna); in mwl8k_cmd_rf_antenna()
2949 cmd->mode = cpu_to_le16(mask); in mwl8k_cmd_rf_antenna()
2951 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_rf_antenna()
2974 return -ENOMEM; in mwl8k_cmd_set_beacon()
2976 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_BEACON); in mwl8k_cmd_set_beacon()
2977 cmd->header.length = cpu_to_le16(sizeof(*cmd) + len); in mwl8k_cmd_set_beacon()
2978 cmd->beacon_len = cpu_to_le16(len); in mwl8k_cmd_set_beacon()
2979 memcpy(cmd->beacon, beacon, len); in mwl8k_cmd_set_beacon()
2981 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_set_beacon()
3001 return -ENOMEM; in mwl8k_cmd_set_pre_scan()
3003 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_PRE_SCAN); in mwl8k_cmd_set_pre_scan()
3004 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_pre_scan()
3006 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_pre_scan()
3034 return -ENOMEM; in mwl8k_cmd_bbp_reg_access()
3036 cmd->header.code = cpu_to_le16(MWL8K_CMD_BBP_REG_ACCESS); in mwl8k_cmd_bbp_reg_access()
3037 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_bbp_reg_access()
3038 cmd->action = cpu_to_le16(action); in mwl8k_cmd_bbp_reg_access()
3039 cmd->offset = cpu_to_le16(offset); in mwl8k_cmd_bbp_reg_access()
3041 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_bbp_reg_access()
3044 *value = cmd->value; in mwl8k_cmd_bbp_reg_access()
3070 return -ENOMEM; in mwl8k_cmd_set_post_scan()
3072 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_POST_SCAN); in mwl8k_cmd_set_post_scan()
3073 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_post_scan()
3074 cmd->isibss = 0; in mwl8k_cmd_set_post_scan()
3075 memcpy(cmd->bssid, mac, ETH_ALEN); in mwl8k_cmd_set_post_scan()
3077 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_post_scan()
3083 static int freq_to_idx(struct mwl8k_priv *priv, int freq) in freq_to_idx() argument
3089 sband = priv->hw->wiphy->bands[band]; in freq_to_idx()
3093 for (ch = 0; ch < sband->n_channels; ch++, idx++) in freq_to_idx()
3094 if (sband->channels[ch].center_freq == freq) in freq_to_idx()
3109 idx = freq_to_idx(priv, priv->acs_chan->center_freq); in mwl8k_update_survey()
3111 wiphy_err(priv->hw->wiphy, "Failed to update survey\n"); in mwl8k_update_survey()
3115 survey = &priv->survey[idx]; in mwl8k_update_survey()
3117 cca_cnt = ioread32(priv->regs + NOK_CCA_CNT_REG); in mwl8k_update_survey()
3119 survey->time_busy = (u64) cca_cnt; in mwl8k_update_survey()
3121 rx_rdy = ioread32(priv->regs + BBU_RXRDY_CNT_REG); in mwl8k_update_survey()
3123 survey->time_rx = (u64) rx_rdy; in mwl8k_update_survey()
3125 priv->channel_time = jiffies - priv->channel_time; in mwl8k_update_survey()
3126 survey->time = jiffies_to_msecs(priv->channel_time); in mwl8k_update_survey()
3128 survey->channel = channel; in mwl8k_update_survey()
3130 mwl8k_cmd_bbp_reg_access(priv->hw, 0, BBU_AVG_NOISE_VAL, &nf); in mwl8k_update_survey()
3133 survey->noise = nf * -1; in mwl8k_update_survey()
3135 survey->filled = SURVEY_INFO_NOISE_DBM | in mwl8k_update_survey()
3154 struct ieee80211_channel *channel = conf->chandef.chan; in mwl8k_cmd_set_rf_channel()
3156 cfg80211_get_chandef_type(&conf->chandef); in mwl8k_cmd_set_rf_channel()
3158 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_set_rf_channel()
3163 return -ENOMEM; in mwl8k_cmd_set_rf_channel()
3165 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RF_CHANNEL); in mwl8k_cmd_set_rf_channel()
3166 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_rf_channel()
3167 cmd->action = cpu_to_le16(MWL8K_CMD_SET); in mwl8k_cmd_set_rf_channel()
3168 cmd->current_channel = channel->hw_value; in mwl8k_cmd_set_rf_channel()
3170 if (channel->band == NL80211_BAND_2GHZ) in mwl8k_cmd_set_rf_channel()
3171 cmd->channel_flags |= cpu_to_le32(0x00000001); in mwl8k_cmd_set_rf_channel()
3172 else if (channel->band == NL80211_BAND_5GHZ) in mwl8k_cmd_set_rf_channel()
3173 cmd->channel_flags |= cpu_to_le32(0x00000004); in mwl8k_cmd_set_rf_channel()
3175 if (!priv->sw_scan_start) { in mwl8k_cmd_set_rf_channel()
3178 cmd->channel_flags |= cpu_to_le32(0x00000080); in mwl8k_cmd_set_rf_channel()
3180 cmd->channel_flags |= cpu_to_le32(0x000001900); in mwl8k_cmd_set_rf_channel()
3182 cmd->channel_flags |= cpu_to_le32(0x000000900); in mwl8k_cmd_set_rf_channel()
3184 cmd->channel_flags |= cpu_to_le32(0x00000080); in mwl8k_cmd_set_rf_channel()
3187 if (priv->sw_scan_start) { in mwl8k_cmd_set_rf_channel()
3192 if (priv->channel_time != 0) in mwl8k_cmd_set_rf_channel()
3193 mwl8k_update_survey(priv, priv->acs_chan); in mwl8k_cmd_set_rf_channel()
3195 priv->channel_time = jiffies; in mwl8k_cmd_set_rf_channel()
3196 priv->acs_chan = channel; in mwl8k_cmd_set_rf_channel()
3199 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_rf_channel()
3249 return -ENOMEM; in mwl8k_cmd_set_aid()
3251 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_AID); in mwl8k_cmd_set_aid()
3252 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_aid()
3253 cmd->aid = cpu_to_le16(vif->cfg.aid); in mwl8k_cmd_set_aid()
3254 memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN); in mwl8k_cmd_set_aid()
3256 if (vif->bss_conf.use_cts_prot) { in mwl8k_cmd_set_aid()
3259 switch (vif->bss_conf.ht_operation_mode & in mwl8k_cmd_set_aid()
3272 cmd->protection_mode = cpu_to_le16(prot_mode); in mwl8k_cmd_set_aid()
3274 legacy_rate_mask_to_array(cmd->supp_rates, legacy_rate_mask); in mwl8k_cmd_set_aid()
3276 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_aid()
3303 return -ENOMEM; in mwl8k_cmd_set_rate()
3305 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE); in mwl8k_cmd_set_rate()
3306 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_rate()
3307 legacy_rate_mask_to_array(cmd->legacy_rates, legacy_rate_mask); in mwl8k_cmd_set_rate()
3308 memcpy(cmd->mcs_set, mcs_rates, 16); in mwl8k_cmd_set_rate()
3310 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_rate()
3337 return -ENOMEM; in mwl8k_cmd_finalize_join()
3339 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN); in mwl8k_cmd_finalize_join()
3340 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_finalize_join()
3341 cmd->sleep_interval = cpu_to_le32(dtim ? dtim : 1); in mwl8k_cmd_finalize_join()
3343 payload_len = framelen - ieee80211_hdrlen(payload->frame_control); in mwl8k_cmd_finalize_join()
3349 memcpy(cmd->beacon_data, &payload->u.beacon, payload_len); in mwl8k_cmd_finalize_join()
3351 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_finalize_join()
3374 return -ENOMEM; in mwl8k_cmd_set_rts_threshold()
3376 cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD); in mwl8k_cmd_set_rts_threshold()
3377 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_rts_threshold()
3378 cmd->action = cpu_to_le16(MWL8K_CMD_SET); in mwl8k_cmd_set_rts_threshold()
3379 cmd->threshold = cpu_to_le16(rts_thresh); in mwl8k_cmd_set_rts_threshold()
3381 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_rts_threshold()
3403 return -ENOMEM; in mwl8k_cmd_set_slot()
3405 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_SLOT); in mwl8k_cmd_set_slot()
3406 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_slot()
3407 cmd->action = cpu_to_le16(MWL8K_CMD_SET); in mwl8k_cmd_set_slot()
3408 cmd->short_slot = short_slot_time; in mwl8k_cmd_set_slot()
3410 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_slot()
3471 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_set_edca_params()
3477 return -ENOMEM; in mwl8k_cmd_set_edca_params()
3479 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS); in mwl8k_cmd_set_edca_params()
3480 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_edca_params()
3481 cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL); in mwl8k_cmd_set_edca_params()
3482 cmd->txop = cpu_to_le16(txop); in mwl8k_cmd_set_edca_params()
3483 if (priv->ap_fw) { in mwl8k_cmd_set_edca_params()
3484 cmd->ap.log_cw_max = cpu_to_le32(ilog2(cw_max + 1)); in mwl8k_cmd_set_edca_params()
3485 cmd->ap.log_cw_min = cpu_to_le32(ilog2(cw_min + 1)); in mwl8k_cmd_set_edca_params()
3486 cmd->ap.aifs = aifs; in mwl8k_cmd_set_edca_params()
3487 cmd->ap.txq = qnum; in mwl8k_cmd_set_edca_params()
3489 cmd->sta.log_cw_max = (u8)ilog2(cw_max + 1); in mwl8k_cmd_set_edca_params()
3490 cmd->sta.log_cw_min = (u8)ilog2(cw_min + 1); in mwl8k_cmd_set_edca_params()
3491 cmd->sta.aifs = aifs; in mwl8k_cmd_set_edca_params()
3492 cmd->sta.txq = qnum; in mwl8k_cmd_set_edca_params()
3495 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_edca_params()
3511 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_set_wmm_mode()
3517 return -ENOMEM; in mwl8k_cmd_set_wmm_mode()
3519 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_WMM_MODE); in mwl8k_cmd_set_wmm_mode()
3520 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_wmm_mode()
3521 cmd->action = cpu_to_le16(!!enable); in mwl8k_cmd_set_wmm_mode()
3523 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_wmm_mode()
3527 priv->wmm_enabled = enable; in mwl8k_cmd_set_wmm_mode()
3549 return -ENOMEM; in mwl8k_cmd_mimo_config()
3551 cmd->header.code = cpu_to_le16(MWL8K_CMD_MIMO_CONFIG); in mwl8k_cmd_mimo_config()
3552 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_mimo_config()
3553 cmd->action = cpu_to_le32((u32)MWL8K_CMD_SET); in mwl8k_cmd_mimo_config()
3554 cmd->rx_antenna_map = rx; in mwl8k_cmd_mimo_config()
3555 cmd->tx_antenna_map = tx; in mwl8k_cmd_mimo_config()
3557 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_mimo_config()
3592 return -ENOMEM; in mwl8k_cmd_use_fixed_rate_sta()
3594 cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE); in mwl8k_cmd_use_fixed_rate_sta()
3595 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_use_fixed_rate_sta()
3596 cmd->action = cpu_to_le32(MWL8K_USE_AUTO_RATE); in mwl8k_cmd_use_fixed_rate_sta()
3597 cmd->rate_type = cpu_to_le32(MWL8K_UCAST_RATE); in mwl8k_cmd_use_fixed_rate_sta()
3599 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_use_fixed_rate_sta()
3632 return -ENOMEM; in mwl8k_cmd_use_fixed_rate_ap()
3634 cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE); in mwl8k_cmd_use_fixed_rate_ap()
3635 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_use_fixed_rate_ap()
3636 cmd->action = cpu_to_le32(MWL8K_USE_AUTO_RATE); in mwl8k_cmd_use_fixed_rate_ap()
3637 cmd->multicast_rate = mcast; in mwl8k_cmd_use_fixed_rate_ap()
3638 cmd->management_rate = mgmt; in mwl8k_cmd_use_fixed_rate_ap()
3640 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_use_fixed_rate_ap()
3661 return -ENOMEM; in mwl8k_cmd_enable_sniffer()
3663 cmd->header.code = cpu_to_le16(MWL8K_CMD_ENABLE_SNIFFER); in mwl8k_cmd_enable_sniffer()
3664 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_enable_sniffer()
3665 cmd->action = cpu_to_le32(!!enable); in mwl8k_cmd_enable_sniffer()
3667 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_enable_sniffer()
3692 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_update_mac_addr()
3699 if (vif != NULL && vif->type == NL80211_IFTYPE_STATION) { in mwl8k_cmd_update_mac_addr()
3700 if (mwl8k_vif->macid + 1 == ffs(priv->sta_macids_supported)) in mwl8k_cmd_update_mac_addr()
3701 if (priv->ap_fw) in mwl8k_cmd_update_mac_addr()
3707 } else if (vif != NULL && vif->type == NL80211_IFTYPE_AP) { in mwl8k_cmd_update_mac_addr()
3708 if (mwl8k_vif->macid + 1 == ffs(priv->ap_macids_supported)) in mwl8k_cmd_update_mac_addr()
3716 return -ENOMEM; in mwl8k_cmd_update_mac_addr()
3719 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR); in mwl8k_cmd_update_mac_addr()
3721 cmd->header.code = cpu_to_le16(MWL8K_CMD_DEL_MAC_ADDR); in mwl8k_cmd_update_mac_addr()
3723 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_update_mac_addr()
3724 if (priv->ap_fw) { in mwl8k_cmd_update_mac_addr()
3725 cmd->mbss.mac_type = cpu_to_le16(mac_type); in mwl8k_cmd_update_mac_addr()
3726 memcpy(cmd->mbss.mac_addr, mac, ETH_ALEN); in mwl8k_cmd_update_mac_addr()
3728 memcpy(cmd->mac_addr, mac, ETH_ALEN); in mwl8k_cmd_update_mac_addr()
3731 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_update_mac_addr()
3771 return -ENOMEM; in mwl8k_cmd_set_rateadapt_mode()
3773 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATEADAPT_MODE); in mwl8k_cmd_set_rateadapt_mode()
3774 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_rateadapt_mode()
3775 cmd->action = cpu_to_le16(MWL8K_CMD_SET); in mwl8k_cmd_set_rateadapt_mode()
3776 cmd->mode = cpu_to_le16(mode); in mwl8k_cmd_set_rateadapt_mode()
3778 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_set_rateadapt_mode()
3799 return -ENOMEM; in mwl8k_cmd_get_watchdog_bitmap()
3801 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_WATCHDOG_BITMAP); in mwl8k_cmd_get_watchdog_bitmap()
3802 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_get_watchdog_bitmap()
3804 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_get_watchdog_bitmap()
3806 *bitmap = cmd->bitmap; in mwl8k_cmd_get_watchdog_bitmap()
3825 struct ieee80211_hw *hw = priv->hw; in mwl8k_watchdog_ba_events()
3831 rc = mwl8k_cmd_get_watchdog_bitmap(priv->hw, &bitmap); in mwl8k_watchdog_ba_events()
3835 spin_lock(&priv->stream_lock); in mwl8k_watchdog_ba_events()
3842 streams = &priv->ampdu[stream_index]; in mwl8k_watchdog_ba_events()
3843 if (streams->state == AMPDU_STREAM_ACTIVE) { in mwl8k_watchdog_ba_events()
3844 ieee80211_stop_tx_ba_session(streams->sta, in mwl8k_watchdog_ba_events()
3845 streams->tid); in mwl8k_watchdog_ba_events()
3846 spin_unlock(&priv->stream_lock); in mwl8k_watchdog_ba_events()
3848 spin_lock(&priv->stream_lock); in mwl8k_watchdog_ba_events()
3853 spin_unlock(&priv->stream_lock); in mwl8k_watchdog_ba_events()
3855 atomic_dec(&priv->watchdog_event_pending); in mwl8k_watchdog_ba_events()
3856 status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); in mwl8k_watchdog_ba_events()
3858 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); in mwl8k_watchdog_ba_events()
3877 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_bss_start()
3880 if (enable && (priv->running_bsses & (1 << mwl8k_vif->macid))) in mwl8k_cmd_bss_start()
3883 if (!enable && !(priv->running_bsses & (1 << mwl8k_vif->macid))) in mwl8k_cmd_bss_start()
3888 return -ENOMEM; in mwl8k_cmd_bss_start()
3890 cmd->header.code = cpu_to_le16(MWL8K_CMD_BSS_START); in mwl8k_cmd_bss_start()
3891 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_bss_start()
3892 cmd->enable = cpu_to_le32(enable); in mwl8k_cmd_bss_start()
3894 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_bss_start()
3899 priv->running_bsses |= (1 << mwl8k_vif->macid); in mwl8k_cmd_bss_start()
3901 priv->running_bsses &= ~(1 << mwl8k_vif->macid); in mwl8k_cmd_bss_start()
3908 struct mwl8k_priv *priv = hw->priv; in mwl8k_enable_bsses()
3912 list_for_each_entry_safe(mwl8k_vif, tmp_vif, &priv->vif_list, list) { in mwl8k_enable_bsses()
3913 vif = mwl8k_vif->vif; in mwl8k_enable_bsses()
3915 if (!(bitmap & (1 << mwl8k_vif->macid))) in mwl8k_enable_bsses()
3918 if (vif->type == NL80211_IFTYPE_AP) in mwl8k_enable_bsses()
3980 return -ENOMEM; in mwl8k_check_ba()
3982 cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM); in mwl8k_check_ba()
3983 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_check_ba()
3985 cmd->action = cpu_to_le32(MWL8K_BA_CHECK); in mwl8k_check_ba()
3987 cmd->create_params.queue_id = stream->idx; in mwl8k_check_ba()
3988 memcpy(&cmd->create_params.peer_mac_addr[0], stream->sta->addr, in mwl8k_check_ba()
3990 cmd->create_params.tid = stream->tid; in mwl8k_check_ba()
3992 cmd->create_params.flags = in mwl8k_check_ba()
3996 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_check_ba()
4012 return -ENOMEM; in mwl8k_create_ba()
4015 cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM); in mwl8k_create_ba()
4016 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_create_ba()
4018 cmd->action = cpu_to_le32(MWL8K_BA_CREATE); in mwl8k_create_ba()
4020 cmd->create_params.bar_thrs = cpu_to_le32((u32)buf_size); in mwl8k_create_ba()
4021 cmd->create_params.window_size = cpu_to_le32((u32)buf_size); in mwl8k_create_ba()
4022 cmd->create_params.queue_id = stream->idx; in mwl8k_create_ba()
4024 memcpy(cmd->create_params.peer_mac_addr, stream->sta->addr, ETH_ALEN); in mwl8k_create_ba()
4025 cmd->create_params.tid = stream->tid; in mwl8k_create_ba()
4026 cmd->create_params.curr_seq_no = cpu_to_le16(0); in mwl8k_create_ba()
4027 cmd->create_params.reset_seq_no_flag = 1; in mwl8k_create_ba()
4029 cmd->create_params.param_info = in mwl8k_create_ba()
4030 (stream->sta->deflink.ht_cap.ampdu_factor & in mwl8k_create_ba()
4032 ((stream->sta->deflink.ht_cap.ampdu_density << 2) & in mwl8k_create_ba()
4035 cmd->create_params.flags = in mwl8k_create_ba()
4039 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_create_ba()
4041 wiphy_debug(hw->wiphy, "Created a BA stream for %pM : tid %d\n", in mwl8k_create_ba()
4042 stream->sta->addr, stream->tid); in mwl8k_create_ba()
4057 cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM); in mwl8k_destroy_ba()
4058 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_destroy_ba()
4059 cmd->action = cpu_to_le32(MWL8K_BA_DESTROY); in mwl8k_destroy_ba()
4061 cmd->destroy_params.ba_context = cpu_to_le32(idx); in mwl8k_destroy_ba()
4062 mwl8k_post_cmd(hw, &cmd->header); in mwl8k_destroy_ba()
4064 wiphy_debug(hw->wiphy, "Deleted BA stream index %d\n", idx); in mwl8k_destroy_ba()
4107 return -ENOMEM; in mwl8k_cmd_set_new_stn_add()
4109 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN); in mwl8k_cmd_set_new_stn_add()
4110 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_new_stn_add()
4111 cmd->aid = cpu_to_le16(sta->aid); in mwl8k_cmd_set_new_stn_add()
4112 memcpy(cmd->mac_addr, sta->addr, ETH_ALEN); in mwl8k_cmd_set_new_stn_add()
4113 cmd->stn_id = cpu_to_le16(sta->aid); in mwl8k_cmd_set_new_stn_add()
4114 cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD); in mwl8k_cmd_set_new_stn_add()
4115 if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) in mwl8k_cmd_set_new_stn_add()
4116 rates = sta->deflink.supp_rates[NL80211_BAND_2GHZ]; in mwl8k_cmd_set_new_stn_add()
4118 rates = sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 5; in mwl8k_cmd_set_new_stn_add()
4119 cmd->legacy_rates = cpu_to_le32(rates); in mwl8k_cmd_set_new_stn_add()
4120 if (sta->deflink.ht_cap.ht_supported) { in mwl8k_cmd_set_new_stn_add()
4121 cmd->ht_rates[0] = sta->deflink.ht_cap.mcs.rx_mask[0]; in mwl8k_cmd_set_new_stn_add()
4122 cmd->ht_rates[1] = sta->deflink.ht_cap.mcs.rx_mask[1]; in mwl8k_cmd_set_new_stn_add()
4123 cmd->ht_rates[2] = sta->deflink.ht_cap.mcs.rx_mask[2]; in mwl8k_cmd_set_new_stn_add()
4124 cmd->ht_rates[3] = sta->deflink.ht_cap.mcs.rx_mask[3]; in mwl8k_cmd_set_new_stn_add()
4125 cmd->ht_capabilities_info = cpu_to_le16(sta->deflink.ht_cap.cap); in mwl8k_cmd_set_new_stn_add()
4126 cmd->mac_ht_param_info = (sta->deflink.ht_cap.ampdu_factor & 3) | in mwl8k_cmd_set_new_stn_add()
4127 ((sta->deflink.ht_cap.ampdu_density & 7) << 2); in mwl8k_cmd_set_new_stn_add()
4128 cmd->is_qos_sta = 1; in mwl8k_cmd_set_new_stn_add()
4131 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_set_new_stn_add()
4145 return -ENOMEM; in mwl8k_cmd_set_new_stn_add_self()
4147 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN); in mwl8k_cmd_set_new_stn_add_self()
4148 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_new_stn_add_self()
4149 memcpy(cmd->mac_addr, vif->addr, ETH_ALEN); in mwl8k_cmd_set_new_stn_add_self()
4151 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_set_new_stn_add_self()
4161 struct mwl8k_priv *priv = hw->priv; in mwl8k_cmd_set_new_stn_del()
4165 spin_lock(&priv->stream_lock); in mwl8k_cmd_set_new_stn_del()
4169 s = &priv->ampdu[i]; in mwl8k_cmd_set_new_stn_del()
4170 if (s->state != AMPDU_NO_STREAM) { in mwl8k_cmd_set_new_stn_del()
4171 if (memcmp(s->sta->addr, addr, ETH_ALEN) == 0) { in mwl8k_cmd_set_new_stn_del()
4172 if (s->state == AMPDU_STREAM_ACTIVE) { in mwl8k_cmd_set_new_stn_del()
4173 idx = s->idx; in mwl8k_cmd_set_new_stn_del()
4174 spin_unlock(&priv->stream_lock); in mwl8k_cmd_set_new_stn_del()
4176 spin_lock(&priv->stream_lock); in mwl8k_cmd_set_new_stn_del()
4177 } else if (s->state == AMPDU_STREAM_NEW) { in mwl8k_cmd_set_new_stn_del()
4184 spin_unlock(&priv->stream_lock); in mwl8k_cmd_set_new_stn_del()
4188 return -ENOMEM; in mwl8k_cmd_set_new_stn_del()
4190 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN); in mwl8k_cmd_set_new_stn_del()
4191 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_set_new_stn_del()
4192 memcpy(cmd->mac_addr, addr, ETH_ALEN); in mwl8k_cmd_set_new_stn_del()
4193 cmd->action = cpu_to_le16(MWL8K_STA_ACTION_REMOVE); in mwl8k_cmd_set_new_stn_del()
4195 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_set_new_stn_del()
4275 return -ENOMEM; in mwl8k_cmd_update_encryption_enable()
4277 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_ENCRYPTION); in mwl8k_cmd_update_encryption_enable()
4278 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_update_encryption_enable()
4279 cmd->action = cpu_to_le32(MWL8K_ENCR_ENABLE); in mwl8k_cmd_update_encryption_enable()
4280 memcpy(cmd->mac_addr, addr, ETH_ALEN); in mwl8k_cmd_update_encryption_enable()
4281 cmd->encr_type = encr_type; in mwl8k_cmd_update_encryption_enable()
4283 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_update_encryption_enable()
4293 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_ENCRYPTION); in mwl8k_encryption_set_cmd_info()
4294 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_encryption_set_cmd_info()
4295 cmd->length = cpu_to_le16(sizeof(*cmd) - in mwl8k_encryption_set_cmd_info()
4297 cmd->key_id = cpu_to_le32(key->keyidx); in mwl8k_encryption_set_cmd_info()
4298 cmd->key_len = cpu_to_le16(key->keylen); in mwl8k_encryption_set_cmd_info()
4299 memcpy(cmd->mac_addr, addr, ETH_ALEN); in mwl8k_encryption_set_cmd_info()
4301 switch (key->cipher) { in mwl8k_encryption_set_cmd_info()
4304 cmd->key_type_id = cpu_to_le16(MWL8K_ALG_WEP); in mwl8k_encryption_set_cmd_info()
4305 if (key->keyidx == 0) in mwl8k_encryption_set_cmd_info()
4306 cmd->key_info = cpu_to_le32(MWL8K_KEY_FLAG_WEP_TXKEY); in mwl8k_encryption_set_cmd_info()
4310 cmd->key_type_id = cpu_to_le16(MWL8K_ALG_TKIP); in mwl8k_encryption_set_cmd_info()
4311 cmd->key_info = (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) in mwl8k_encryption_set_cmd_info()
4314 cmd->key_info |= cpu_to_le32(MWL8K_KEY_FLAG_MICKEY_VALID in mwl8k_encryption_set_cmd_info()
4318 cmd->key_type_id = cpu_to_le16(MWL8K_ALG_CCMP); in mwl8k_encryption_set_cmd_info()
4319 cmd->key_info = (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) in mwl8k_encryption_set_cmd_info()
4324 return -ENOTSUPP; in mwl8k_encryption_set_cmd_info()
4344 return -ENOMEM; in mwl8k_cmd_encryption_set_key()
4350 idx = key->keyidx; in mwl8k_cmd_encryption_set_key()
4352 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) in mwl8k_cmd_encryption_set_key()
4357 switch (key->cipher) { in mwl8k_cmd_encryption_set_key()
4360 if (!mwl8k_vif->wep_key_conf[idx].enabled) { in mwl8k_cmd_encryption_set_key()
4361 memcpy(mwl8k_vif->wep_key_conf[idx].key, key, in mwl8k_cmd_encryption_set_key()
4362 sizeof(*key) + key->keylen); in mwl8k_cmd_encryption_set_key()
4363 mwl8k_vif->wep_key_conf[idx].enabled = 1; in mwl8k_cmd_encryption_set_key()
4366 keymlen = key->keylen; in mwl8k_cmd_encryption_set_key()
4373 keymlen = key->keylen; in mwl8k_cmd_encryption_set_key()
4376 rc = -ENOTSUPP; in mwl8k_cmd_encryption_set_key()
4380 memcpy(&cmd->tkip, key->key, keymlen); in mwl8k_cmd_encryption_set_key()
4381 cmd->action = cpu_to_le32(action); in mwl8k_cmd_encryption_set_key()
4383 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_encryption_set_key()
4401 return -ENOMEM; in mwl8k_cmd_encryption_remove_key()
4407 if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || in mwl8k_cmd_encryption_remove_key()
4408 key->cipher == WLAN_CIPHER_SUITE_WEP104) in mwl8k_cmd_encryption_remove_key()
4409 mwl8k_vif->wep_key_conf[key->keyidx].enabled = 0; in mwl8k_cmd_encryption_remove_key()
4411 cmd->action = cpu_to_le32(MWL8K_ENCR_REMOVE_KEY); in mwl8k_cmd_encryption_remove_key()
4413 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_encryption_remove_key()
4430 struct mwl8k_priv *priv = hw->priv; in mwl8k_set_key()
4432 if (vif->type == NL80211_IFTYPE_STATION && !priv->ap_fw) in mwl8k_set_key()
4433 return -EOPNOTSUPP; in mwl8k_set_key()
4436 addr = vif->addr; in mwl8k_set_key()
4438 addr = sta->addr; in mwl8k_set_key()
4445 if ((key->cipher == WLAN_CIPHER_SUITE_WEP40) in mwl8k_set_key()
4446 || (key->cipher == WLAN_CIPHER_SUITE_WEP104)) in mwl8k_set_key()
4456 mwl8k_vif->is_hw_crypto_enabled = true; in mwl8k_set_key()
4478 /* Peer type - AP vs. STA. */
4517 /* Peer info - valid during add/update. */
4524 /* Peer Entry flags - used to define the type of the peer node */
4538 return -ENOMEM; in mwl8k_cmd_update_stadb_add()
4540 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB); in mwl8k_cmd_update_stadb_add()
4541 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_update_stadb_add()
4542 cmd->action = cpu_to_le32(MWL8K_STA_DB_MODIFY_ENTRY); in mwl8k_cmd_update_stadb_add()
4543 memcpy(cmd->peer_addr, sta->addr, ETH_ALEN); in mwl8k_cmd_update_stadb_add()
4545 p = &cmd->peer_info; in mwl8k_cmd_update_stadb_add()
4546 p->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT; in mwl8k_cmd_update_stadb_add()
4547 p->basic_caps = cpu_to_le16(vif->bss_conf.assoc_capability); in mwl8k_cmd_update_stadb_add()
4548 p->ht_support = sta->deflink.ht_cap.ht_supported; in mwl8k_cmd_update_stadb_add()
4549 p->ht_caps = cpu_to_le16(sta->deflink.ht_cap.cap); in mwl8k_cmd_update_stadb_add()
4550 p->extended_ht_caps = (sta->deflink.ht_cap.ampdu_factor & 3) | in mwl8k_cmd_update_stadb_add()
4551 ((sta->deflink.ht_cap.ampdu_density & 7) << 2); in mwl8k_cmd_update_stadb_add()
4552 if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) in mwl8k_cmd_update_stadb_add()
4553 rates = sta->deflink.supp_rates[NL80211_BAND_2GHZ]; in mwl8k_cmd_update_stadb_add()
4555 rates = sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 5; in mwl8k_cmd_update_stadb_add()
4556 legacy_rate_mask_to_array(p->legacy_rates, rates); in mwl8k_cmd_update_stadb_add()
4557 memcpy(p->ht_rates, &sta->deflink.ht_cap.mcs, 16); in mwl8k_cmd_update_stadb_add()
4558 p->interop = 1; in mwl8k_cmd_update_stadb_add()
4559 p->amsdu_enabled = 0; in mwl8k_cmd_update_stadb_add()
4561 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_update_stadb_add()
4563 rc = p->station_id; in mwl8k_cmd_update_stadb_add()
4577 return -ENOMEM; in mwl8k_cmd_update_stadb_del()
4579 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB); in mwl8k_cmd_update_stadb_del()
4580 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_update_stadb_del()
4581 cmd->action = cpu_to_le32(MWL8K_STA_DB_DEL_ENTRY); in mwl8k_cmd_update_stadb_del()
4582 memcpy(cmd->peer_addr, addr, ETH_ALEN); in mwl8k_cmd_update_stadb_del()
4584 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_update_stadb_del()
4597 struct mwl8k_priv *priv = hw->priv; in mwl8k_interrupt()
4600 status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); in mwl8k_interrupt()
4606 tasklet_schedule(&priv->poll_tx_task); in mwl8k_interrupt()
4611 tasklet_schedule(&priv->poll_rx_task); in mwl8k_interrupt()
4616 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); in mwl8k_interrupt()
4618 atomic_inc(&priv->watchdog_event_pending); in mwl8k_interrupt()
4620 ieee80211_queue_work(hw, &priv->watchdog_ba_handle); in mwl8k_interrupt()
4624 iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); in mwl8k_interrupt()
4627 if (priv->hostcmd_wait != NULL) in mwl8k_interrupt()
4628 complete(priv->hostcmd_wait); in mwl8k_interrupt()
4632 if (!mutex_is_locked(&priv->fw_mutex) && in mwl8k_interrupt()
4633 priv->radio_on && priv->pending_tx_pkts) in mwl8k_interrupt()
4643 struct ieee80211_hw *hw = pci_get_drvdata(priv->pdev); in mwl8k_tx_poll()
4644 int limit; in mwl8k_tx_poll() local
4647 limit = 32; in mwl8k_tx_poll()
4649 spin_lock(&priv->tx_lock); in mwl8k_tx_poll()
4652 limit -= mwl8k_txq_reclaim(hw, i, limit, 0); in mwl8k_tx_poll()
4654 if (!priv->pending_tx_pkts && priv->tx_wait != NULL) { in mwl8k_tx_poll()
4655 complete(priv->tx_wait); in mwl8k_tx_poll()
4656 priv->tx_wait = NULL; in mwl8k_tx_poll()
4659 spin_unlock(&priv->tx_lock); in mwl8k_tx_poll()
4661 if (limit) { in mwl8k_tx_poll()
4663 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); in mwl8k_tx_poll()
4665 tasklet_schedule(&priv->poll_tx_task); in mwl8k_tx_poll()
4672 struct ieee80211_hw *hw = pci_get_drvdata(priv->pdev); in mwl8k_rx_poll()
4673 int limit; in mwl8k_rx_poll() local
4675 limit = 32; in mwl8k_rx_poll()
4676 limit -= rxq_process(hw, 0, limit); in mwl8k_rx_poll()
4677 limit -= rxq_refill(hw, 0, limit); in mwl8k_rx_poll()
4679 if (limit) { in mwl8k_rx_poll()
4681 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); in mwl8k_rx_poll()
4683 tasklet_schedule(&priv->poll_rx_task); in mwl8k_rx_poll()
4695 struct mwl8k_priv *priv = hw->priv; in mwl8k_tx()
4698 if (!priv->radio_on) { in mwl8k_tx()
4699 wiphy_debug(hw->wiphy, in mwl8k_tx()
4705 mwl8k_txq_xmit(hw, index, control->sta, skb); in mwl8k_tx()
4710 struct mwl8k_priv *priv = hw->priv; in mwl8k_start()
4713 rc = request_irq(priv->pdev->irq, mwl8k_interrupt, in mwl8k_start()
4716 priv->irq = -1; in mwl8k_start()
4717 wiphy_err(hw->wiphy, "failed to register IRQ handler\n"); in mwl8k_start()
4718 return -EIO; in mwl8k_start()
4720 priv->irq = priv->pdev->irq; in mwl8k_start()
4723 tasklet_enable(&priv->poll_tx_task); in mwl8k_start()
4724 tasklet_enable(&priv->poll_rx_task); in mwl8k_start()
4727 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_start()
4729 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); in mwl8k_start()
4735 if (!priv->ap_fw) { in mwl8k_start()
4757 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_start()
4758 free_irq(priv->pdev->irq, hw); in mwl8k_start()
4759 priv->irq = -1; in mwl8k_start()
4760 tasklet_disable(&priv->poll_tx_task); in mwl8k_start()
4761 tasklet_disable(&priv->poll_rx_task); in mwl8k_start()
4771 struct mwl8k_priv *priv = hw->priv; in mwl8k_stop()
4774 if (!priv->hw_restart_in_progress) in mwl8k_stop()
4780 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_stop()
4781 if (priv->irq != -1) { in mwl8k_stop()
4782 free_irq(priv->pdev->irq, hw); in mwl8k_stop()
4783 priv->irq = -1; in mwl8k_stop()
4787 cancel_work_sync(&priv->finalize_join_worker); in mwl8k_stop()
4788 cancel_work_sync(&priv->watchdog_ba_handle); in mwl8k_stop()
4789 if (priv->beacon_skb != NULL) in mwl8k_stop()
4790 dev_kfree_skb(priv->beacon_skb); in mwl8k_stop()
4793 tasklet_disable(&priv->poll_tx_task); in mwl8k_stop()
4794 tasklet_disable(&priv->poll_rx_task); in mwl8k_stop()
4806 struct mwl8k_priv *priv = hw->priv; in mwl8k_add_interface()
4817 if (priv->sniffer_enabled) { in mwl8k_add_interface()
4818 wiphy_info(hw->wiphy, in mwl8k_add_interface()
4820 return -EINVAL; in mwl8k_add_interface()
4823 di = priv->device_info; in mwl8k_add_interface()
4824 switch (vif->type) { in mwl8k_add_interface()
4826 if (!priv->ap_fw && di->fw_image_ap) { in mwl8k_add_interface()
4828 if (!list_empty(&priv->vif_list)) in mwl8k_add_interface()
4829 return -EBUSY; in mwl8k_add_interface()
4830 rc = mwl8k_reload_firmware(hw, di->fw_image_ap); in mwl8k_add_interface()
4834 macids_supported = priv->ap_macids_supported; in mwl8k_add_interface()
4837 if (priv->ap_fw && di->fw_image_sta) { in mwl8k_add_interface()
4838 if (!list_empty(&priv->vif_list)) { in mwl8k_add_interface()
4839 wiphy_warn(hw->wiphy, "AP interface is running.\n" in mwl8k_add_interface()
4846 di->fw_image_sta); in mwl8k_add_interface()
4851 macids_supported = priv->sta_macids_supported; in mwl8k_add_interface()
4854 return -EINVAL; in mwl8k_add_interface()
4857 macid = ffs(macids_supported & ~priv->macids_used); in mwl8k_add_interface()
4858 if (!macid--) in mwl8k_add_interface()
4859 return -EBUSY; in mwl8k_add_interface()
4864 mwl8k_vif->vif = vif; in mwl8k_add_interface()
4865 mwl8k_vif->macid = macid; in mwl8k_add_interface()
4866 mwl8k_vif->seqno = 0; in mwl8k_add_interface()
4867 memcpy(mwl8k_vif->bssid, vif->addr, ETH_ALEN); in mwl8k_add_interface()
4868 mwl8k_vif->is_hw_crypto_enabled = false; in mwl8k_add_interface()
4871 mwl8k_cmd_set_mac_addr(hw, vif, vif->addr); in mwl8k_add_interface()
4873 if (vif->type == NL80211_IFTYPE_AP) in mwl8k_add_interface()
4876 priv->macids_used |= 1 << mwl8k_vif->macid; in mwl8k_add_interface()
4877 list_add_tail(&mwl8k_vif->list, &priv->vif_list); in mwl8k_add_interface()
4884 /* Has ieee80211_restart_hw re-added the removed interfaces? */ in mwl8k_remove_vif()
4885 if (!priv->macids_used) in mwl8k_remove_vif()
4888 priv->macids_used &= ~(1 << vif->macid); in mwl8k_remove_vif()
4889 list_del(&vif->list); in mwl8k_remove_vif()
4895 struct mwl8k_priv *priv = hw->priv; in mwl8k_remove_interface()
4898 if (vif->type == NL80211_IFTYPE_AP) in mwl8k_remove_interface()
4899 mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr); in mwl8k_remove_interface()
4901 mwl8k_cmd_del_mac_addr(hw, vif, vif->addr); in mwl8k_remove_interface()
4910 struct ieee80211_hw *hw = priv->hw; in mwl8k_hw_restart_work()
4915 if (priv->hostcmd_wait != NULL) { in mwl8k_hw_restart_work()
4916 complete(priv->hostcmd_wait); in mwl8k_hw_restart_work()
4917 priv->hostcmd_wait = NULL; in mwl8k_hw_restart_work()
4920 priv->hw_restart_owner = current; in mwl8k_hw_restart_work()
4921 di = priv->device_info; in mwl8k_hw_restart_work()
4924 if (priv->ap_fw) in mwl8k_hw_restart_work()
4925 rc = mwl8k_reload_firmware(hw, di->fw_image_ap); in mwl8k_hw_restart_work()
4927 rc = mwl8k_reload_firmware(hw, di->fw_image_sta); in mwl8k_hw_restart_work()
4932 priv->hw_restart_owner = NULL; in mwl8k_hw_restart_work()
4933 priv->hw_restart_in_progress = false; in mwl8k_hw_restart_work()
4944 wiphy_err(hw->wiphy, "Firmware restarted successfully\n"); in mwl8k_hw_restart_work()
4950 wiphy_err(hw->wiphy, "Firmware restart failed\n"); in mwl8k_hw_restart_work()
4955 struct ieee80211_conf *conf = &hw->conf; in mwl8k_config()
4956 struct mwl8k_priv *priv = hw->priv; in mwl8k_config()
4963 if (conf->flags & IEEE80211_CONF_IDLE) in mwl8k_config()
4976 if (conf->power_level > 18) in mwl8k_config()
4977 conf->power_level = 18; in mwl8k_config()
4979 if (priv->ap_fw) { in mwl8k_config()
4981 if (conf->flags & IEEE80211_CONF_CHANGE_POWER) { in mwl8k_config()
4982 rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level); in mwl8k_config()
4989 rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level); in mwl8k_config()
5005 struct mwl8k_priv *priv = hw->priv; in mwl8k_bss_info_changed_sta()
5016 if ((changed & BSS_CHANGED_ASSOC) && !vif->cfg.assoc) in mwl8k_bss_info_changed_sta()
5017 priv->capture_beacon = false; in mwl8k_bss_info_changed_sta()
5022 if (vif->cfg.assoc) { in mwl8k_bss_info_changed_sta()
5027 ap = ieee80211_find_sta(vif, vif->bss_conf.bssid); in mwl8k_bss_info_changed_sta()
5033 if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) { in mwl8k_bss_info_changed_sta()
5034 ap_legacy_rates = ap->deflink.supp_rates[NL80211_BAND_2GHZ]; in mwl8k_bss_info_changed_sta()
5037 ap->deflink.supp_rates[NL80211_BAND_5GHZ] << 5; in mwl8k_bss_info_changed_sta()
5039 memcpy(ap_mcs_rates, &ap->deflink.ht_cap.mcs, 16); in mwl8k_bss_info_changed_sta()
5044 if (!priv->ap_fw) { in mwl8k_bss_info_changed_sta()
5060 idx = ffs(vif->bss_conf.basic_rates); in mwl8k_bss_info_changed_sta()
5062 idx--; in mwl8k_bss_info_changed_sta()
5064 if (hw->conf.chandef.chan->band == in mwl8k_bss_info_changed_sta()
5077 vif->bss_conf.use_short_preamble); in mwl8k_bss_info_changed_sta()
5082 if ((changed & BSS_CHANGED_ERP_SLOT) && !priv->ap_fw) { in mwl8k_bss_info_changed_sta()
5083 rc = mwl8k_cmd_set_slot(hw, vif->bss_conf.use_short_slot); in mwl8k_bss_info_changed_sta()
5088 if (vif->cfg.assoc && !priv->ap_fw && in mwl8k_bss_info_changed_sta()
5096 if (vif->cfg.assoc && in mwl8k_bss_info_changed_sta()
5102 memcpy(priv->capture_bssid, vif->bss_conf.bssid, ETH_ALEN); in mwl8k_bss_info_changed_sta()
5103 priv->capture_beacon = true; in mwl8k_bss_info_changed_sta()
5121 vif->bss_conf.use_short_preamble); in mwl8k_bss_info_changed_ap()
5132 * and management frames (such as probe responses -- in mwl8k_bss_info_changed_ap()
5135 idx = ffs(vif->bss_conf.basic_rates); in mwl8k_bss_info_changed_ap()
5137 idx--; in mwl8k_bss_info_changed_ap()
5139 if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) in mwl8k_bss_info_changed_ap()
5152 mwl8k_cmd_set_beacon(hw, vif, skb->data, skb->len); in mwl8k_bss_info_changed_ap()
5158 mwl8k_cmd_bss_start(hw, vif, info->enable_beacon); in mwl8k_bss_info_changed_ap()
5168 if (vif->type == NL80211_IFTYPE_STATION) in mwl8k_bss_info_changed()
5170 if (vif->type == NL80211_IFTYPE_AP) in mwl8k_bss_info_changed()
5196 struct mwl8k_priv *priv = hw->priv; in mwl8k_configure_filter_sniffer()
5203 if (!list_empty(&priv->vif_list)) { in mwl8k_configure_filter_sniffer()
5205 wiphy_info(hw->wiphy, in mwl8k_configure_filter_sniffer()
5210 if (!priv->sniffer_enabled) { in mwl8k_configure_filter_sniffer()
5213 priv->sniffer_enabled = true; in mwl8k_configure_filter_sniffer()
5225 if (!list_empty(&priv->vif_list)) in mwl8k_first_vif()
5226 return list_entry(priv->vif_list.next, struct mwl8k_vif, list); in mwl8k_first_vif()
5236 struct mwl8k_priv *priv = hw->priv; in mwl8k_configure_filter()
5240 * AP firmware doesn't allow fine-grained control over in mwl8k_configure_filter()
5243 if (priv->ap_fw) { in mwl8k_configure_filter()
5267 if (priv->sniffer_enabled) { in mwl8k_configure_filter()
5269 priv->sniffer_enabled = false; in mwl8k_configure_filter()
5292 bssid = mwl8k_vif->vif->bss_conf.bssid; in mwl8k_configure_filter()
5302 * packet that ->prepare_multicast() built and replace it with in mwl8k_configure_filter()
5328 struct mwl8k_priv *priv = hw->priv; in mwl8k_sta_remove()
5330 if (priv->ap_fw) in mwl8k_sta_remove()
5331 return mwl8k_cmd_set_new_stn_del(hw, vif, sta->addr); in mwl8k_sta_remove()
5333 return mwl8k_cmd_update_stadb_del(hw, vif, sta->addr); in mwl8k_sta_remove()
5340 struct mwl8k_priv *priv = hw->priv; in mwl8k_sta_add()
5346 if (!priv->ap_fw) { in mwl8k_sta_add()
5349 MWL8K_STA(sta)->peer_id = ret; in mwl8k_sta_add()
5350 if (sta->deflink.ht_cap.ht_supported) in mwl8k_sta_add()
5351 MWL8K_STA(sta)->is_ampdu_allowed = true; in mwl8k_sta_add()
5360 key = IEEE80211_KEY_CONF(mwl8k_vif->wep_key_conf[i].key); in mwl8k_sta_add()
5361 if (mwl8k_vif->wep_key_conf[i].enabled) in mwl8k_sta_add()
5372 struct mwl8k_priv *priv = hw->priv; in mwl8k_conf_tx()
5377 BUG_ON(queue > MWL8K_TX_WMM_QUEUES - 1); in mwl8k_conf_tx()
5378 memcpy(&priv->wmm_params[queue], params, sizeof(*params)); in mwl8k_conf_tx()
5380 if (!priv->wmm_enabled) in mwl8k_conf_tx()
5384 int q = MWL8K_TX_WMM_QUEUES - 1 - queue; in mwl8k_conf_tx()
5386 params->cw_min, in mwl8k_conf_tx()
5387 params->cw_max, in mwl8k_conf_tx()
5388 params->aifs, in mwl8k_conf_tx()
5389 params->txop); in mwl8k_conf_tx()
5407 struct mwl8k_priv *priv = hw->priv; in mwl8k_get_survey()
5408 struct ieee80211_conf *conf = &hw->conf; in mwl8k_get_survey()
5411 if (priv->ap_fw) { in mwl8k_get_survey()
5412 sband = hw->wiphy->bands[NL80211_BAND_2GHZ]; in mwl8k_get_survey()
5414 if (sband && idx >= sband->n_channels) { in mwl8k_get_survey()
5415 idx -= sband->n_channels; in mwl8k_get_survey()
5420 sband = hw->wiphy->bands[NL80211_BAND_5GHZ]; in mwl8k_get_survey()
5422 if (!sband || idx >= sband->n_channels) in mwl8k_get_survey()
5423 return -ENOENT; in mwl8k_get_survey()
5425 memcpy(survey, &priv->survey[idx], sizeof(*survey)); in mwl8k_get_survey()
5426 survey->channel = &sband->channels[idx]; in mwl8k_get_survey()
5432 return -ENOENT; in mwl8k_get_survey()
5434 survey->channel = conf->chandef.chan; in mwl8k_get_survey()
5435 survey->filled = SURVEY_INFO_NOISE_DBM; in mwl8k_get_survey()
5436 survey->noise = priv->noise; in mwl8k_get_survey()
5447 struct ieee80211_sta *sta = params->sta; in mwl8k_ampdu_action()
5448 enum ieee80211_ampdu_mlme_action action = params->action; in mwl8k_ampdu_action()
5449 u16 tid = params->tid; in mwl8k_ampdu_action()
5450 u16 *ssn = ¶ms->ssn; in mwl8k_ampdu_action()
5451 u8 buf_size = params->buf_size; in mwl8k_ampdu_action()
5453 struct mwl8k_priv *priv = hw->priv; in mwl8k_ampdu_action()
5455 u8 *addr = sta->addr, idx; in mwl8k_ampdu_action()
5459 return -ENOTSUPP; in mwl8k_ampdu_action()
5461 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5485 wiphy_warn(hw->wiphy, "Unexpected call to %s. " in mwl8k_ampdu_action()
5490 wiphy_debug(hw->wiphy, "no free AMPDU streams\n"); in mwl8k_ampdu_action()
5491 rc = -EBUSY; in mwl8k_ampdu_action()
5494 stream->state = AMPDU_STREAM_IN_PROGRESS; in mwl8k_ampdu_action()
5497 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5501 if (!sta_info->is_ampdu_allowed) { in mwl8k_ampdu_action()
5502 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5504 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5505 return -EBUSY; in mwl8k_ampdu_action()
5511 * return -EBUSY. Avoid retrying mwl8k_check_ba in in mwl8k_ampdu_action()
5514 if (!rc || rc == -EBUSY) in mwl8k_ampdu_action()
5523 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5525 wiphy_err(hw->wiphy, "Stream for tid %d busy after %d" in mwl8k_ampdu_action()
5528 rc = -EBUSY; in mwl8k_ampdu_action()
5537 if (stream->state == AMPDU_STREAM_ACTIVE) { in mwl8k_ampdu_action()
5538 idx = stream->idx; in mwl8k_ampdu_action()
5539 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5541 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5549 BUG_ON(stream->state != AMPDU_STREAM_IN_PROGRESS); in mwl8k_ampdu_action()
5550 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5552 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5554 stream->state = AMPDU_STREAM_ACTIVE; in mwl8k_ampdu_action()
5556 idx = stream->idx; in mwl8k_ampdu_action()
5557 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5559 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5560 wiphy_debug(hw->wiphy, in mwl8k_ampdu_action()
5568 rc = -ENOTSUPP; in mwl8k_ampdu_action()
5571 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5579 struct mwl8k_priv *priv = hw->priv; in mwl8k_sw_scan_start()
5582 if (!priv->ap_fw) in mwl8k_sw_scan_start()
5586 priv->channel_time = 0; in mwl8k_sw_scan_start()
5587 ioread32(priv->regs + BBU_RXRDY_CNT_REG); in mwl8k_sw_scan_start()
5588 ioread32(priv->regs + NOK_CCA_CNT_REG); in mwl8k_sw_scan_start()
5589 mwl8k_cmd_bbp_reg_access(priv->hw, 0, BBU_AVG_NOISE_VAL, &tmp); in mwl8k_sw_scan_start()
5591 priv->sw_scan_start = true; in mwl8k_sw_scan_start()
5597 struct mwl8k_priv *priv = hw->priv; in mwl8k_sw_scan_complete()
5600 if (!priv->ap_fw) in mwl8k_sw_scan_complete()
5603 priv->sw_scan_start = false; in mwl8k_sw_scan_complete()
5606 priv->channel_time = 0; in mwl8k_sw_scan_complete()
5607 ioread32(priv->regs + BBU_RXRDY_CNT_REG); in mwl8k_sw_scan_complete()
5608 ioread32(priv->regs + NOK_CCA_CNT_REG); in mwl8k_sw_scan_complete()
5609 mwl8k_cmd_bbp_reg_access(priv->hw, 0, BBU_AVG_NOISE_VAL, &tmp); in mwl8k_sw_scan_complete()
5639 struct sk_buff *skb = priv->beacon_skb; in mwl8k_finalize_join_worker()
5640 struct ieee80211_mgmt *mgmt = (void *)skb->data; in mwl8k_finalize_join_worker()
5641 int len = skb->len - offsetof(struct ieee80211_mgmt, u.beacon.variable); in mwl8k_finalize_join_worker()
5643 mgmt->u.beacon.variable, len); in mwl8k_finalize_join_worker()
5649 mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, dtim_period); in mwl8k_finalize_join_worker()
5652 priv->beacon_skb = NULL; in mwl8k_finalize_join_worker()
5663 #define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw"
5667 #define _MWL8K_8764_AP_FW(api) "mwl8k/fmimage_8764_ap-" #api ".fw"
5724 "Trying alternative firmware %s\n", pci_name(priv->pdev), in mwl8k_request_alt_fw()
5725 priv->fw_pref, priv->fw_alt); in mwl8k_request_alt_fw()
5726 rc = mwl8k_request_fw(priv, priv->fw_alt, &priv->fw_ucode, true); in mwl8k_request_alt_fw()
5729 pci_name(priv->pdev), priv->fw_alt); in mwl8k_request_alt_fw()
5739 struct mwl8k_device_info *di = priv->device_info; in mwl8k_fw_state_machine()
5742 switch (priv->fw_state) { in mwl8k_fw_state_machine()
5746 pci_name(priv->pdev), di->helper_image); in mwl8k_fw_state_machine()
5749 priv->fw_helper = fw; in mwl8k_fw_state_machine()
5750 rc = mwl8k_request_fw(priv, priv->fw_pref, &priv->fw_ucode, in mwl8k_fw_state_machine()
5752 if (rc && priv->fw_alt) { in mwl8k_fw_state_machine()
5756 priv->fw_state = FW_STATE_LOADING_ALT; in mwl8k_fw_state_machine()
5760 priv->fw_state = FW_STATE_LOADING_PREF; in mwl8k_fw_state_machine()
5765 if (priv->fw_alt) { in mwl8k_fw_state_machine()
5769 priv->fw_state = FW_STATE_LOADING_ALT; in mwl8k_fw_state_machine()
5773 priv->fw_ucode = fw; in mwl8k_fw_state_machine()
5778 complete(&priv->firmware_loading_complete); in mwl8k_fw_state_machine()
5785 pci_name(priv->pdev), di->helper_image); in mwl8k_fw_state_machine()
5788 priv->fw_ucode = fw; in mwl8k_fw_state_machine()
5793 complete(&priv->firmware_loading_complete); in mwl8k_fw_state_machine()
5798 MWL8K_NAME, priv->fw_state); in mwl8k_fw_state_machine()
5805 priv->fw_state = FW_STATE_ERROR; in mwl8k_fw_state_machine()
5806 complete(&priv->firmware_loading_complete); in mwl8k_fw_state_machine()
5808 device_release_driver(&priv->pdev->dev); in mwl8k_fw_state_machine()
5815 struct mwl8k_priv *priv = hw->priv; in mwl8k_init_firmware()
5826 wiphy_err(hw->wiphy, "Firmware files not found\n"); in mwl8k_init_firmware()
5836 wiphy_err(hw->wiphy, "Cannot start firmware\n"); in mwl8k_init_firmware()
5845 count--; in mwl8k_init_firmware()
5846 wiphy_err(hw->wiphy, "Trying to reload the firmware again\n"); in mwl8k_init_firmware()
5856 struct mwl8k_priv *priv = hw->priv; in mwl8k_init_txqs()
5864 if (priv->ap_fw) in mwl8k_init_txqs()
5865 iowrite32(priv->txq[i].txd_dma, in mwl8k_init_txqs()
5866 priv->sram + priv->txq_offset[i]); in mwl8k_init_txqs()
5874 struct mwl8k_priv *priv = hw->priv; in mwl8k_probe_hw()
5878 if (priv->ap_fw) { in mwl8k_probe_hw()
5879 priv->rxd_ops = priv->device_info->ap_rxd_ops; in mwl8k_probe_hw()
5880 if (priv->rxd_ops == NULL) { in mwl8k_probe_hw()
5881 wiphy_err(hw->wiphy, in mwl8k_probe_hw()
5883 rc = -ENOENT; in mwl8k_probe_hw()
5887 priv->rxd_ops = &rxd_sta_ops; in mwl8k_probe_hw()
5890 priv->sniffer_enabled = false; in mwl8k_probe_hw()
5891 priv->wmm_enabled = false; in mwl8k_probe_hw()
5892 priv->pending_tx_pkts = 0; in mwl8k_probe_hw()
5893 atomic_set(&priv->watchdog_event_pending, 0); in mwl8k_probe_hw()
5906 priv->num_ampdu_queues = 0; in mwl8k_probe_hw()
5907 if (!priv->ap_fw) { in mwl8k_probe_hw()
5913 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); in mwl8k_probe_hw()
5914 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_probe_hw()
5917 priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); in mwl8k_probe_hw()
5919 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); in mwl8k_probe_hw()
5921 rc = request_irq(priv->pdev->irq, mwl8k_interrupt, in mwl8k_probe_hw()
5924 wiphy_err(hw->wiphy, "failed to register IRQ handler\n"); in mwl8k_probe_hw()
5934 if (!priv->hw_restart_in_progress) in mwl8k_probe_hw()
5935 memset(priv->ampdu, 0, sizeof(priv->ampdu)); in mwl8k_probe_hw()
5942 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_probe_hw()
5945 if (priv->ap_fw) { in mwl8k_probe_hw()
5955 wiphy_err(hw->wiphy, "Cannot initialise firmware\n"); in mwl8k_probe_hw()
5962 wiphy_err(hw->wiphy, "Cannot disable\n"); in mwl8k_probe_hw()
5969 wiphy_err(hw->wiphy, "Cannot clear MAC address\n"); in mwl8k_probe_hw()
5976 wiphy_warn(hw->wiphy, "failed to set # of RX antennas"); in mwl8k_probe_hw()
5979 wiphy_warn(hw->wiphy, "failed to set # of TX antennas"); in mwl8k_probe_hw()
5983 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_probe_hw()
5984 free_irq(priv->pdev->irq, hw); in mwl8k_probe_hw()
5986 wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n", in mwl8k_probe_hw()
5987 priv->device_info->part_name, in mwl8k_probe_hw()
5988 priv->hw_rev, hw->wiphy->perm_addr, in mwl8k_probe_hw()
5989 priv->ap_fw ? "AP" : "STA", in mwl8k_probe_hw()
5990 (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff, in mwl8k_probe_hw()
5991 (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff); in mwl8k_probe_hw()
5996 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_probe_hw()
5997 free_irq(priv->pdev->irq, hw); in mwl8k_probe_hw()
6017 struct mwl8k_priv *priv = hw->priv; in mwl8k_reload_firmware()
6024 * All the existing interfaces are re-added by the ieee80211_reconfig; in mwl8k_reload_firmware()
6028 if (priv->hw_restart_in_progress) in mwl8k_reload_firmware()
6029 list_for_each_entry_safe(vif, tmp_vif, &priv->vif_list, list) in mwl8k_reload_firmware()
6043 if (priv->hw_restart_in_progress) in mwl8k_reload_firmware()
6055 rc = mwl8k_conf_tx(hw, NULL, 0, i, &priv->wmm_params[i]); in mwl8k_reload_firmware()
6082 struct ieee80211_hw *hw = priv->hw; in mwl8k_firmware_load_success()
6088 wiphy_err(hw->wiphy, "Cannot start firmware\n"); in mwl8k_firmware_load_success()
6096 hw->extra_tx_headroom = in mwl8k_firmware_load_success()
6097 sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts); in mwl8k_firmware_load_success()
6099 hw->extra_tx_headroom -= priv->ap_fw ? REDUCED_TX_HEADROOM : 0; in mwl8k_firmware_load_success()
6101 hw->queues = MWL8K_TX_WMM_QUEUES; in mwl8k_firmware_load_success()
6111 if (priv->ap_fw) in mwl8k_firmware_load_success()
6114 hw->vif_data_size = sizeof(struct mwl8k_vif); in mwl8k_firmware_load_success()
6115 hw->sta_data_size = sizeof(struct mwl8k_sta); in mwl8k_firmware_load_success()
6117 priv->macids_used = 0; in mwl8k_firmware_load_success()
6118 INIT_LIST_HEAD(&priv->vif_list); in mwl8k_firmware_load_success()
6121 priv->radio_on = false; in mwl8k_firmware_load_success()
6122 priv->radio_short_preamble = false; in mwl8k_firmware_load_success()
6125 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); in mwl8k_firmware_load_success()
6127 INIT_WORK(&priv->watchdog_ba_handle, mwl8k_watchdog_ba_events); in mwl8k_firmware_load_success()
6129 INIT_WORK(&priv->fw_reload, mwl8k_hw_restart_work); in mwl8k_firmware_load_success()
6132 tasklet_setup(&priv->poll_tx_task, mwl8k_tx_poll); in mwl8k_firmware_load_success()
6133 tasklet_disable(&priv->poll_tx_task); in mwl8k_firmware_load_success()
6134 tasklet_setup(&priv->poll_rx_task, mwl8k_rx_poll); in mwl8k_firmware_load_success()
6135 tasklet_disable(&priv->poll_rx_task); in mwl8k_firmware_load_success()
6138 priv->cookie = dma_alloc_coherent(&priv->pdev->dev, 4, in mwl8k_firmware_load_success()
6139 &priv->cookie_dma, GFP_KERNEL); in mwl8k_firmware_load_success()
6140 if (priv->cookie == NULL) in mwl8k_firmware_load_success()
6141 return -ENOMEM; in mwl8k_firmware_load_success()
6143 mutex_init(&priv->fw_mutex); in mwl8k_firmware_load_success()
6144 priv->fw_mutex_owner = NULL; in mwl8k_firmware_load_success()
6145 priv->fw_mutex_depth = 0; in mwl8k_firmware_load_success()
6146 priv->hostcmd_wait = NULL; in mwl8k_firmware_load_success()
6148 spin_lock_init(&priv->tx_lock); in mwl8k_firmware_load_success()
6150 spin_lock_init(&priv->stream_lock); in mwl8k_firmware_load_success()
6152 priv->tx_wait = NULL; in mwl8k_firmware_load_success()
6158 hw->wiphy->interface_modes = 0; in mwl8k_firmware_load_success()
6160 if (priv->ap_macids_supported || priv->device_info->fw_image_ap) { in mwl8k_firmware_load_success()
6161 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); in mwl8k_firmware_load_success()
6162 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); in mwl8k_firmware_load_success()
6163 hw->wiphy->iface_combinations = &ap_if_comb; in mwl8k_firmware_load_success()
6164 hw->wiphy->n_iface_combinations = 1; in mwl8k_firmware_load_success()
6167 if (priv->sta_macids_supported || priv->device_info->fw_image_sta) in mwl8k_firmware_load_success()
6168 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); in mwl8k_firmware_load_success()
6170 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); in mwl8k_firmware_load_success()
6174 wiphy_err(hw->wiphy, "Cannot register device\n"); in mwl8k_firmware_load_success()
6186 if (priv->cookie != NULL) in mwl8k_firmware_load_success()
6187 dma_free_coherent(&priv->pdev->dev, 4, priv->cookie, in mwl8k_firmware_load_success()
6188 priv->cookie_dma); in mwl8k_firmware_load_success()
6226 printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME); in mwl8k_probe()
6227 rc = -ENOMEM; in mwl8k_probe()
6231 SET_IEEE80211_DEV(hw, &pdev->dev); in mwl8k_probe()
6234 priv = hw->priv; in mwl8k_probe()
6235 priv->hw = hw; in mwl8k_probe()
6236 priv->pdev = pdev; in mwl8k_probe()
6237 priv->device_info = &mwl8k_info_tbl[id->driver_data]; in mwl8k_probe()
6239 if (id->driver_data == MWL8764) in mwl8k_probe()
6240 priv->is_8764 = true; in mwl8k_probe()
6242 priv->sram = pci_iomap(pdev, 0, 0x10000); in mwl8k_probe()
6243 if (priv->sram == NULL) { in mwl8k_probe()
6244 wiphy_err(hw->wiphy, "Cannot map device SRAM\n"); in mwl8k_probe()
6245 rc = -EIO; in mwl8k_probe()
6253 priv->regs = pci_iomap(pdev, 1, 0x10000); in mwl8k_probe()
6254 if (priv->regs == NULL) { in mwl8k_probe()
6255 priv->regs = pci_iomap(pdev, 2, 0x10000); in mwl8k_probe()
6256 if (priv->regs == NULL) { in mwl8k_probe()
6257 wiphy_err(hw->wiphy, "Cannot map device registers\n"); in mwl8k_probe()
6258 rc = -EIO; in mwl8k_probe()
6268 init_completion(&priv->firmware_loading_complete); in mwl8k_probe()
6269 di = priv->device_info; in mwl8k_probe()
6270 if (ap_mode_default && di->fw_image_ap) { in mwl8k_probe()
6271 priv->fw_pref = di->fw_image_ap; in mwl8k_probe()
6272 priv->fw_alt = di->fw_image_sta; in mwl8k_probe()
6273 } else if (!ap_mode_default && di->fw_image_sta) { in mwl8k_probe()
6274 priv->fw_pref = di->fw_image_sta; in mwl8k_probe()
6275 priv->fw_alt = di->fw_image_ap; in mwl8k_probe()
6276 } else if (ap_mode_default && !di->fw_image_ap && di->fw_image_sta) { in mwl8k_probe()
6278 priv->fw_pref = di->fw_image_sta; in mwl8k_probe()
6279 } else if (!ap_mode_default && !di->fw_image_sta && di->fw_image_ap) { in mwl8k_probe()
6281 priv->fw_pref = di->fw_image_ap; in mwl8k_probe()
6283 rc = mwl8k_init_firmware(hw, priv->fw_pref, true); in mwl8k_probe()
6287 priv->hw_restart_in_progress = false; in mwl8k_probe()
6289 priv->running_bsses = 0; in mwl8k_probe()
6297 if (priv->regs != NULL) in mwl8k_probe()
6298 pci_iounmap(pdev, priv->regs); in mwl8k_probe()
6300 if (priv->sram != NULL) in mwl8k_probe()
6301 pci_iounmap(pdev, priv->sram); in mwl8k_probe()
6322 priv = hw->priv; in mwl8k_remove()
6324 wait_for_completion(&priv->firmware_loading_complete); in mwl8k_remove()
6326 if (priv->fw_state == FW_STATE_ERROR) { in mwl8k_remove()
6336 tasklet_kill(&priv->poll_tx_task); in mwl8k_remove()
6337 tasklet_kill(&priv->poll_rx_task); in mwl8k_remove()
6351 dma_free_coherent(&priv->pdev->dev, 4, priv->cookie, priv->cookie_dma); in mwl8k_remove()
6354 pci_iounmap(pdev, priv->regs); in mwl8k_remove()
6355 pci_iounmap(pdev, priv->sram); in mwl8k_remove()