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 (jiffies - 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->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->bss_conf.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->ht_cap.ampdu_factor & in mwl8k_create_ba()
4032 ((stream->sta->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->supp_rates[NL80211_BAND_2GHZ]; in mwl8k_cmd_set_new_stn_add()
4118 rates = sta->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->ht_cap.ht_supported) { in mwl8k_cmd_set_new_stn_add()
4121 cmd->ht_rates[0] = sta->ht_cap.mcs.rx_mask[0]; in mwl8k_cmd_set_new_stn_add()
4122 cmd->ht_rates[1] = sta->ht_cap.mcs.rx_mask[1]; in mwl8k_cmd_set_new_stn_add()
4123 cmd->ht_rates[2] = sta->ht_cap.mcs.rx_mask[2]; in mwl8k_cmd_set_new_stn_add()
4124 cmd->ht_rates[3] = sta->ht_cap.mcs.rx_mask[3]; in mwl8k_cmd_set_new_stn_add()
4125 cmd->ht_capabilities_info = cpu_to_le16(sta->ht_cap.cap); in mwl8k_cmd_set_new_stn_add()
4126 cmd->mac_ht_param_info = (sta->ht_cap.ampdu_factor & 3) | in mwl8k_cmd_set_new_stn_add()
4127 ((sta->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()
4273 return -ENOMEM; in mwl8k_cmd_update_encryption_enable()
4275 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_ENCRYPTION); in mwl8k_cmd_update_encryption_enable()
4276 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_update_encryption_enable()
4277 cmd->action = cpu_to_le32(MWL8K_ENCR_ENABLE); in mwl8k_cmd_update_encryption_enable()
4278 memcpy(cmd->mac_addr, addr, ETH_ALEN); in mwl8k_cmd_update_encryption_enable()
4279 cmd->encr_type = encr_type; in mwl8k_cmd_update_encryption_enable()
4281 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_update_encryption_enable()
4291 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_ENCRYPTION); in mwl8k_encryption_set_cmd_info()
4292 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_encryption_set_cmd_info()
4293 cmd->length = cpu_to_le16(sizeof(*cmd) - in mwl8k_encryption_set_cmd_info()
4295 cmd->key_id = cpu_to_le32(key->keyidx); in mwl8k_encryption_set_cmd_info()
4296 cmd->key_len = cpu_to_le16(key->keylen); in mwl8k_encryption_set_cmd_info()
4297 memcpy(cmd->mac_addr, addr, ETH_ALEN); in mwl8k_encryption_set_cmd_info()
4299 switch (key->cipher) { in mwl8k_encryption_set_cmd_info()
4302 cmd->key_type_id = cpu_to_le16(MWL8K_ALG_WEP); in mwl8k_encryption_set_cmd_info()
4303 if (key->keyidx == 0) in mwl8k_encryption_set_cmd_info()
4304 cmd->key_info = cpu_to_le32(MWL8K_KEY_FLAG_WEP_TXKEY); in mwl8k_encryption_set_cmd_info()
4308 cmd->key_type_id = cpu_to_le16(MWL8K_ALG_TKIP); in mwl8k_encryption_set_cmd_info()
4309 cmd->key_info = (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) in mwl8k_encryption_set_cmd_info()
4312 cmd->key_info |= cpu_to_le32(MWL8K_KEY_FLAG_MICKEY_VALID in mwl8k_encryption_set_cmd_info()
4316 cmd->key_type_id = cpu_to_le16(MWL8K_ALG_CCMP); in mwl8k_encryption_set_cmd_info()
4317 cmd->key_info = (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) in mwl8k_encryption_set_cmd_info()
4322 return -ENOTSUPP; in mwl8k_encryption_set_cmd_info()
4342 return -ENOMEM; in mwl8k_cmd_encryption_set_key()
4348 idx = key->keyidx; in mwl8k_cmd_encryption_set_key()
4350 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) in mwl8k_cmd_encryption_set_key()
4355 switch (key->cipher) { in mwl8k_cmd_encryption_set_key()
4358 if (!mwl8k_vif->wep_key_conf[idx].enabled) { in mwl8k_cmd_encryption_set_key()
4359 memcpy(mwl8k_vif->wep_key_conf[idx].key, key, in mwl8k_cmd_encryption_set_key()
4360 sizeof(*key) + key->keylen); in mwl8k_cmd_encryption_set_key()
4361 mwl8k_vif->wep_key_conf[idx].enabled = 1; in mwl8k_cmd_encryption_set_key()
4364 keymlen = key->keylen; in mwl8k_cmd_encryption_set_key()
4371 keymlen = key->keylen; in mwl8k_cmd_encryption_set_key()
4374 rc = -ENOTSUPP; in mwl8k_cmd_encryption_set_key()
4378 memcpy(cmd->key_material, key->key, keymlen); in mwl8k_cmd_encryption_set_key()
4379 cmd->action = cpu_to_le32(action); in mwl8k_cmd_encryption_set_key()
4381 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_encryption_set_key()
4399 return -ENOMEM; in mwl8k_cmd_encryption_remove_key()
4405 if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || in mwl8k_cmd_encryption_remove_key()
4406 key->cipher == WLAN_CIPHER_SUITE_WEP104) in mwl8k_cmd_encryption_remove_key()
4407 mwl8k_vif->wep_key_conf[key->keyidx].enabled = 0; in mwl8k_cmd_encryption_remove_key()
4409 cmd->action = cpu_to_le32(MWL8K_ENCR_REMOVE_KEY); in mwl8k_cmd_encryption_remove_key()
4411 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); in mwl8k_cmd_encryption_remove_key()
4428 struct mwl8k_priv *priv = hw->priv; in mwl8k_set_key()
4430 if (vif->type == NL80211_IFTYPE_STATION && !priv->ap_fw) in mwl8k_set_key()
4431 return -EOPNOTSUPP; in mwl8k_set_key()
4434 addr = vif->addr; in mwl8k_set_key()
4436 addr = sta->addr; in mwl8k_set_key()
4443 if ((key->cipher == WLAN_CIPHER_SUITE_WEP40) in mwl8k_set_key()
4444 || (key->cipher == WLAN_CIPHER_SUITE_WEP104)) in mwl8k_set_key()
4454 mwl8k_vif->is_hw_crypto_enabled = true; in mwl8k_set_key()
4476 /* Peer type - AP vs. STA. */
4515 /* Peer info - valid during add/update. */
4522 /* Peer Entry flags - used to define the type of the peer node */
4536 return -ENOMEM; in mwl8k_cmd_update_stadb_add()
4538 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB); in mwl8k_cmd_update_stadb_add()
4539 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_update_stadb_add()
4540 cmd->action = cpu_to_le32(MWL8K_STA_DB_MODIFY_ENTRY); in mwl8k_cmd_update_stadb_add()
4541 memcpy(cmd->peer_addr, sta->addr, ETH_ALEN); in mwl8k_cmd_update_stadb_add()
4543 p = &cmd->peer_info; in mwl8k_cmd_update_stadb_add()
4544 p->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT; in mwl8k_cmd_update_stadb_add()
4545 p->basic_caps = cpu_to_le16(vif->bss_conf.assoc_capability); in mwl8k_cmd_update_stadb_add()
4546 p->ht_support = sta->ht_cap.ht_supported; in mwl8k_cmd_update_stadb_add()
4547 p->ht_caps = cpu_to_le16(sta->ht_cap.cap); in mwl8k_cmd_update_stadb_add()
4548 p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) | in mwl8k_cmd_update_stadb_add()
4549 ((sta->ht_cap.ampdu_density & 7) << 2); in mwl8k_cmd_update_stadb_add()
4550 if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) in mwl8k_cmd_update_stadb_add()
4551 rates = sta->supp_rates[NL80211_BAND_2GHZ]; in mwl8k_cmd_update_stadb_add()
4553 rates = sta->supp_rates[NL80211_BAND_5GHZ] << 5; in mwl8k_cmd_update_stadb_add()
4554 legacy_rate_mask_to_array(p->legacy_rates, rates); in mwl8k_cmd_update_stadb_add()
4555 memcpy(p->ht_rates, &sta->ht_cap.mcs, 16); in mwl8k_cmd_update_stadb_add()
4556 p->interop = 1; in mwl8k_cmd_update_stadb_add()
4557 p->amsdu_enabled = 0; in mwl8k_cmd_update_stadb_add()
4559 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_update_stadb_add()
4561 rc = p->station_id; in mwl8k_cmd_update_stadb_add()
4575 return -ENOMEM; in mwl8k_cmd_update_stadb_del()
4577 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB); in mwl8k_cmd_update_stadb_del()
4578 cmd->header.length = cpu_to_le16(sizeof(*cmd)); in mwl8k_cmd_update_stadb_del()
4579 cmd->action = cpu_to_le32(MWL8K_STA_DB_DEL_ENTRY); in mwl8k_cmd_update_stadb_del()
4580 memcpy(cmd->peer_addr, addr, ETH_ALEN); in mwl8k_cmd_update_stadb_del()
4582 rc = mwl8k_post_cmd(hw, &cmd->header); in mwl8k_cmd_update_stadb_del()
4595 struct mwl8k_priv *priv = hw->priv; in mwl8k_interrupt()
4598 status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); in mwl8k_interrupt()
4604 tasklet_schedule(&priv->poll_tx_task); in mwl8k_interrupt()
4609 tasklet_schedule(&priv->poll_rx_task); in mwl8k_interrupt()
4614 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); in mwl8k_interrupt()
4616 atomic_inc(&priv->watchdog_event_pending); in mwl8k_interrupt()
4618 ieee80211_queue_work(hw, &priv->watchdog_ba_handle); in mwl8k_interrupt()
4622 iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); in mwl8k_interrupt()
4625 if (priv->hostcmd_wait != NULL) in mwl8k_interrupt()
4626 complete(priv->hostcmd_wait); in mwl8k_interrupt()
4630 if (!mutex_is_locked(&priv->fw_mutex) && in mwl8k_interrupt()
4631 priv->radio_on && priv->pending_tx_pkts) in mwl8k_interrupt()
4641 struct ieee80211_hw *hw = pci_get_drvdata(priv->pdev); in mwl8k_tx_poll()
4642 int limit; in mwl8k_tx_poll() local
4645 limit = 32; in mwl8k_tx_poll()
4647 spin_lock(&priv->tx_lock); in mwl8k_tx_poll()
4650 limit -= mwl8k_txq_reclaim(hw, i, limit, 0); in mwl8k_tx_poll()
4652 if (!priv->pending_tx_pkts && priv->tx_wait != NULL) { in mwl8k_tx_poll()
4653 complete(priv->tx_wait); in mwl8k_tx_poll()
4654 priv->tx_wait = NULL; in mwl8k_tx_poll()
4657 spin_unlock(&priv->tx_lock); in mwl8k_tx_poll()
4659 if (limit) { in mwl8k_tx_poll()
4661 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); in mwl8k_tx_poll()
4663 tasklet_schedule(&priv->poll_tx_task); in mwl8k_tx_poll()
4670 struct ieee80211_hw *hw = pci_get_drvdata(priv->pdev); in mwl8k_rx_poll()
4671 int limit; in mwl8k_rx_poll() local
4673 limit = 32; in mwl8k_rx_poll()
4674 limit -= rxq_process(hw, 0, limit); in mwl8k_rx_poll()
4675 limit -= rxq_refill(hw, 0, limit); in mwl8k_rx_poll()
4677 if (limit) { in mwl8k_rx_poll()
4679 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); in mwl8k_rx_poll()
4681 tasklet_schedule(&priv->poll_rx_task); in mwl8k_rx_poll()
4693 struct mwl8k_priv *priv = hw->priv; in mwl8k_tx()
4696 if (!priv->radio_on) { in mwl8k_tx()
4697 wiphy_debug(hw->wiphy, in mwl8k_tx()
4703 mwl8k_txq_xmit(hw, index, control->sta, skb); in mwl8k_tx()
4708 struct mwl8k_priv *priv = hw->priv; in mwl8k_start()
4711 rc = request_irq(priv->pdev->irq, mwl8k_interrupt, in mwl8k_start()
4714 priv->irq = -1; in mwl8k_start()
4715 wiphy_err(hw->wiphy, "failed to register IRQ handler\n"); in mwl8k_start()
4716 return -EIO; in mwl8k_start()
4718 priv->irq = priv->pdev->irq; in mwl8k_start()
4721 tasklet_enable(&priv->poll_tx_task); in mwl8k_start()
4722 tasklet_enable(&priv->poll_rx_task); in mwl8k_start()
4725 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_start()
4727 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); in mwl8k_start()
4733 if (!priv->ap_fw) { in mwl8k_start()
4755 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_start()
4756 free_irq(priv->pdev->irq, hw); in mwl8k_start()
4757 priv->irq = -1; in mwl8k_start()
4758 tasklet_disable(&priv->poll_tx_task); in mwl8k_start()
4759 tasklet_disable(&priv->poll_rx_task); in mwl8k_start()
4769 struct mwl8k_priv *priv = hw->priv; in mwl8k_stop()
4772 if (!priv->hw_restart_in_progress) in mwl8k_stop()
4778 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_stop()
4779 if (priv->irq != -1) { in mwl8k_stop()
4780 free_irq(priv->pdev->irq, hw); in mwl8k_stop()
4781 priv->irq = -1; in mwl8k_stop()
4785 cancel_work_sync(&priv->finalize_join_worker); in mwl8k_stop()
4786 cancel_work_sync(&priv->watchdog_ba_handle); in mwl8k_stop()
4787 if (priv->beacon_skb != NULL) in mwl8k_stop()
4788 dev_kfree_skb(priv->beacon_skb); in mwl8k_stop()
4791 tasklet_disable(&priv->poll_tx_task); in mwl8k_stop()
4792 tasklet_disable(&priv->poll_rx_task); in mwl8k_stop()
4804 struct mwl8k_priv *priv = hw->priv; in mwl8k_add_interface()
4815 if (priv->sniffer_enabled) { in mwl8k_add_interface()
4816 wiphy_info(hw->wiphy, in mwl8k_add_interface()
4818 return -EINVAL; in mwl8k_add_interface()
4821 di = priv->device_info; in mwl8k_add_interface()
4822 switch (vif->type) { in mwl8k_add_interface()
4824 if (!priv->ap_fw && di->fw_image_ap) { in mwl8k_add_interface()
4826 if (!list_empty(&priv->vif_list)) in mwl8k_add_interface()
4827 return -EBUSY; in mwl8k_add_interface()
4828 rc = mwl8k_reload_firmware(hw, di->fw_image_ap); in mwl8k_add_interface()
4832 macids_supported = priv->ap_macids_supported; in mwl8k_add_interface()
4835 if (priv->ap_fw && di->fw_image_sta) { in mwl8k_add_interface()
4836 if (!list_empty(&priv->vif_list)) { in mwl8k_add_interface()
4837 wiphy_warn(hw->wiphy, "AP interface is running.\n" in mwl8k_add_interface()
4844 di->fw_image_sta); in mwl8k_add_interface()
4849 macids_supported = priv->sta_macids_supported; in mwl8k_add_interface()
4852 return -EINVAL; in mwl8k_add_interface()
4855 macid = ffs(macids_supported & ~priv->macids_used); in mwl8k_add_interface()
4856 if (!macid--) in mwl8k_add_interface()
4857 return -EBUSY; in mwl8k_add_interface()
4862 mwl8k_vif->vif = vif; in mwl8k_add_interface()
4863 mwl8k_vif->macid = macid; in mwl8k_add_interface()
4864 mwl8k_vif->seqno = 0; in mwl8k_add_interface()
4865 memcpy(mwl8k_vif->bssid, vif->addr, ETH_ALEN); in mwl8k_add_interface()
4866 mwl8k_vif->is_hw_crypto_enabled = false; in mwl8k_add_interface()
4869 mwl8k_cmd_set_mac_addr(hw, vif, vif->addr); in mwl8k_add_interface()
4871 if (vif->type == NL80211_IFTYPE_AP) in mwl8k_add_interface()
4874 priv->macids_used |= 1 << mwl8k_vif->macid; in mwl8k_add_interface()
4875 list_add_tail(&mwl8k_vif->list, &priv->vif_list); in mwl8k_add_interface()
4882 /* Has ieee80211_restart_hw re-added the removed interfaces? */ in mwl8k_remove_vif()
4883 if (!priv->macids_used) in mwl8k_remove_vif()
4886 priv->macids_used &= ~(1 << vif->macid); in mwl8k_remove_vif()
4887 list_del(&vif->list); in mwl8k_remove_vif()
4893 struct mwl8k_priv *priv = hw->priv; in mwl8k_remove_interface()
4896 if (vif->type == NL80211_IFTYPE_AP) in mwl8k_remove_interface()
4897 mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr); in mwl8k_remove_interface()
4899 mwl8k_cmd_del_mac_addr(hw, vif, vif->addr); in mwl8k_remove_interface()
4908 struct ieee80211_hw *hw = priv->hw; in mwl8k_hw_restart_work()
4913 if (priv->hostcmd_wait != NULL) { in mwl8k_hw_restart_work()
4914 complete(priv->hostcmd_wait); in mwl8k_hw_restart_work()
4915 priv->hostcmd_wait = NULL; in mwl8k_hw_restart_work()
4918 priv->hw_restart_owner = current; in mwl8k_hw_restart_work()
4919 di = priv->device_info; in mwl8k_hw_restart_work()
4922 if (priv->ap_fw) in mwl8k_hw_restart_work()
4923 rc = mwl8k_reload_firmware(hw, di->fw_image_ap); in mwl8k_hw_restart_work()
4925 rc = mwl8k_reload_firmware(hw, di->fw_image_sta); in mwl8k_hw_restart_work()
4930 priv->hw_restart_owner = NULL; in mwl8k_hw_restart_work()
4931 priv->hw_restart_in_progress = false; in mwl8k_hw_restart_work()
4942 wiphy_err(hw->wiphy, "Firmware restarted successfully\n"); in mwl8k_hw_restart_work()
4948 wiphy_err(hw->wiphy, "Firmware restart failed\n"); in mwl8k_hw_restart_work()
4953 struct ieee80211_conf *conf = &hw->conf; in mwl8k_config()
4954 struct mwl8k_priv *priv = hw->priv; in mwl8k_config()
4961 if (conf->flags & IEEE80211_CONF_IDLE) in mwl8k_config()
4974 if (conf->power_level > 18) in mwl8k_config()
4975 conf->power_level = 18; in mwl8k_config()
4977 if (priv->ap_fw) { in mwl8k_config()
4979 if (conf->flags & IEEE80211_CONF_CHANGE_POWER) { in mwl8k_config()
4980 rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level); in mwl8k_config()
4987 rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level); in mwl8k_config()
5003 struct mwl8k_priv *priv = hw->priv; in mwl8k_bss_info_changed_sta()
5014 if ((changed & BSS_CHANGED_ASSOC) && !vif->bss_conf.assoc) in mwl8k_bss_info_changed_sta()
5015 priv->capture_beacon = false; in mwl8k_bss_info_changed_sta()
5020 if (vif->bss_conf.assoc) { in mwl8k_bss_info_changed_sta()
5025 ap = ieee80211_find_sta(vif, vif->bss_conf.bssid); in mwl8k_bss_info_changed_sta()
5031 if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) { in mwl8k_bss_info_changed_sta()
5032 ap_legacy_rates = ap->supp_rates[NL80211_BAND_2GHZ]; in mwl8k_bss_info_changed_sta()
5035 ap->supp_rates[NL80211_BAND_5GHZ] << 5; in mwl8k_bss_info_changed_sta()
5037 memcpy(ap_mcs_rates, &ap->ht_cap.mcs, 16); in mwl8k_bss_info_changed_sta()
5042 if (!priv->ap_fw) { in mwl8k_bss_info_changed_sta()
5058 idx = ffs(vif->bss_conf.basic_rates); in mwl8k_bss_info_changed_sta()
5060 idx--; in mwl8k_bss_info_changed_sta()
5062 if (hw->conf.chandef.chan->band == in mwl8k_bss_info_changed_sta()
5075 vif->bss_conf.use_short_preamble); in mwl8k_bss_info_changed_sta()
5080 if ((changed & BSS_CHANGED_ERP_SLOT) && !priv->ap_fw) { in mwl8k_bss_info_changed_sta()
5081 rc = mwl8k_cmd_set_slot(hw, vif->bss_conf.use_short_slot); in mwl8k_bss_info_changed_sta()
5086 if (vif->bss_conf.assoc && !priv->ap_fw && in mwl8k_bss_info_changed_sta()
5094 if (vif->bss_conf.assoc && in mwl8k_bss_info_changed_sta()
5100 memcpy(priv->capture_bssid, vif->bss_conf.bssid, ETH_ALEN); in mwl8k_bss_info_changed_sta()
5101 priv->capture_beacon = true; in mwl8k_bss_info_changed_sta()
5119 vif->bss_conf.use_short_preamble); in mwl8k_bss_info_changed_ap()
5130 * and management frames (such as probe responses -- in mwl8k_bss_info_changed_ap()
5133 idx = ffs(vif->bss_conf.basic_rates); in mwl8k_bss_info_changed_ap()
5135 idx--; in mwl8k_bss_info_changed_ap()
5137 if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) in mwl8k_bss_info_changed_ap()
5150 mwl8k_cmd_set_beacon(hw, vif, skb->data, skb->len); in mwl8k_bss_info_changed_ap()
5156 mwl8k_cmd_bss_start(hw, vif, info->enable_beacon); in mwl8k_bss_info_changed_ap()
5166 if (vif->type == NL80211_IFTYPE_STATION) in mwl8k_bss_info_changed()
5168 if (vif->type == NL80211_IFTYPE_AP) in mwl8k_bss_info_changed()
5194 struct mwl8k_priv *priv = hw->priv; in mwl8k_configure_filter_sniffer()
5201 if (!list_empty(&priv->vif_list)) { in mwl8k_configure_filter_sniffer()
5203 wiphy_info(hw->wiphy, in mwl8k_configure_filter_sniffer()
5208 if (!priv->sniffer_enabled) { in mwl8k_configure_filter_sniffer()
5211 priv->sniffer_enabled = true; in mwl8k_configure_filter_sniffer()
5223 if (!list_empty(&priv->vif_list)) in mwl8k_first_vif()
5224 return list_entry(priv->vif_list.next, struct mwl8k_vif, list); in mwl8k_first_vif()
5234 struct mwl8k_priv *priv = hw->priv; in mwl8k_configure_filter()
5238 * AP firmware doesn't allow fine-grained control over in mwl8k_configure_filter()
5241 if (priv->ap_fw) { in mwl8k_configure_filter()
5265 if (priv->sniffer_enabled) { in mwl8k_configure_filter()
5267 priv->sniffer_enabled = false; in mwl8k_configure_filter()
5290 bssid = mwl8k_vif->vif->bss_conf.bssid; in mwl8k_configure_filter()
5300 * packet that ->prepare_multicast() built and replace it with in mwl8k_configure_filter()
5326 struct mwl8k_priv *priv = hw->priv; in mwl8k_sta_remove()
5328 if (priv->ap_fw) in mwl8k_sta_remove()
5329 return mwl8k_cmd_set_new_stn_del(hw, vif, sta->addr); in mwl8k_sta_remove()
5331 return mwl8k_cmd_update_stadb_del(hw, vif, sta->addr); in mwl8k_sta_remove()
5338 struct mwl8k_priv *priv = hw->priv; in mwl8k_sta_add()
5344 if (!priv->ap_fw) { in mwl8k_sta_add()
5347 MWL8K_STA(sta)->peer_id = ret; in mwl8k_sta_add()
5348 if (sta->ht_cap.ht_supported) in mwl8k_sta_add()
5349 MWL8K_STA(sta)->is_ampdu_allowed = true; in mwl8k_sta_add()
5358 key = IEEE80211_KEY_CONF(mwl8k_vif->wep_key_conf[i].key); in mwl8k_sta_add()
5359 if (mwl8k_vif->wep_key_conf[i].enabled) in mwl8k_sta_add()
5369 struct mwl8k_priv *priv = hw->priv; in mwl8k_conf_tx()
5374 BUG_ON(queue > MWL8K_TX_WMM_QUEUES - 1); in mwl8k_conf_tx()
5375 memcpy(&priv->wmm_params[queue], params, sizeof(*params)); in mwl8k_conf_tx()
5377 if (!priv->wmm_enabled) in mwl8k_conf_tx()
5381 int q = MWL8K_TX_WMM_QUEUES - 1 - queue; in mwl8k_conf_tx()
5383 params->cw_min, in mwl8k_conf_tx()
5384 params->cw_max, in mwl8k_conf_tx()
5385 params->aifs, in mwl8k_conf_tx()
5386 params->txop); in mwl8k_conf_tx()
5404 struct mwl8k_priv *priv = hw->priv; in mwl8k_get_survey()
5405 struct ieee80211_conf *conf = &hw->conf; in mwl8k_get_survey()
5408 if (priv->ap_fw) { in mwl8k_get_survey()
5409 sband = hw->wiphy->bands[NL80211_BAND_2GHZ]; in mwl8k_get_survey()
5411 if (sband && idx >= sband->n_channels) { in mwl8k_get_survey()
5412 idx -= sband->n_channels; in mwl8k_get_survey()
5417 sband = hw->wiphy->bands[NL80211_BAND_5GHZ]; in mwl8k_get_survey()
5419 if (!sband || idx >= sband->n_channels) in mwl8k_get_survey()
5420 return -ENOENT; in mwl8k_get_survey()
5422 memcpy(survey, &priv->survey[idx], sizeof(*survey)); in mwl8k_get_survey()
5423 survey->channel = &sband->channels[idx]; in mwl8k_get_survey()
5429 return -ENOENT; in mwl8k_get_survey()
5431 survey->channel = conf->chandef.chan; in mwl8k_get_survey()
5432 survey->filled = SURVEY_INFO_NOISE_DBM; in mwl8k_get_survey()
5433 survey->noise = priv->noise; in mwl8k_get_survey()
5444 struct ieee80211_sta *sta = params->sta; in mwl8k_ampdu_action()
5445 enum ieee80211_ampdu_mlme_action action = params->action; in mwl8k_ampdu_action()
5446 u16 tid = params->tid; in mwl8k_ampdu_action()
5447 u16 *ssn = &params->ssn; in mwl8k_ampdu_action()
5448 u8 buf_size = params->buf_size; in mwl8k_ampdu_action()
5450 struct mwl8k_priv *priv = hw->priv; in mwl8k_ampdu_action()
5452 u8 *addr = sta->addr, idx; in mwl8k_ampdu_action()
5456 return -ENOTSUPP; in mwl8k_ampdu_action()
5458 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5482 wiphy_warn(hw->wiphy, "Unexpected call to %s. " in mwl8k_ampdu_action()
5487 wiphy_debug(hw->wiphy, "no free AMPDU streams\n"); in mwl8k_ampdu_action()
5488 rc = -EBUSY; in mwl8k_ampdu_action()
5491 stream->state = AMPDU_STREAM_IN_PROGRESS; in mwl8k_ampdu_action()
5494 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5498 if (!sta_info->is_ampdu_allowed) { in mwl8k_ampdu_action()
5499 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5501 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5502 return -EBUSY; in mwl8k_ampdu_action()
5508 * return -EBUSY. Avoid retrying mwl8k_check_ba in in mwl8k_ampdu_action()
5511 if (!rc || rc == -EBUSY) in mwl8k_ampdu_action()
5520 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5522 wiphy_err(hw->wiphy, "Stream for tid %d busy after %d" in mwl8k_ampdu_action()
5525 rc = -EBUSY; in mwl8k_ampdu_action()
5534 if (stream->state == AMPDU_STREAM_ACTIVE) { in mwl8k_ampdu_action()
5535 idx = stream->idx; in mwl8k_ampdu_action()
5536 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5538 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5546 BUG_ON(stream->state != AMPDU_STREAM_IN_PROGRESS); in mwl8k_ampdu_action()
5547 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5549 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5551 stream->state = AMPDU_STREAM_ACTIVE; in mwl8k_ampdu_action()
5553 idx = stream->idx; in mwl8k_ampdu_action()
5554 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5556 spin_lock(&priv->stream_lock); in mwl8k_ampdu_action()
5557 wiphy_debug(hw->wiphy, in mwl8k_ampdu_action()
5565 rc = -ENOTSUPP; in mwl8k_ampdu_action()
5568 spin_unlock(&priv->stream_lock); in mwl8k_ampdu_action()
5576 struct mwl8k_priv *priv = hw->priv; in mwl8k_sw_scan_start()
5579 if (!priv->ap_fw) in mwl8k_sw_scan_start()
5583 priv->channel_time = 0; in mwl8k_sw_scan_start()
5584 ioread32(priv->regs + BBU_RXRDY_CNT_REG); in mwl8k_sw_scan_start()
5585 ioread32(priv->regs + NOK_CCA_CNT_REG); in mwl8k_sw_scan_start()
5586 mwl8k_cmd_bbp_reg_access(priv->hw, 0, BBU_AVG_NOISE_VAL, &tmp); in mwl8k_sw_scan_start()
5588 priv->sw_scan_start = true; in mwl8k_sw_scan_start()
5594 struct mwl8k_priv *priv = hw->priv; in mwl8k_sw_scan_complete()
5597 if (!priv->ap_fw) in mwl8k_sw_scan_complete()
5600 priv->sw_scan_start = false; in mwl8k_sw_scan_complete()
5603 priv->channel_time = 0; in mwl8k_sw_scan_complete()
5604 ioread32(priv->regs + BBU_RXRDY_CNT_REG); in mwl8k_sw_scan_complete()
5605 ioread32(priv->regs + NOK_CCA_CNT_REG); in mwl8k_sw_scan_complete()
5606 mwl8k_cmd_bbp_reg_access(priv->hw, 0, BBU_AVG_NOISE_VAL, &tmp); in mwl8k_sw_scan_complete()
5635 struct sk_buff *skb = priv->beacon_skb; in mwl8k_finalize_join_worker()
5636 struct ieee80211_mgmt *mgmt = (void *)skb->data; in mwl8k_finalize_join_worker()
5637 int len = skb->len - offsetof(struct ieee80211_mgmt, u.beacon.variable); in mwl8k_finalize_join_worker()
5639 mgmt->u.beacon.variable, len); in mwl8k_finalize_join_worker()
5645 mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, dtim_period); in mwl8k_finalize_join_worker()
5648 priv->beacon_skb = NULL; in mwl8k_finalize_join_worker()
5659 #define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw"
5663 #define _MWL8K_8764_AP_FW(api) "mwl8k/fmimage_8764_ap-" #api ".fw"
5720 "Trying alternative firmware %s\n", pci_name(priv->pdev), in mwl8k_request_alt_fw()
5721 priv->fw_pref, priv->fw_alt); in mwl8k_request_alt_fw()
5722 rc = mwl8k_request_fw(priv, priv->fw_alt, &priv->fw_ucode, true); in mwl8k_request_alt_fw()
5725 pci_name(priv->pdev), priv->fw_alt); in mwl8k_request_alt_fw()
5735 struct mwl8k_device_info *di = priv->device_info; in mwl8k_fw_state_machine()
5738 switch (priv->fw_state) { in mwl8k_fw_state_machine()
5742 pci_name(priv->pdev), di->helper_image); in mwl8k_fw_state_machine()
5745 priv->fw_helper = fw; in mwl8k_fw_state_machine()
5746 rc = mwl8k_request_fw(priv, priv->fw_pref, &priv->fw_ucode, in mwl8k_fw_state_machine()
5748 if (rc && priv->fw_alt) { in mwl8k_fw_state_machine()
5752 priv->fw_state = FW_STATE_LOADING_ALT; in mwl8k_fw_state_machine()
5756 priv->fw_state = FW_STATE_LOADING_PREF; in mwl8k_fw_state_machine()
5761 if (priv->fw_alt) { in mwl8k_fw_state_machine()
5765 priv->fw_state = FW_STATE_LOADING_ALT; in mwl8k_fw_state_machine()
5769 priv->fw_ucode = fw; in mwl8k_fw_state_machine()
5774 complete(&priv->firmware_loading_complete); in mwl8k_fw_state_machine()
5781 pci_name(priv->pdev), di->helper_image); in mwl8k_fw_state_machine()
5784 priv->fw_ucode = fw; in mwl8k_fw_state_machine()
5789 complete(&priv->firmware_loading_complete); in mwl8k_fw_state_machine()
5794 MWL8K_NAME, priv->fw_state); in mwl8k_fw_state_machine()
5801 priv->fw_state = FW_STATE_ERROR; in mwl8k_fw_state_machine()
5802 complete(&priv->firmware_loading_complete); in mwl8k_fw_state_machine()
5803 device_release_driver(&priv->pdev->dev); in mwl8k_fw_state_machine()
5811 struct mwl8k_priv *priv = hw->priv; in mwl8k_init_firmware()
5822 wiphy_err(hw->wiphy, "Firmware files not found\n"); in mwl8k_init_firmware()
5832 wiphy_err(hw->wiphy, "Cannot start firmware\n"); in mwl8k_init_firmware()
5841 count--; in mwl8k_init_firmware()
5842 wiphy_err(hw->wiphy, "Trying to reload the firmware again\n"); in mwl8k_init_firmware()
5852 struct mwl8k_priv *priv = hw->priv; in mwl8k_init_txqs()
5860 if (priv->ap_fw) in mwl8k_init_txqs()
5861 iowrite32(priv->txq[i].txd_dma, in mwl8k_init_txqs()
5862 priv->sram + priv->txq_offset[i]); in mwl8k_init_txqs()
5870 struct mwl8k_priv *priv = hw->priv; in mwl8k_probe_hw()
5874 if (priv->ap_fw) { in mwl8k_probe_hw()
5875 priv->rxd_ops = priv->device_info->ap_rxd_ops; in mwl8k_probe_hw()
5876 if (priv->rxd_ops == NULL) { in mwl8k_probe_hw()
5877 wiphy_err(hw->wiphy, in mwl8k_probe_hw()
5879 rc = -ENOENT; in mwl8k_probe_hw()
5883 priv->rxd_ops = &rxd_sta_ops; in mwl8k_probe_hw()
5886 priv->sniffer_enabled = false; in mwl8k_probe_hw()
5887 priv->wmm_enabled = false; in mwl8k_probe_hw()
5888 priv->pending_tx_pkts = 0; in mwl8k_probe_hw()
5889 atomic_set(&priv->watchdog_event_pending, 0); in mwl8k_probe_hw()
5902 priv->num_ampdu_queues = 0; in mwl8k_probe_hw()
5903 if (!priv->ap_fw) { in mwl8k_probe_hw()
5909 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); in mwl8k_probe_hw()
5910 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_probe_hw()
5913 priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); in mwl8k_probe_hw()
5915 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); in mwl8k_probe_hw()
5917 rc = request_irq(priv->pdev->irq, mwl8k_interrupt, in mwl8k_probe_hw()
5920 wiphy_err(hw->wiphy, "failed to register IRQ handler\n"); in mwl8k_probe_hw()
5930 if (!priv->hw_restart_in_progress) in mwl8k_probe_hw()
5931 memset(priv->ampdu, 0, sizeof(priv->ampdu)); in mwl8k_probe_hw()
5938 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_probe_hw()
5941 if (priv->ap_fw) { in mwl8k_probe_hw()
5951 wiphy_err(hw->wiphy, "Cannot initialise firmware\n"); in mwl8k_probe_hw()
5958 wiphy_err(hw->wiphy, "Cannot disable\n"); in mwl8k_probe_hw()
5965 wiphy_err(hw->wiphy, "Cannot clear MAC address\n"); in mwl8k_probe_hw()
5972 wiphy_warn(hw->wiphy, "failed to set # of RX antennas"); in mwl8k_probe_hw()
5975 wiphy_warn(hw->wiphy, "failed to set # of TX antennas"); in mwl8k_probe_hw()
5979 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_probe_hw()
5980 free_irq(priv->pdev->irq, hw); in mwl8k_probe_hw()
5982 wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n", in mwl8k_probe_hw()
5983 priv->device_info->part_name, in mwl8k_probe_hw()
5984 priv->hw_rev, hw->wiphy->perm_addr, in mwl8k_probe_hw()
5985 priv->ap_fw ? "AP" : "STA", in mwl8k_probe_hw()
5986 (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff, in mwl8k_probe_hw()
5987 (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff); in mwl8k_probe_hw()
5992 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); in mwl8k_probe_hw()
5993 free_irq(priv->pdev->irq, hw); in mwl8k_probe_hw()
6013 struct mwl8k_priv *priv = hw->priv; in mwl8k_reload_firmware()
6020 * All the existing interfaces are re-added by the ieee80211_reconfig; in mwl8k_reload_firmware()
6024 if (priv->hw_restart_in_progress) in mwl8k_reload_firmware()
6025 list_for_each_entry_safe(vif, tmp_vif, &priv->vif_list, list) in mwl8k_reload_firmware()
6039 if (priv->hw_restart_in_progress) in mwl8k_reload_firmware()
6051 rc = mwl8k_conf_tx(hw, NULL, i, &priv->wmm_params[i]); in mwl8k_reload_firmware()
6078 struct ieee80211_hw *hw = priv->hw; in mwl8k_firmware_load_success()
6084 wiphy_err(hw->wiphy, "Cannot start firmware\n"); in mwl8k_firmware_load_success()
6092 hw->extra_tx_headroom = in mwl8k_firmware_load_success()
6093 sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts); in mwl8k_firmware_load_success()
6095 hw->extra_tx_headroom -= priv->ap_fw ? REDUCED_TX_HEADROOM : 0; in mwl8k_firmware_load_success()
6097 hw->queues = MWL8K_TX_WMM_QUEUES; in mwl8k_firmware_load_success()
6107 if (priv->ap_fw) in mwl8k_firmware_load_success()
6110 hw->vif_data_size = sizeof(struct mwl8k_vif); in mwl8k_firmware_load_success()
6111 hw->sta_data_size = sizeof(struct mwl8k_sta); in mwl8k_firmware_load_success()
6113 priv->macids_used = 0; in mwl8k_firmware_load_success()
6114 INIT_LIST_HEAD(&priv->vif_list); in mwl8k_firmware_load_success()
6117 priv->radio_on = false; in mwl8k_firmware_load_success()
6118 priv->radio_short_preamble = false; in mwl8k_firmware_load_success()
6121 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); in mwl8k_firmware_load_success()
6123 INIT_WORK(&priv->watchdog_ba_handle, mwl8k_watchdog_ba_events); in mwl8k_firmware_load_success()
6125 INIT_WORK(&priv->fw_reload, mwl8k_hw_restart_work); in mwl8k_firmware_load_success()
6128 tasklet_setup(&priv->poll_tx_task, mwl8k_tx_poll); in mwl8k_firmware_load_success()
6129 tasklet_disable(&priv->poll_tx_task); in mwl8k_firmware_load_success()
6130 tasklet_setup(&priv->poll_rx_task, mwl8k_rx_poll); in mwl8k_firmware_load_success()
6131 tasklet_disable(&priv->poll_rx_task); in mwl8k_firmware_load_success()
6134 priv->cookie = dma_alloc_coherent(&priv->pdev->dev, 4, in mwl8k_firmware_load_success()
6135 &priv->cookie_dma, GFP_KERNEL); in mwl8k_firmware_load_success()
6136 if (priv->cookie == NULL) in mwl8k_firmware_load_success()
6137 return -ENOMEM; in mwl8k_firmware_load_success()
6139 mutex_init(&priv->fw_mutex); in mwl8k_firmware_load_success()
6140 priv->fw_mutex_owner = NULL; in mwl8k_firmware_load_success()
6141 priv->fw_mutex_depth = 0; in mwl8k_firmware_load_success()
6142 priv->hostcmd_wait = NULL; in mwl8k_firmware_load_success()
6144 spin_lock_init(&priv->tx_lock); in mwl8k_firmware_load_success()
6146 spin_lock_init(&priv->stream_lock); in mwl8k_firmware_load_success()
6148 priv->tx_wait = NULL; in mwl8k_firmware_load_success()
6154 hw->wiphy->interface_modes = 0; in mwl8k_firmware_load_success()
6156 if (priv->ap_macids_supported || priv->device_info->fw_image_ap) { in mwl8k_firmware_load_success()
6157 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); in mwl8k_firmware_load_success()
6158 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); in mwl8k_firmware_load_success()
6159 hw->wiphy->iface_combinations = &ap_if_comb; in mwl8k_firmware_load_success()
6160 hw->wiphy->n_iface_combinations = 1; in mwl8k_firmware_load_success()
6163 if (priv->sta_macids_supported || priv->device_info->fw_image_sta) in mwl8k_firmware_load_success()
6164 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); in mwl8k_firmware_load_success()
6166 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); in mwl8k_firmware_load_success()
6170 wiphy_err(hw->wiphy, "Cannot register device\n"); in mwl8k_firmware_load_success()
6182 if (priv->cookie != NULL) in mwl8k_firmware_load_success()
6183 dma_free_coherent(&priv->pdev->dev, 4, priv->cookie, in mwl8k_firmware_load_success()
6184 priv->cookie_dma); in mwl8k_firmware_load_success()
6222 printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME); in mwl8k_probe()
6223 rc = -ENOMEM; in mwl8k_probe()
6227 SET_IEEE80211_DEV(hw, &pdev->dev); in mwl8k_probe()
6230 priv = hw->priv; in mwl8k_probe()
6231 priv->hw = hw; in mwl8k_probe()
6232 priv->pdev = pdev; in mwl8k_probe()
6233 priv->device_info = &mwl8k_info_tbl[id->driver_data]; in mwl8k_probe()
6235 if (id->driver_data == MWL8764) in mwl8k_probe()
6236 priv->is_8764 = true; in mwl8k_probe()
6238 priv->sram = pci_iomap(pdev, 0, 0x10000); in mwl8k_probe()
6239 if (priv->sram == NULL) { in mwl8k_probe()
6240 wiphy_err(hw->wiphy, "Cannot map device SRAM\n"); in mwl8k_probe()
6241 rc = -EIO; in mwl8k_probe()
6249 priv->regs = pci_iomap(pdev, 1, 0x10000); in mwl8k_probe()
6250 if (priv->regs == NULL) { in mwl8k_probe()
6251 priv->regs = pci_iomap(pdev, 2, 0x10000); in mwl8k_probe()
6252 if (priv->regs == NULL) { in mwl8k_probe()
6253 wiphy_err(hw->wiphy, "Cannot map device registers\n"); in mwl8k_probe()
6254 rc = -EIO; in mwl8k_probe()
6264 init_completion(&priv->firmware_loading_complete); in mwl8k_probe()
6265 di = priv->device_info; in mwl8k_probe()
6266 if (ap_mode_default && di->fw_image_ap) { in mwl8k_probe()
6267 priv->fw_pref = di->fw_image_ap; in mwl8k_probe()
6268 priv->fw_alt = di->fw_image_sta; in mwl8k_probe()
6269 } else if (!ap_mode_default && di->fw_image_sta) { in mwl8k_probe()
6270 priv->fw_pref = di->fw_image_sta; in mwl8k_probe()
6271 priv->fw_alt = di->fw_image_ap; in mwl8k_probe()
6272 } else if (ap_mode_default && !di->fw_image_ap && di->fw_image_sta) { in mwl8k_probe()
6274 priv->fw_pref = di->fw_image_sta; in mwl8k_probe()
6275 } else if (!ap_mode_default && !di->fw_image_sta && di->fw_image_ap) { in mwl8k_probe()
6277 priv->fw_pref = di->fw_image_ap; in mwl8k_probe()
6279 rc = mwl8k_init_firmware(hw, priv->fw_pref, true); in mwl8k_probe()
6283 priv->hw_restart_in_progress = false; in mwl8k_probe()
6285 priv->running_bsses = 0; in mwl8k_probe()
6293 if (priv->regs != NULL) in mwl8k_probe()
6294 pci_iounmap(pdev, priv->regs); in mwl8k_probe()
6296 if (priv->sram != NULL) in mwl8k_probe()
6297 pci_iounmap(pdev, priv->sram); in mwl8k_probe()
6318 priv = hw->priv; in mwl8k_remove()
6320 wait_for_completion(&priv->firmware_loading_complete); in mwl8k_remove()
6322 if (priv->fw_state == FW_STATE_ERROR) { in mwl8k_remove()
6332 tasklet_kill(&priv->poll_tx_task); in mwl8k_remove()
6333 tasklet_kill(&priv->poll_rx_task); in mwl8k_remove()
6347 dma_free_coherent(&priv->pdev->dev, 4, priv->cookie, priv->cookie_dma); in mwl8k_remove()
6350 pci_iounmap(pdev, priv->regs); in mwl8k_remove()
6351 pci_iounmap(pdev, priv->sram); in mwl8k_remove()