14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/sched.h>
18 #include <linux/list.h>
19 #include <linux/pci.h>
23 #include <linux/slab.h>
29 #define MWL8K_DESC "Marvell TOPDOG(R) 802.11 Wireless Network Driver"
30 #define MWL8K_NAME KBUILD_MODNAME
31 #define MWL8K_VERSION "0.13"
34 static bool ap_mode_default;
37 "Set to 1 to make ap mode the default instead of sta mode");
40 #define MWL8K_HIU_GEN_PTR 0x00000c10
41 #define MWL8K_MODE_STA 0x0000005a
42 #define MWL8K_MODE_AP 0x000000a5
43 #define MWL8K_HIU_INT_CODE 0x00000c14
44 #define MWL8K_FWSTA_READY 0xf0f1f2f4
45 #define MWL8K_FWAP_READY 0xf1f2f4a5
46 #define MWL8K_INT_CODE_CMD_FINISHED 0x00000005
47 #define MWL8K_HIU_SCRATCH 0x00000c40
50 #define MWL8K_HIU_H2A_INTERRUPT_EVENTS 0x00000c18
51 #define MWL8K_HIU_H2A_INTERRUPT_STATUS 0x00000c1c
52 #define MWL8K_HIU_H2A_INTERRUPT_MASK 0x00000c20
53 #define MWL8K_HIU_H2A_INTERRUPT_CLEAR_SEL 0x00000c24
54 #define MWL8K_HIU_H2A_INTERRUPT_STATUS_MASK 0x00000c28
55 #define MWL8K_H2A_INT_DUMMY (1 << 20)
56 #define MWL8K_H2A_INT_RESET (1 << 15)
57 #define MWL8K_H2A_INT_DOORBELL (1 << 1)
58 #define MWL8K_H2A_INT_PPA_READY (1 << 0)
61 #define MWL8K_HIU_A2H_INTERRUPT_EVENTS 0x00000c2c
62 #define MWL8K_HIU_A2H_INTERRUPT_STATUS 0x00000c30
63 #define MWL8K_HIU_A2H_INTERRUPT_MASK 0x00000c34
64 #define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL 0x00000c38
65 #define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK 0x00000c3c
66 #define MWL8K_A2H_INT_DUMMY (1 << 20)
67 #define MWL8K_A2H_INT_BA_WATCHDOG (1 << 14)
68 #define MWL8K_A2H_INT_CHNL_SWITCHED (1 << 11)
69 #define MWL8K_A2H_INT_QUEUE_EMPTY (1 << 10)
70 #define MWL8K_A2H_INT_RADAR_DETECT (1 << 7)
71 #define MWL8K_A2H_INT_RADIO_ON (1 << 6)
72 #define MWL8K_A2H_INT_RADIO_OFF (1 << 5)
73 #define MWL8K_A2H_INT_MAC_EVENT (1 << 3)
74 #define MWL8K_A2H_INT_OPC_DONE (1 << 2)
75 #define MWL8K_A2H_INT_RX_READY (1 << 1)
76 #define MWL8K_A2H_INT_TX_DONE (1 << 0)
84 #define MWL8K_HW_TIMER_REGISTER 0x0000a600
86 #define MWL8K_A2H_EVENTS (MWL8K_A2H_INT_DUMMY | \
87 MWL8K_A2H_INT_CHNL_SWITCHED | \
88 MWL8K_A2H_INT_QUEUE_EMPTY | \
89 MWL8K_A2H_INT_RADAR_DETECT | \
90 MWL8K_A2H_INT_RADIO_ON | \
91 MWL8K_A2H_INT_RADIO_OFF | \
92 MWL8K_A2H_INT_MAC_EVENT | \
93 MWL8K_A2H_INT_OPC_DONE | \
94 MWL8K_A2H_INT_RX_READY | \
95 MWL8K_A2H_INT_TX_DONE | \
96 MWL8K_A2H_INT_BA_WATCHDOG)
98 #define MWL8K_RX_QUEUES 1
99 #define MWL8K_TX_WMM_QUEUES 4
100 #define MWL8K_MAX_AMPDU_QUEUES 8
101 #define MWL8K_MAX_TX_QUEUES (MWL8K_TX_WMM_QUEUES + MWL8K_MAX_AMPDU_QUEUES)
102 #define mwl8k_tx_queues(priv) (MWL8K_TX_WMM_QUEUES + (priv)->num_ampdu_queues)
277 #define MAX_WEP_KEY_LEN 13
278 #define NUM_WEP_KEYS 4
303 #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
304 #define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8))
311 #define MWL8K_MAX_TID 8
318 #define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))
321 { .center_freq = 2412, .hw_value = 1, },
322 { .center_freq = 2417, .hw_value = 2, },
323 { .center_freq = 2422, .hw_value = 3, },
324 { .center_freq = 2427, .hw_value = 4, },
325 { .center_freq = 2432, .hw_value = 5, },
326 { .center_freq = 2437, .hw_value = 6, },
327 { .center_freq = 2442, .hw_value = 7, },
328 { .center_freq = 2447, .hw_value = 8, },
329 { .center_freq = 2452, .hw_value = 9, },
330 { .center_freq = 2457, .hw_value = 10, },
331 { .center_freq = 2462, .hw_value = 11, },
332 { .center_freq = 2467, .hw_value = 12, },
333 { .center_freq = 2472, .hw_value = 13, },
334 { .center_freq = 2484, .hw_value = 14, },
338 { .bitrate = 10, .hw_value = 2, },
339 { .bitrate = 20, .hw_value = 4, },
340 { .bitrate = 55, .hw_value = 11, },
341 { .bitrate = 110, .hw_value = 22, },
342 { .bitrate = 220, .hw_value = 44, },
343 { .bitrate = 60, .hw_value = 12, },
344 { .bitrate = 90, .hw_value = 18, },
345 { .bitrate = 120, .hw_value = 24, },
346 { .bitrate = 180, .hw_value = 36, },
347 { .bitrate = 240, .hw_value = 48, },
348 { .bitrate = 360, .hw_value = 72, },
349 { .bitrate = 480, .hw_value = 96, },
350 { .bitrate = 540, .hw_value = 108, },
351 { .bitrate = 720, .hw_value = 144, },
355 { .center_freq = 5180, .hw_value = 36, },
356 { .center_freq = 5200, .hw_value = 40, },
357 { .center_freq = 5220, .hw_value = 44, },
358 { .center_freq = 5240, .hw_value = 48, },
362 { .bitrate = 60, .hw_value = 12, },
363 { .bitrate = 90, .hw_value = 18, },
364 { .bitrate = 120, .hw_value = 24, },
365 { .bitrate = 180, .hw_value = 36, },
366 { .bitrate = 240, .hw_value = 48, },
367 { .bitrate = 360, .hw_value = 72, },
368 { .bitrate = 480, .hw_value = 96, },
369 { .bitrate = 540, .hw_value = 108, },
370 { .bitrate = 720, .hw_value = 144, },
374 #define MWL8K_CMD_GET 0x0000
375 #define MWL8K_CMD_SET 0x0001
376 #define MWL8K_CMD_SET_LIST 0x0002
379 #define MWL8K_CMD_CODE_DNLD 0x0001
380 #define MWL8K_CMD_GET_HW_SPEC 0x0003
381 #define MWL8K_CMD_SET_HW_SPEC 0x0004
382 #define MWL8K_CMD_MAC_MULTICAST_ADR 0x0010
383 #define MWL8K_CMD_GET_STAT 0x0014
384 #define MWL8K_CMD_RADIO_CONTROL 0x001c
385 #define MWL8K_CMD_RF_TX_POWER 0x001e
386 #define MWL8K_CMD_TX_POWER 0x001f
387 #define MWL8K_CMD_RF_ANTENNA 0x0020
388 #define MWL8K_CMD_SET_BEACON 0x0100
389 #define MWL8K_CMD_SET_PRE_SCAN 0x0107
390 #define MWL8K_CMD_SET_POST_SCAN 0x0108
391 #define MWL8K_CMD_SET_RF_CHANNEL 0x010a
392 #define MWL8K_CMD_SET_AID 0x010d
393 #define MWL8K_CMD_SET_RATE 0x0110
394 #define MWL8K_CMD_SET_FINALIZE_JOIN 0x0111
395 #define MWL8K_CMD_RTS_THRESHOLD 0x0113
396 #define MWL8K_CMD_SET_SLOT 0x0114
397 #define MWL8K_CMD_SET_EDCA_PARAMS 0x0115
398 #define MWL8K_CMD_SET_WMM_MODE 0x0123
399 #define MWL8K_CMD_MIMO_CONFIG 0x0125
400 #define MWL8K_CMD_USE_FIXED_RATE 0x0126
401 #define MWL8K_CMD_ENABLE_SNIFFER 0x0150
402 #define MWL8K_CMD_SET_MAC_ADDR 0x0202
403 #define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203
404 #define MWL8K_CMD_GET_WATCHDOG_BITMAP 0x0205
405 #define MWL8K_CMD_DEL_MAC_ADDR 0x0206
406 #define MWL8K_CMD_BSS_START 0x1100
407 #define MWL8K_CMD_SET_NEW_STN 0x1111
408 #define MWL8K_CMD_UPDATE_ENCRYPTION 0x1122
409 #define MWL8K_CMD_UPDATE_STADB 0x1123
410 #define MWL8K_CMD_BASTREAM 0x1125
416 #define MWL8K_CMDNAME(x) case MWL8K_CMD_##x: do {\
417 snprintf(buf, bufsize, "%s", #x);\
420 switch (command & ~0x8000) {
453 snprintf(buf, bufsize,
"0x%x", cmd);
471 static void mwl8k_release_fw(
const struct firmware **
fw)
486 static void mwl8k_fw_state_machine(
const struct firmware *fw,
void *
context);
501 mwl8k_release_fw(fw);
506 priv, mwl8k_fw_state_machine);
538 rc = mwl8k_request_fw(priv, fw_image,
542 rc = mwl8k_request_fw(priv, fw_image,
546 pci_name(priv->
pdev), fw_image);
574 if (pci_dma_mapping_error(priv->
pdev, dma_addr))
603 static int mwl8k_load_fw_image(
struct mwl8k_priv *priv,
604 const u8 *data,
size_t length)
626 rc = mwl8k_send_fw_load_cmd(priv, cmd,
627 sizeof(*cmd) + block_size);
637 rc = mwl8k_send_fw_load_cmd(priv, cmd,
sizeof(*cmd));
645 static int mwl8k_feed_fw_image(
struct mwl8k_priv *priv,
646 const u8 *data,
size_t length)
649 int may_continue, rc = 0;
659 while (may_continue > 0) {
663 if (block_size & 1) {
667 done += prev_block_size;
668 length -= prev_block_size;
671 if (block_size > 1024 || block_size > length) {
681 if (block_size == 0) {
689 memcpy(buffer, data + done, block_size);
691 rc = mwl8k_send_fw_load_cmd(priv, buffer, block_size);
696 if (!rc && length != 0)
711 if (!
memcmp(fw->
data,
"\x01\x00\x00\x00", 4)) {
714 if (helper ==
NULL) {
716 "given\n", pci_name(priv->
pdev));
720 rc = mwl8k_load_fw_image(priv, helper->
data, helper->
size);
723 "helper image\n", pci_name(priv->
pdev));
728 rc = mwl8k_feed_fw_image(priv, fw->
data, fw->
size);
730 rc = mwl8k_load_fw_image(priv, fw->
data, fw->
size);
735 pci_name(priv->
pdev));
778 if (hdrlen !=
sizeof(tr->
wh)) {
779 if (ieee80211_is_data_qos(tr->
wh.frame_control)) {
787 if (hdrlen !=
sizeof(*tr))
788 skb_pull(skb,
sizeof(*tr) - hdrlen);
791 #define REDUCED_TX_HEADROOM 8
795 int head_pad,
int tail_pad)
821 "Failed to reallocate TX buffer\n");
827 reqd_hdrlen =
sizeof(*tr) + head_pad;
829 if (hdrlen != reqd_hdrlen)
830 skb_push(skb, reqd_hdrlen - hdrlen);
838 if (hdrlen !=
sizeof(tr->
wh))
839 memset(((
void *)&tr->
wh) + hdrlen, 0,
sizeof(tr->
wh) - hdrlen);
849 static void mwl8k_encapsulate_tx_frame(
struct mwl8k_priv *priv,
860 tx_info = IEEE80211_SKB_CB(skb);
864 key_conf = tx_info->
control.hw_key;
877 head_pad = key_conf->
iv_len;
878 switch (key_conf->
cipher) {
891 mwl8k_add_dma_header(priv, skb, head_pad, data_pad);
915 #define MWL8K_8366_AP_RATE_INFO_MCS_FORMAT 0x80
916 #define MWL8K_8366_AP_RATE_INFO_40MHZ 0x40
917 #define MWL8K_8366_AP_RATE_INFO_RATEID(x) ((x) & 0x3f)
919 #define MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST 0x80
922 #define MWL8K_8366_AP_RXSTAT_DECRYPT_ERR_MASK 0x80
923 #define MWL8K_8366_AP_RXSTAT_GENERAL_DECRYPT_ERR 0xFF
924 #define MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR 0x02
925 #define MWL8K_8366_AP_RXSTAT_WEP_DECRYPT_ICV_ERR 0x04
926 #define MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_ICV_ERR 0x08
928 static void mwl8k_rxd_8366_ap_init(
void *_rxd,
dma_addr_t next_dma_addr)
936 static void mwl8k_rxd_8366_ap_refill(
void *_rxd,
dma_addr_t addr,
int len)
956 memset(status, 0,
sizeof(*status));
969 for (i = 0; i <
ARRAY_SIZE(mwl8k_rates_24); i++) {
970 if (mwl8k_rates_24[i].hw_value == rxd->
rate) {
997 static struct rxd_ops rxd_8366_ap_ops = {
999 .rxd_init = mwl8k_rxd_8366_ap_init,
1000 .rxd_refill = mwl8k_rxd_8366_ap_refill,
1001 .rxd_process = mwl8k_rxd_8366_ap_process,
1024 #define MWL8K_STA_RATE_INFO_SHORTPRE 0x8000
1025 #define MWL8K_STA_RATE_INFO_ANTSELECT(x) (((x) >> 11) & 0x3)
1026 #define MWL8K_STA_RATE_INFO_RATEID(x) (((x) >> 3) & 0x3f)
1027 #define MWL8K_STA_RATE_INFO_40MHZ 0x0004
1028 #define MWL8K_STA_RATE_INFO_SHORTGI 0x0002
1029 #define MWL8K_STA_RATE_INFO_MCS_FORMAT 0x0001
1031 #define MWL8K_STA_RX_CTRL_OWNED_BY_HOST 0x02
1032 #define MWL8K_STA_RX_CTRL_DECRYPT_ERROR 0x04
1034 #define MWL8K_STA_RX_CTRL_DEC_ERR_TYPE 0x08
1036 #define MWL8K_STA_RX_CTRL_KEY_INDEX 0x30
1038 static void mwl8k_rxd_sta_init(
void *_rxd,
dma_addr_t next_dma_addr)
1046 static void mwl8k_rxd_sta_refill(
void *_rxd,
dma_addr_t addr,
int len)
1069 memset(status, 0,
sizeof(*status));
1103 static struct rxd_ops rxd_sta_ops = {
1105 .rxd_init = mwl8k_rxd_sta_init,
1106 .rxd_refill = mwl8k_rxd_sta_refill,
1107 .rxd_process = mwl8k_rxd_sta_process,
1111 #define MWL8K_RX_DESCS 256
1112 #define MWL8K_RX_MAXSZ 3800
1147 desc_size = priv->
rxd_ops->rxd_size;
1148 rxd = rxq->
rxd + (i * priv->
rxd_ops->rxd_size);
1151 if (nexti == MWL8K_RX_DESCS)
1153 next_dma_addr = rxq->
rxd_dma + (nexti * desc_size);
1155 priv->
rxd_ops->rxd_init(rxd, next_dma_addr);
1178 addr = pci_map_single(priv->
pdev, skb->
data,
1188 rxd = rxq->
rxd + (rx * priv->
rxd_ops->rxd_size);
1198 static void mwl8k_rxq_deinit(
struct ieee80211_hw *hw,
int index)
1208 if (rxq->
buf[i].skb !=
NULL) {
1209 pci_unmap_single(priv->
pdev,
1223 MWL8K_RX_DESCS * priv->
rxd_ops->rxd_size,
1241 static inline void mwl8k_save_beacon(
struct ieee80211_hw *hw,
1274 static int rxq_process(
struct ieee80211_hw *hw,
int index,
int limit)
1277 struct mwl8k_vif *mwl8k_vif =
NULL;
1290 skb = rxq->
buf[rxq->
head].skb;
1296 pkt_len = priv->
rxd_ops->rxd_process(rxd, &status, &qos,
1303 pci_unmap_single(priv->
pdev,
1309 if (rxq->
head == MWL8K_RX_DESCS)
1321 if (mwl8k_capture_bssid(priv, (
void *)skb->
data))
1322 mwl8k_save_beacon(hw, skb);
1330 mwl8k_vif = mwl8k_find_vif_bss(&priv->
vif_list,
1333 if (mwl8k_vif !=
NULL &&
1363 mwl8k_remove_dma_header(skb, qos);
1364 memcpy(IEEE80211_SKB_RXCB(skb), &status,
sizeof(status));
1378 #define MWL8K_TXD_STATUS_OK 0x00000001
1379 #define MWL8K_TXD_STATUS_OK_RETRY 0x00000002
1380 #define MWL8K_TXD_STATUS_OK_MORE_RETRY 0x00000004
1381 #define MWL8K_TXD_STATUS_MULTICAST_TX 0x00000008
1382 #define MWL8K_TXD_STATUS_FW_OWNED 0x80000000
1384 #define MWL8K_QOS_QLEN_UNSPEC 0xff00
1385 #define MWL8K_QOS_ACK_POLICY_MASK 0x0060
1386 #define MWL8K_QOS_ACK_POLICY_NORMAL 0x0000
1387 #define MWL8K_QOS_ACK_POLICY_BLOCKACK 0x0060
1388 #define MWL8K_QOS_EOSP 0x0010
1405 #define MWL8K_TX_DESCS 128
1407 static int mwl8k_txq_init(
struct ieee80211_hw *hw,
int index)
1438 tx_desc = txq->
txd +
i;
1439 nexti = (i + 1) % MWL8K_TX_DESCS;
1449 static inline void mwl8k_tx_start(
struct mwl8k_priv *priv)
1458 static void mwl8k_dump_tx_rings(
struct ieee80211_hw *hw)
1485 "txq[%d] len=%d head=%d tail=%d "
1486 "fw_owned=%d drv_owned=%d unused=%d\n",
1489 fw_owned, drv_owned, unused);
1496 #define MWL8K_TX_WAIT_TIMEOUT_MS 5000
1498 static int mwl8k_tx_wait_empty(
struct ieee80211_hw *hw)
1537 spin_unlock_bh(&priv->
tx_lock);
1551 "waiting for tx rings to drain (%d -> %d pkts)\n",
1561 mwl8k_dump_tx_rings(hw);
1567 spin_unlock_bh(&priv->
tx_lock);
1572 #define MWL8K_TXD_SUCCESS(status) \
1573 ((status) & (MWL8K_TXD_STATUS_OK | \
1574 MWL8K_TXD_STATUS_OK_RETRY | \
1575 MWL8K_TXD_STATUS_OK_MORE_RETRY))
1577 static int mwl8k_tid_queue_mapping(
u8 tid)
1609 #define RI_FORMAT(a) (a & 0x0001)
1610 #define RI_RATE_ID_MCS(a) ((a & 0x01f8) >> 3)
1620 while (txq->
len > 0 && limit--) {
1634 tx_desc = txq->
txd +
tx;
1645 txq->
head = (tx + 1) % MWL8K_TX_DESCS;
1658 mwl8k_remove_dma_header(skb, tx_desc->
qos_control);
1666 info = IEEE80211_SKB_CB(skb);
1690 ieee80211_tx_info_clear_status(info);
1695 info->
status.rates[0].idx = -1;
1696 info->
status.rates[0].count = 1;
1710 static void mwl8k_txq_deinit(
struct ieee80211_hw *hw,
int index)
1718 mwl8k_txq_reclaim(hw, index,
INT_MAX, 1);
1738 stream = &priv->
ampdu[
i];
1764 "%d\n", stream->
sta->addr, stream->
tid, ret);
1767 stream->
sta->addr, stream->
tid);
1776 memset(stream, 0,
sizeof(*stream));
1787 stream = &priv->
ampdu[
i];
1797 #define MWL8K_AMPDU_PACKET_THRESHOLD 64
1798 static inline bool mwl8k_ampdu_allowed(
struct ieee80211_sta *sta,
u8 tid)
1804 tx_stats = &sta_info->
tx_stats[tid];
1810 static inline void mwl8k_tx_count_packet(
struct ieee80211_sta *sta,
u8 tid)
1816 tx_stats = &sta_info->
tx_stats[tid];
1840 struct mwl8k_vif *mwl8k_vif;
1851 bool start_ba_session =
false;
1852 bool mgmtframe =
false;
1865 mwl8k_encapsulate_tx_frame(priv, skb);
1867 mwl8k_add_dma_header(priv, skb, 0, 0);
1871 tx_info = IEEE80211_SKB_CB(skb);
1877 mwl8k_vif->
seqno += 0x10;
1889 if (is_multicast_ether_addr(wh->
addr1))
1914 index = mwl8k_tid_queue_mapping(tid);
1919 if (priv->
ap_fw && sta && sta->
ht_cap.ht_supported
1923 mwl8k_tx_count_packet(sta, tid);
1925 stream = mwl8k_lookup_stream(hw, sta->
addr, tid);
1926 if (stream !=
NULL) {
1952 "Cannot send packet while ADDBA "
1953 "dialog is underway.\n");
1964 if (mwl8k_ampdu_allowed(sta, tid)) {
1965 stream = mwl8k_add_stream(hw, sta, tid);
1967 start_ba_session =
true;
1973 dma = pci_map_single(priv->
pdev, skb->
data,
1976 if (pci_dma_mapping_error(priv->
pdev, dma)) {
1978 "failed to dma map skb, dropping TX frame.\n");
1979 if (start_ba_session) {
1981 mwl8k_remove_stream(hw, stream);
2000 if (txq->
len >= MWL8K_TX_DESCS - 2) {
2001 if (!mgmtframe || txq->
len == MWL8K_TX_DESCS) {
2002 if (start_ba_session) {
2004 mwl8k_remove_stream(hw, stream);
2007 spin_unlock_bh(&priv->
tx_lock);
2039 if (txq->
tail == MWL8K_TX_DESCS)
2042 mwl8k_tx_start(priv);
2044 spin_unlock_bh(&priv->
tx_lock);
2047 if (start_ba_session) {
2049 if (mwl8k_start_stream(hw, stream))
2050 mwl8k_remove_stream(hw, stream);
2082 rc = mwl8k_tx_wait_empty(hw);
2119 #define MWL8K_CMD_TIMEOUT_MS 10000
2127 unsigned int dma_size;
2134 dma_addr = pci_map_single(priv->
pdev, cmd, dma_size,
2136 if (pci_dma_mapping_error(priv->
pdev, dma_addr))
2139 rc = mwl8k_fw_lock(hw);
2141 pci_unmap_single(priv->
pdev, dma_addr, dma_size,
2158 mwl8k_fw_unlock(hw);
2160 pci_unmap_single(priv->
pdev, dma_addr, dma_size,
2165 mwl8k_cmd_name(cmd->
code, buf,
sizeof(buf)),
2176 mwl8k_cmd_name(cmd->
code, buf,
sizeof(buf)),
2180 mwl8k_cmd_name(cmd->
code,
2188 static int mwl8k_post_pervif_cmd(
struct ieee80211_hw *hw,
2194 return mwl8k_post_cmd(hw, cmd);
2200 static void mwl8k_setup_2ghz_band(
struct ieee80211_hw *hw)
2219 static void mwl8k_setup_5ghz_band(
struct ieee80211_hw *hw)
2260 #define MWL8K_CAP_MAX_AMSDU 0x20000000
2261 #define MWL8K_CAP_GREENFIELD 0x08000000
2262 #define MWL8K_CAP_AMPDU 0x04000000
2263 #define MWL8K_CAP_RX_STBC 0x01000000
2264 #define MWL8K_CAP_TX_STBC 0x00800000
2265 #define MWL8K_CAP_SHORTGI_40MHZ 0x00400000
2266 #define MWL8K_CAP_SHORTGI_20MHZ 0x00200000
2267 #define MWL8K_CAP_RX_ANTENNA_MASK 0x000e0000
2268 #define MWL8K_CAP_TX_ANTENNA_MASK 0x0001c000
2269 #define MWL8K_CAP_DELAY_BA 0x00003000
2270 #define MWL8K_CAP_MIMO 0x00000200
2271 #define MWL8K_CAP_40MHZ 0x00000100
2272 #define MWL8K_CAP_BAND_MASK 0x00000007
2273 #define MWL8K_CAP_5GHZ 0x00000004
2274 #define MWL8K_CAP_2GHZ4 0x00000001
2283 band->
ht_cap.ht_supported = 1;
2310 band->
ht_cap.mcs.rx_mask[0] = 0xff;
2311 if (rx_streams >= 2)
2312 band->
ht_cap.mcs.rx_mask[1] = 0xff;
2313 if (rx_streams >= 3)
2314 band->
ht_cap.mcs.rx_mask[2] = 0xff;
2315 band->
ht_cap.mcs.rx_mask[4] = 0x01;
2318 if (rx_streams != tx_streams) {
2320 band->
ht_cap.mcs.tx_params |= (tx_streams - 1) <<
2331 mwl8k_setup_2ghz_band(hw);
2333 mwl8k_set_ht_caps(hw, &priv->
band_24, caps);
2337 mwl8k_setup_5ghz_band(hw);
2339 mwl8k_set_ht_caps(hw, &priv->
band_50, caps);
2366 rc = mwl8k_post_cmd(hw, &cmd->
header);
2369 SET_IEEE80211_PERM_ADDR(hw, cmd->
perm_addr);
2425 rc = mwl8k_post_cmd(hw, &cmd->
header);
2431 if (priv->
device_info->fw_api_ap != api_version) {
2440 SET_IEEE80211_PERM_ADDR(hw, cmd->
perm_addr);
2450 " but we only support %d.\n",
2504 #define MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY 0x00000400
2505 #define MWL8K_SET_HW_SPEC_FLAG_GENERATE_CCMP_HDR 0x00000200
2506 #define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080
2507 #define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020
2508 #define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON 0x00000010
2547 rc = mwl8k_post_cmd(hw, &cmd->
header);
2563 #define MWL8K_ENABLE_RX_DIRECTED 0x0001
2564 #define MWL8K_ENABLE_RX_MULTICAST 0x0002
2565 #define MWL8K_ENABLE_RX_ALL_MULTICAST 0x0004
2566 #define MWL8K_ENABLE_RX_BROADCAST 0x0008
2569 __mwl8k_cmd_mac_multicast_adr(
struct ieee80211_hw *hw,
int allmulti,
2585 size =
sizeof(*cmd) + mc_count *
ETH_ALEN;
2598 }
else if (mc_count) {
2620 #define MWL8K_STAT_ACK_FAILURE 9
2621 #define MWL8K_STAT_RTS_FAILURE 12
2622 #define MWL8K_STAT_FCS_ERROR 24
2623 #define MWL8K_STAT_RTS_SUCCESS 11
2638 rc = mwl8k_post_cmd(hw, &cmd->
header);
2671 if (enable == priv->
radio_on && !force)
2684 rc = mwl8k_post_cmd(hw, &cmd->
header);
2693 static int mwl8k_cmd_radio_disable(
struct ieee80211_hw *hw)
2698 static int mwl8k_cmd_radio_enable(
struct ieee80211_hw *hw)
2704 mwl8k_set_radio_preamble(
struct ieee80211_hw *hw,
bool short_preamble)
2716 #define MWL8K_RF_TX_POWER_LEVEL_TOTAL 8
2741 rc = mwl8k_post_cmd(hw, &cmd->
header);
2750 #define MWL8K_TX_POWER_LEVEL_TOTAL 12
2800 rc = mwl8k_post_cmd(hw, &cmd->
header);
2815 #define MWL8K_RF_ANTENNA_RX 1
2816 #define MWL8K_RF_ANTENNA_TX 2
2833 rc = mwl8k_post_cmd(hw, &cmd->
header);
2854 cmd = kzalloc(
sizeof(*cmd) + len,
GFP_KERNEL);
2863 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->
header);
2888 rc = mwl8k_post_cmd(hw, &cmd->
header);
2918 rc = mwl8k_post_cmd(hw, &cmd->
header);
2963 rc = mwl8k_post_cmd(hw, &cmd->
header);
2972 #define MWL8K_FRAME_PROT_DISABLED 0x00
2973 #define MWL8K_FRAME_PROT_11G 0x07
2974 #define MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY 0x02
2975 #define MWL8K_FRAME_PROT_11N_HT_ALL 0x06
2987 static void legacy_rate_mask_to_array(
u8 *rates,
u32 mask)
2997 for (i = 0, j = 0; i < 14; i++) {
2998 if (mask & (1 << i))
2999 rates[j++] = mwl8k_rates_24[
i].
hw_value;
3023 switch (vif->
bss_conf.ht_operation_mode &
3038 legacy_rate_mask_to_array(cmd->
supp_rates, legacy_rate_mask);
3040 rc = mwl8k_post_cmd(hw, &cmd->
header);
3060 u32 legacy_rate_mask,
u8 *mcs_rates)
3071 legacy_rate_mask_to_array(cmd->
legacy_rates, legacy_rate_mask);
3074 rc = mwl8k_post_cmd(hw, &cmd->
header);
3083 #define MWL8K_FJ_BEACON_MAXLEN 128
3092 int framelen,
int dtim)
3108 if (payload_len < 0)
3115 rc = mwl8k_post_cmd(hw, &cmd->
header);
3145 rc = mwl8k_post_cmd(hw, &cmd->
header);
3174 rc = mwl8k_post_cmd(hw, &cmd->
header);
3222 #define MWL8K_SET_EDCA_CW 0x01
3223 #define MWL8K_SET_EDCA_TXOP 0x02
3224 #define MWL8K_SET_EDCA_AIFS 0x04
3226 #define MWL8K_SET_EDCA_ALL (MWL8K_SET_EDCA_CW | \
3227 MWL8K_SET_EDCA_TXOP | \
3228 MWL8K_SET_EDCA_AIFS)
3256 cmd->
sta.txq = qnum;
3259 rc = mwl8k_post_cmd(hw, &cmd->
header);
3287 rc = mwl8k_post_cmd(hw, &cmd->
header);
3321 rc = mwl8k_post_cmd(hw, &cmd->
header);
3346 #define MWL8K_USE_AUTO_RATE 0x0002
3347 #define MWL8K_UCAST_RATE 0
3363 rc = mwl8k_post_cmd(hw, &cmd->
header);
3404 rc = mwl8k_post_cmd(hw, &cmd->
header);
3431 rc = mwl8k_post_cmd(hw, &cmd->
header);
3448 #define MWL8K_MAC_TYPE_PRIMARY_CLIENT 0
3449 #define MWL8K_MAC_TYPE_SECONDARY_CLIENT 1
3450 #define MWL8K_MAC_TYPE_PRIMARY_AP 2
3451 #define MWL8K_MAC_TYPE_SECONDARY_AP 3
3457 struct mwl8k_vif *mwl8k_vif =
MWL8K_VIF(vif);
3492 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->
header);
3501 static inline int mwl8k_cmd_set_mac_addr(
struct ieee80211_hw *hw,
3510 static inline int mwl8k_cmd_del_mac_addr(
struct ieee80211_hw *hw,
3539 rc = mwl8k_post_cmd(hw, &cmd->
header);
3565 rc = mwl8k_post_cmd(hw, &cmd->
header);
3574 #define INVALID_BA 0xAA
3595 streams = &priv->
ampdu[stream_index];
3626 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->
header);
3639 #define BASTREAM_FLAG_DIRECTION_UPSTREAM 0x00
3640 #define BASTREAM_FLAG_IMMEDIATE_TYPE 0x01
3705 rc = mwl8k_post_cmd(hw, &cmd->
header);
3739 (stream->
sta->ht_cap.ampdu_factor &
3741 ((stream->
sta->ht_cap.ampdu_density << 2) &
3748 rc = mwl8k_post_cmd(hw, &cmd->
header);
3751 stream->
sta->addr, stream->
tid);
3771 mwl8k_post_cmd(hw, &cmd->
header);
3803 #define MWL8K_STA_ACTION_ADD 0
3804 #define MWL8K_STA_ACTION_REMOVE 2
3806 static int mwl8k_cmd_set_new_stn_add(
struct ieee80211_hw *hw,
3829 if (sta->
ht_cap.ht_supported) {
3836 ((sta->
ht_cap.ampdu_density & 7) << 2);
3840 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->
header);
3846 static int mwl8k_cmd_set_new_stn_add_self(
struct ieee80211_hw *hw,
3860 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->
header);
3866 static int mwl8k_cmd_set_new_stn_del(
struct ieee80211_hw *hw,
3881 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->
header);
3891 #define MAX_ENCR_KEY_LENGTH 16
3892 #define MIC_KEY_LENGTH 8
3931 #define MWL8K_UPDATE_ENCRYPTION_TYPE_WEP 0
3932 #define MWL8K_UPDATE_ENCRYPTION_TYPE_DISABLE 1
3933 #define MWL8K_UPDATE_ENCRYPTION_TYPE_TKIP 4
3934 #define MWL8K_UPDATE_ENCRYPTION_TYPE_MIXED 7
3935 #define MWL8K_UPDATE_ENCRYPTION_TYPE_AES 8
3943 #define MWL8K_KEY_FLAG_TXGROUPKEY 0x00000004
3944 #define MWL8K_KEY_FLAG_PAIRWISE 0x00000008
3945 #define MWL8K_KEY_FLAG_TSC_VALID 0x00000040
3946 #define MWL8K_KEY_FLAG_WEP_TXKEY 0x01000000
3947 #define MWL8K_KEY_FLAG_MICKEY_VALID 0x02000000
3949 static int mwl8k_cmd_update_encryption_enable(
struct ieee80211_hw *hw,
3967 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->
header);
4014 static int mwl8k_cmd_encryption_set_key(
struct ieee80211_hw *hw,
4024 struct mwl8k_vif *mwl8k_vif =
MWL8K_VIF(vif);
4030 rc = mwl8k_encryption_set_cmd_info(cmd, addr, key);
4046 sizeof(*key) + key->
keylen);
4067 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->
header);
4074 static int mwl8k_cmd_encryption_remove_key(
struct ieee80211_hw *hw,
4081 struct mwl8k_vif *mwl8k_vif =
MWL8K_VIF(vif);
4087 rc = mwl8k_encryption_set_cmd_info(cmd, addr, key);
4097 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->
header);
4113 struct mwl8k_vif *mwl8k_vif =
MWL8K_VIF(vif);
4124 rc = mwl8k_cmd_encryption_set_key(hw, vif, addr, key);
4134 rc = mwl8k_cmd_update_encryption_enable(hw, vif, addr,
4142 rc = mwl8k_cmd_encryption_remove_key(hw, vif, addr, key);
4204 #define MWL8K_STA_DB_MODIFY_ENTRY 1
4205 #define MWL8K_STA_DB_DEL_ENTRY 2
4208 #define MWL8K_PEER_TYPE_ACCESSPOINT 2
4210 static int mwl8k_cmd_update_stadb_add(
struct ieee80211_hw *hw,
4234 ((sta->
ht_cap.ampdu_density & 7) << 2);
4244 rc = mwl8k_post_cmd(hw, &cmd->
header);
4250 static int mwl8k_cmd_update_stadb_del(
struct ieee80211_hw *hw,
4265 rc = mwl8k_post_cmd(hw, &cmd->
header);
4286 status &= ~MWL8K_A2H_INT_TX_DONE;
4291 status &= ~MWL8K_A2H_INT_RX_READY;
4296 status &= ~MWL8K_A2H_INT_BA_WATCHDOG;
4309 if (!mutex_is_locked(&priv->
fw_mutex) &&
4311 mwl8k_tx_start(priv);
4317 static void mwl8k_tx_poll(
unsigned long data)
4329 limit -= mwl8k_txq_reclaim(hw, i, limit, 0);
4336 spin_unlock_bh(&priv->
tx_lock);
4339 writel(~MWL8K_A2H_INT_TX_DONE,
4346 static void mwl8k_rx_poll(
unsigned long data)
4353 limit -= rxq_process(hw, 0, limit);
4354 limit -= rxq_refill(hw, 0, limit);
4357 writel(~MWL8K_A2H_INT_RX_READY,
4373 int index = skb_get_queue_mapping(skb);
4377 "dropped TX frame since radio disabled\n");
4382 mwl8k_txq_xmit(hw, index, control->
sta, skb);
4408 rc = mwl8k_fw_lock(hw);
4410 rc = mwl8k_cmd_radio_enable(hw);
4421 "\x00\x00\x00\x00\x00\x00");
4425 rc = mwl8k_cmd_set_rateadapt_mode(hw, 0);
4430 mwl8k_fw_unlock(hw);
4450 mwl8k_cmd_radio_disable(hw);
4456 if (priv->
irq != -1) {
4473 mwl8k_txq_reclaim(hw, i,
INT_MAX, 1);
4476 static int mwl8k_reload_firmware(
struct ieee80211_hw *hw,
char *fw_image);
4478 static int mwl8k_add_interface(
struct ieee80211_hw *hw,
4482 struct mwl8k_vif *mwl8k_vif;
4483 u32 macids_supported;
4494 "unable to create STA interface because sniffer mode is enabled\n");
4499 switch (vif->
type) {
4532 memset(mwl8k_vif, 0,
sizeof(*mwl8k_vif));
4533 mwl8k_vif->
vif = vif;
4534 mwl8k_vif->
macid = macid;
4535 mwl8k_vif->
seqno = 0;
4540 mwl8k_cmd_set_mac_addr(hw, vif, vif->
addr);
4543 mwl8k_cmd_set_new_stn_add_self(hw, vif);
4551 static void mwl8k_remove_vif(
struct mwl8k_priv *priv,
struct mwl8k_vif *vif)
4561 static void mwl8k_remove_interface(
struct ieee80211_hw *hw,
4565 struct mwl8k_vif *mwl8k_vif =
MWL8K_VIF(vif);
4568 mwl8k_cmd_set_new_stn_del(hw, vif, vif->
addr);
4570 mwl8k_cmd_del_mac_addr(hw, vif, vif->
addr);
4572 mwl8k_remove_vif(priv, mwl8k_vif);
4609 mwl8k_fw_unlock(hw);
4617 mwl8k_fw_unlock(hw);
4629 mwl8k_cmd_radio_disable(hw);
4633 rc = mwl8k_fw_lock(hw);
4637 rc = mwl8k_cmd_radio_enable(hw);
4671 mwl8k_fw_unlock(hw);
4681 u32 ap_legacy_rates = 0;
4682 u8 ap_mcs_rates[16];
4685 if (mwl8k_fw_lock(hw))
4719 if ((changed & BSS_CHANGED_ASSOC) && vif->
bss_conf.assoc) {
4730 rc = mwl8k_set_radio_preamble(hw,
4745 rc = mwl8k_cmd_set_aid(hw, vif, ap_legacy_rates);
4761 mwl8k_fw_unlock(hw);
4770 if (mwl8k_fw_lock(hw))
4773 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
4774 rc = mwl8k_set_radio_preamble(hw,
4804 skb = ieee80211_beacon_get(hw, vif);
4815 mwl8k_fw_unlock(hw);
4825 mwl8k_bss_info_changed_sta(hw, vif, info, changed);
4827 mwl8k_bss_info_changed_ap(hw, vif, info, changed);
4842 cmd = __mwl8k_cmd_mac_multicast_adr(hw, 0, mc_list);
4844 return (
unsigned long)
cmd;
4848 mwl8k_configure_filter_sniffer(
struct ieee80211_hw *hw,
4849 unsigned int changed_flags,
4850 unsigned int *total_flags)
4859 if (!list_empty(&priv->
vif_list)) {
4862 "not enabling sniffer mode because STA interface is active\n");
4879 static struct mwl8k_vif *mwl8k_first_vif(
struct mwl8k_priv *priv)
4887 static void mwl8k_configure_filter(
struct ieee80211_hw *hw,
4888 unsigned int changed_flags,
4889 unsigned int *total_flags,
4893 struct mwl8k_cmd_pkt *cmd = (
void *)(
unsigned long)multicast;
4910 mwl8k_configure_filter_sniffer(hw, changed_flags, total_flags)) {
4918 if (mwl8k_fw_lock(hw)) {
4929 if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
4935 struct mwl8k_vif *mwl8k_vif;
4946 mwl8k_vif = mwl8k_first_vif(priv);
4947 if (mwl8k_vif !=
NULL)
4948 bssid = mwl8k_vif->
vif->bss_conf.bssid;
4950 bssid =
"\x01\x00\x00\x00\x00\x00";
4964 cmd = __mwl8k_cmd_mac_multicast_adr(hw, 1,
NULL);
4968 mwl8k_post_cmd(hw, cmd);
4972 mwl8k_fw_unlock(hw);
4987 return mwl8k_cmd_set_new_stn_del(hw, vif, sta->
addr);
4989 return mwl8k_cmd_update_stadb_del(hw, vif, sta->
addr);
4999 struct mwl8k_vif *mwl8k_vif =
MWL8K_VIF(vif);
5003 ret = mwl8k_cmd_update_stadb_add(hw, vif, sta);
5006 if (sta->
ht_cap.ht_supported)
5007 MWL8K_STA(sta)->is_ampdu_allowed =
true;
5012 ret = mwl8k_cmd_set_new_stn_add(hw, vif, sta);
5018 mwl8k_set_key(hw,
SET_KEY, vif, sta, key);
5030 rc = mwl8k_fw_lock(hw);
5047 mwl8k_fw_unlock(hw);
5059 static int mwl8k_get_survey(
struct ieee80211_hw *hw,
int idx,
5075 #define MAX_AMPDU_ATTEMPTS 5
5093 stream = mwl8k_lookup_stream(hw, addr, tid);
5110 if (stream ==
NULL) {
5117 "Proceeding anyway.\n", __func__);
5118 stream = mwl8k_add_stream(hw, sta, tid);
5120 if (stream ==
NULL) {
5130 rc = mwl8k_check_ba(hw, stream);
5136 if (!rc || rc == -
EBUSY)
5148 " attempts\n", tid, MAX_AMPDU_ATTEMPTS);
5149 mwl8k_remove_stream(hw, stream);
5159 mwl8k_destroy_ba(hw, stream);
5162 mwl8k_remove_stream(hw, stream);
5170 rc = mwl8k_create_ba(hw, stream, buf_size);
5176 mwl8k_destroy_ba(hw, stream);
5179 "Failed adding stream for sta %pM tid %d\n",
5181 mwl8k_remove_stream(hw, stream);
5195 .start = mwl8k_start,
5197 .add_interface = mwl8k_add_interface,
5198 .remove_interface = mwl8k_remove_interface,
5199 .config = mwl8k_config,
5200 .bss_info_changed = mwl8k_bss_info_changed,
5201 .prepare_multicast = mwl8k_prepare_multicast,
5202 .configure_filter = mwl8k_configure_filter,
5203 .set_key = mwl8k_set_key,
5204 .set_rts_threshold = mwl8k_set_rts_threshold,
5205 .sta_add = mwl8k_sta_add,
5206 .sta_remove = mwl8k_sta_remove,
5207 .conf_tx = mwl8k_conf_tx,
5208 .get_stats = mwl8k_get_stats,
5209 .get_survey = mwl8k_get_survey,
5210 .ampdu_action = mwl8k_ampdu_action,
5213 static void mwl8k_finalize_join_worker(
struct work_struct *work)
5221 mgmt->
u.beacon.variable, len);
5224 if (tim && tim[1] >= 2)
5225 dtim_period = tim[3];
5239 #define MWL8K_8366_AP_FW_API 2
5240 #define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw"
5241 #define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api)
5245 .part_name =
"88w8363",
5246 .helper_image =
"mwl8k/helper_8363.fw",
5247 .fw_image_sta =
"mwl8k/fmimage_8363.fw",
5250 .part_name =
"88w8687",
5251 .helper_image =
"mwl8k/helper_8687.fw",
5252 .fw_image_sta =
"mwl8k/fmimage_8687.fw",
5255 .part_name =
"88w8366",
5256 .helper_image =
"mwl8k/helper_8366.fw",
5257 .fw_image_sta =
"mwl8k/fmimage_8366.fw",
5260 .ap_rxd_ops = &rxd_8366_ap_ops,
5284 static int mwl8k_request_alt_fw(
struct mwl8k_priv *priv)
5288 "Trying alternative firmware %s\n", pci_name(priv->
pdev),
5290 rc = mwl8k_request_fw(priv, priv->
fw_alt, &priv->
fw_ucode,
true);
5299 static int mwl8k_firmware_load_success(
struct mwl8k_priv *priv);
5300 static void mwl8k_fw_state_machine(
const struct firmware *fw,
void *
context)
5316 if (rc && priv->
fw_alt) {
5317 rc = mwl8k_request_alt_fw(priv);
5330 rc = mwl8k_request_alt_fw(priv);
5338 rc = mwl8k_firmware_load_success(priv);
5353 rc = mwl8k_firmware_load_success(priv);
5372 mwl8k_release_firmware(priv);
5375 #define MAX_RESTART_ATTEMPTS 1
5376 static int mwl8k_init_firmware(
struct ieee80211_hw *hw,
char *fw_image,
5385 mwl8k_hw_reset(priv);
5388 rc = mwl8k_request_firmware(priv, fw_image, nowait);
5398 rc = mwl8k_load_firmware(hw);
5403 mwl8k_release_firmware(priv);
5425 rc = mwl8k_txq_init(hw, i);
5446 "Driver does not have AP firmware image support for this hardware\n");
5447 goto err_stop_firmware;
5457 rc = mwl8k_rxq_init(hw, 0);
5459 goto err_stop_firmware;
5470 rc = mwl8k_init_txqs(hw);
5472 goto err_free_queues;
5477 iowrite32(MWL8K_A2H_INT_TX_DONE|MWL8K_A2H_INT_RX_READY|
5478 MWL8K_A2H_INT_BA_WATCHDOG,
5487 goto err_free_queues;
5510 rc = mwl8k_init_txqs(hw);
5522 rc = mwl8k_cmd_radio_disable(hw);
5529 rc = mwl8k_cmd_set_mac_addr(hw,
NULL,
"\x00\x00\x00\x00\x00\x00");
5542 priv->
ap_fw ?
"AP" :
"STA",
5543 (priv->
fw_rev >> 24) & 0xff, (priv->
fw_rev >> 16) & 0xff,
5554 mwl8k_txq_deinit(hw, i);
5555 mwl8k_rxq_deinit(hw, 0);
5558 mwl8k_hw_reset(priv);
5567 static int mwl8k_reload_firmware(
struct ieee80211_hw *hw,
char *fw_image)
5571 struct mwl8k_vif *
vif, *tmp_vif;
5574 mwl8k_rxq_deinit(hw, 0);
5583 mwl8k_remove_vif(priv, vif);
5586 mwl8k_txq_deinit(hw, i);
5588 rc = mwl8k_init_firmware(hw, fw_image,
false);
5592 rc = mwl8k_probe_hw(hw);
5596 if (priv->hw_restart_in_progress)
5599 rc = mwl8k_start(hw);
5603 rc = mwl8k_config(hw, ~0);
5608 rc = mwl8k_conf_tx(hw,
NULL, i, &priv->wmm_params[i]);
5620 static int mwl8k_firmware_load_success(
struct mwl8k_priv *priv)
5625 rc = mwl8k_load_firmware(hw);
5626 mwl8k_release_firmware(priv);
5694 rc = mwl8k_probe_hw(hw);
5696 goto err_free_cookie;
5698 hw->
wiphy->interface_modes = 0;
5707 goto err_unprobe_hw;
5714 mwl8k_txq_deinit(hw, i);
5715 mwl8k_rxq_deinit(hw, 0);
5727 static int printed_version;
5733 if (!printed_version) {
5735 printed_version = 1;
5750 goto err_disable_device;
5763 SET_IEEE80211_DEV(hw, &pdev->
dev);
5764 pci_set_drvdata(pdev, hw);
5769 priv->
device_info = &mwl8k_info_tbl[
id->driver_data];
5772 priv->
sram = pci_iomap(pdev, 0, 0x10000);
5782 priv->
regs = pci_iomap(pdev, 1, 0x10000);
5784 priv->
regs = pci_iomap(pdev, 2, 0x10000);
5811 rc = mwl8k_init_firmware(hw, priv->
fw_pref,
true);
5813 goto err_stop_firmware;
5820 mwl8k_hw_reset(priv);
5829 pci_set_drvdata(pdev,
NULL);
5859 mwl8k_hw_reset(priv);
5872 mwl8k_hw_reset(priv);
5876 mwl8k_txq_reclaim(hw, i,
INT_MAX, 1);
5879 mwl8k_txq_deinit(hw, i);
5881 mwl8k_rxq_deinit(hw, 0);
5888 pci_set_drvdata(pdev,
NULL);
5896 .id_table = mwl8k_pci_id_table,
5897 .probe = mwl8k_probe,