From: Daniel Golle Date: Thu, 30 Mar 2017 16:08:49 +0000 (+0200) Subject: mac80211: rt2x00: import upstream changes and rebase our patches X-Git-Tag: v17.01.2~71 X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fopenwrt.git;a=commitdiff_plain;h=5b91d2b52ed0d31e6ca6990ca01923e3a3d1d217 mac80211: rt2x00: import upstream changes and rebase our patches Some of our local patches have been accepted upstream. And there are some more relevant changes (mostly for rt2800usb). Import them and rebase our remaining local patches on top. Signed-off-by: Daniel Golle --- diff --git a/package/kernel/mac80211/patches/020-01-rt2x00-avoid-introducing-a-USB-dependency-in-the-rt2.patch b/package/kernel/mac80211/patches/020-01-rt2x00-avoid-introducing-a-USB-dependency-in-the-rt2.patch new file mode 100644 index 0000000000..7e829faef6 --- /dev/null +++ b/package/kernel/mac80211/patches/020-01-rt2x00-avoid-introducing-a-USB-dependency-in-the-rt2.patch @@ -0,0 +1,85 @@ +From 6232c17438ed01f43665197db5a98a4a4f77ef47 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Thu, 2 Feb 2017 10:57:40 +0100 +Subject: [PATCH 01/19] rt2x00: avoid introducing a USB dependency in the + rt2x00lib module + +As reported by Felix: + +Though protected by an ifdef, introducing an usb symbol dependency in +the rt2x00lib module is a major inconvenience for distributions that +package kernel modules split into individual packages. + +Get rid of this unnecessary dependency by calling the usb related +function from a more suitable place. + +Cc: Vishal Thanki +Reported-by: Felix Fietkau +Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB") +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 23 ++++++++--------------- + drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 5 +++++ + 2 files changed, 13 insertions(+), 15 deletions(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +index 8fcbc8dc94c1..4b08007f93f7 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -1436,21 +1436,6 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) + cancel_work_sync(&rt2x00dev->intf_work); + cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); + cancel_work_sync(&rt2x00dev->sleep_work); +-#if IS_ENABLED(CPTCFG_RT2X00_LIB_USB) +- if (rt2x00_is_usb(rt2x00dev)) { +- usb_kill_anchored_urbs(rt2x00dev->anchor); +- hrtimer_cancel(&rt2x00dev->txstatus_timer); +- cancel_work_sync(&rt2x00dev->rxdone_work); +- cancel_work_sync(&rt2x00dev->txdone_work); +- } +-#endif +- if (rt2x00dev->workqueue) +- destroy_workqueue(rt2x00dev->workqueue); +- +- /* +- * Free the tx status fifo. +- */ +- kfifo_free(&rt2x00dev->txstatus_fifo); + + /* + * Kill the tx status tasklet. +@@ -1466,6 +1451,14 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) + */ + rt2x00lib_uninitialize(rt2x00dev); + ++ if (rt2x00dev->workqueue) ++ destroy_workqueue(rt2x00dev->workqueue); ++ ++ /* ++ * Free the tx status fifo. ++ */ ++ kfifo_free(&rt2x00dev->txstatus_fifo); ++ + /* + * Free extra components + */ +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +index 838ca58d2dd6..5a2bf9f63cd7 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +@@ -744,6 +744,11 @@ void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev) + { + struct data_queue *queue; + ++ usb_kill_anchored_urbs(rt2x00dev->anchor); ++ hrtimer_cancel(&rt2x00dev->txstatus_timer); ++ cancel_work_sync(&rt2x00dev->rxdone_work); ++ cancel_work_sync(&rt2x00dev->txdone_work); ++ + queue_for_each(rt2x00dev, queue) + rt2x00usb_free_entries(queue); + } +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-02-rt2x00usb-do-not-anchor-rx-and-tx-urb-s.patch b/package/kernel/mac80211/patches/020-02-rt2x00usb-do-not-anchor-rx-and-tx-urb-s.patch new file mode 100644 index 0000000000..6510b55c79 --- /dev/null +++ b/package/kernel/mac80211/patches/020-02-rt2x00usb-do-not-anchor-rx-and-tx-urb-s.patch @@ -0,0 +1,61 @@ +From 93c7018ec16bb83399dd4db61c361a6d6aba0d5a Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 8 Feb 2017 12:18:09 +0100 +Subject: [PATCH 02/19] rt2x00usb: do not anchor rx and tx urb's + +We might kill TX or RX urb during rt2x00usb_flush_entry(), what can +cause anchor list corruption like shown below: + +[ 2074.035633] WARNING: CPU: 2 PID: 14480 at lib/list_debug.c:33 __list_add+0xac/0xc0 +[ 2074.035634] list_add corruption. prev->next should be next (ffff88020f362c28), but was dead000000000100. (prev=ffff8801d161bb70). + +[ 2074.035670] Call Trace: +[ 2074.035672] [] dump_stack+0x63/0x8c +[ 2074.035674] [] __warn+0xd1/0xf0 +[ 2074.035676] [] warn_slowpath_fmt+0x5f/0x80 +[ 2074.035678] [] ? rt2x00usb_register_write_lock+0x3d/0x60 [rt2800usb] +[ 2074.035679] [] __list_add+0xac/0xc0 +[ 2074.035681] [] usb_anchor_urb+0x4c/0xa0 +[ 2074.035683] [] rt2x00usb_kick_rx_entry+0xaf/0x100 [rt2x00usb] +[ 2074.035684] [] rt2x00usb_clear_entry+0x22/0x30 [rt2x00usb] + +To fix do not anchor TX and RX urb's, it is not needed as during +shutdown we kill those urbs in rt2x00usb_free_entries(). + +Cc: Vishal Thanki +Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB") +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +index 5a2bf9f63cd7..fe13dd07cc2a 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +@@ -319,10 +319,8 @@ static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void *data) + entry->skb->data, length, + rt2x00usb_interrupt_txdone, entry); + +- usb_anchor_urb(entry_priv->urb, rt2x00dev->anchor); + status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); + if (status) { +- usb_unanchor_urb(entry_priv->urb); + if (status == -ENODEV) + clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); + set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); +@@ -410,10 +408,8 @@ static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void *data) + entry->skb->data, entry->skb->len, + rt2x00usb_interrupt_rxdone, entry); + +- usb_anchor_urb(entry_priv->urb, rt2x00dev->anchor); + status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); + if (status) { +- usb_unanchor_urb(entry_priv->urb); + if (status == -ENODEV) + clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); + set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-03-rt2x00usb-fix-anchor-initialization.patch b/package/kernel/mac80211/patches/020-03-rt2x00usb-fix-anchor-initialization.patch new file mode 100644 index 0000000000..78d8ac63d8 --- /dev/null +++ b/package/kernel/mac80211/patches/020-03-rt2x00usb-fix-anchor-initialization.patch @@ -0,0 +1,75 @@ +From 0488a6121dfe6cbd44de15ea3627913b7549a1e9 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 8 Feb 2017 12:18:10 +0100 +Subject: [PATCH 03/19] rt2x00usb: fix anchor initialization + +If device fail to initialize we can OOPS in rt2x00lib_remove_dev(), due +to using uninitialized usb_anchor structure: + +[ 855.435820] ieee80211 phy3: rt2x00usb_vendor_request: Error - Vendor Request 0x07 failed for offset 0x1000 with error -19 +[ 855.435826] ieee80211 phy3: rt2800_probe_rt: Error - Invalid RT chipset 0x0000, rev 0000 detected +[ 855.435829] ieee80211 phy3: rt2x00lib_probe_dev: Error - Failed to allocate device +[ 855.435845] BUG: unable to handle kernel NULL pointer dereference at 0000000000000028 +[ 855.435900] IP: _raw_spin_lock_irq+0xd/0x30 +[ 855.435926] PGD 0 +[ 855.435953] Oops: 0002 [#1] SMP + +[ 855.437011] Call Trace: +[ 855.437029] ? usb_kill_anchored_urbs+0x27/0xc0 +[ 855.437061] rt2x00lib_remove_dev+0x190/0x1c0 [rt2x00lib] +[ 855.437097] rt2x00lib_probe_dev+0x246/0x7a0 [rt2x00lib] +[ 855.437149] ? ieee80211_roc_setup+0x9e/0xd0 [mac80211] +[ 855.437183] ? __kmalloc+0x1af/0x1f0 +[ 855.437207] ? rt2x00usb_probe+0x13d/0xc50 [rt2x00usb] +[ 855.437240] rt2x00usb_probe+0x155/0xc50 [rt2x00usb] +[ 855.437273] rt2800usb_probe+0x15/0x20 [rt2800usb] +[ 855.437304] usb_probe_interface+0x159/0x2d0 +[ 855.437333] driver_probe_device+0x2bb/0x460 + +Patch changes initialization sequence to fix the problem. + +Cc: Vishal Thanki +Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB") +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +index fe13dd07cc2a..c696f0ad6a68 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +@@ -825,10 +825,6 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, + if (retval) + goto exit_free_device; + +- retval = rt2x00lib_probe_dev(rt2x00dev); +- if (retval) +- goto exit_free_reg; +- + rt2x00dev->anchor = devm_kmalloc(&usb_dev->dev, + sizeof(struct usb_anchor), + GFP_KERNEL); +@@ -836,10 +832,17 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, + retval = -ENOMEM; + goto exit_free_reg; + } +- + init_usb_anchor(rt2x00dev->anchor); ++ ++ retval = rt2x00lib_probe_dev(rt2x00dev); ++ if (retval) ++ goto exit_free_anchor; ++ + return 0; + ++exit_free_anchor: ++ usb_kill_anchored_urbs(rt2x00dev->anchor); ++ + exit_free_reg: + rt2x00usb_free_reg(rt2x00dev); + +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-04-rt61pci-use-entry-directly.patch b/package/kernel/mac80211/patches/020-04-rt61pci-use-entry-directly.patch new file mode 100644 index 0000000000..d8f262af85 --- /dev/null +++ b/package/kernel/mac80211/patches/020-04-rt61pci-use-entry-directly.patch @@ -0,0 +1,28 @@ +From 80a97eae304631f57ff8560f87c0b18b95321443 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 8 Feb 2017 13:51:29 +0100 +Subject: [PATCH 04/19] rt61pci: use entry directly + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt61pci.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt61pci.c b/drivers/net/wireless/ralink/rt2x00/rt61pci.c +index 5306a3b2622d..8adb5f3abe15 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c +@@ -1903,8 +1903,7 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry, + + rt2x00_desc_read(txd, 5, &word); + rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->queue->qid); +- rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, +- skbdesc->entry->entry_idx); ++ rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, entry->entry_idx); + rt2x00_set_field32(&word, TXD_W5_TX_POWER, + TXPOWER_TO_DEV(entry->queue->rt2x00dev->tx_power)); + rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-05-rt2x00-call-entry-directly-in-rt2x00_dump_frame.patch b/package/kernel/mac80211/patches/020-05-rt2x00-call-entry-directly-in-rt2x00_dump_frame.patch new file mode 100644 index 0000000000..04a5118103 --- /dev/null +++ b/package/kernel/mac80211/patches/020-05-rt2x00-call-entry-directly-in-rt2x00_dump_frame.patch @@ -0,0 +1,181 @@ +From 2ceb813798e1fd33e71a574771828c0f298e077b Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 8 Feb 2017 13:51:30 +0100 +Subject: [PATCH 05/19] rt2x00: call entry directly in rt2x00_dump_frame + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2400pci.c | 2 +- + drivers/net/wireless/ralink/rt2x00/rt2500pci.c | 2 +- + drivers/net/wireless/ralink/rt2x00/rt2500usb.c | 2 +- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 +- + drivers/net/wireless/ralink/rt2x00/rt2x00.h | 4 ++-- + drivers/net/wireless/ralink/rt2x00/rt2x00debug.c | 7 ++++--- + drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 4 ++-- + drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 2 +- + drivers/net/wireless/ralink/rt2x00/rt61pci.c | 2 +- + drivers/net/wireless/ralink/rt2x00/rt73usb.c | 2 +- + 10 files changed, 15 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c +index 085c5b423bdf..19874439ac40 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c +@@ -1200,7 +1200,7 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, + /* + * Dump beacon to userspace through debugfs. + */ +- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); ++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry); + out: + /* + * Enable beaconing again. +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c +index 9832fd50c793..791434de8052 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c +@@ -1349,7 +1349,7 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, + /* + * Dump beacon to userspace through debugfs. + */ +- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); ++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry); + out: + /* + * Enable beaconing again. +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c +index cd3ab5a9e98d..62357465fe29 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c +@@ -1170,7 +1170,7 @@ static void rt2500usb_write_beacon(struct queue_entry *entry, + /* + * Dump beacon to userspace through debugfs. + */ +- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); ++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry); + + /* + * USB devices cannot blindly pass the skb->len as the +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +index 572cdea4ca25..8223a1520316 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -1014,7 +1014,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) + /* + * Dump beacon to userspace through debugfs. + */ +- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); ++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry); + + /* + * Write entire beacon with TXWI and padding to register. +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +index ea299c4e7ada..26869b3bef45 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -1400,11 +1400,11 @@ void rt2x00queue_flush_queues(struct rt2x00_dev *rt2x00dev, bool drop); + */ + #ifdef CPTCFG_RT2X00_LIB_DEBUGFS + void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, +- enum rt2x00_dump_type type, struct sk_buff *skb); ++ enum rt2x00_dump_type type, struct queue_entry *entry); + #else + static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, + enum rt2x00_dump_type type, +- struct sk_buff *skb) ++ struct queue_entry *entry) + { + } + #endif /* CPTCFG_RT2X00_LIB_DEBUGFS */ +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c +index 72ae530e4a3b..964aefdc11f0 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c +@@ -157,9 +157,10 @@ void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, + } + + void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, +- enum rt2x00_dump_type type, struct sk_buff *skb) ++ enum rt2x00_dump_type type, struct queue_entry *entry) + { + struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf; ++ struct sk_buff *skb = entry->skb; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); + struct sk_buff *skbcopy; + struct rt2x00dump_hdr *dump_hdr; +@@ -196,8 +197,8 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, + dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf); + dump_hdr->chip_rev = cpu_to_le16(rt2x00dev->chip.rev); + dump_hdr->type = cpu_to_le16(type); +- dump_hdr->queue_index = skbdesc->entry->queue->qid; +- dump_hdr->entry_index = skbdesc->entry->entry_idx; ++ dump_hdr->queue_index = entry->queue->qid; ++ dump_hdr->entry_index = entry->entry_idx; + dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec); + dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec); + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +index 4b08007f93f7..dd6678109b7e 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -363,7 +363,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, + * Send frame to debugfs immediately, after this call is completed + * we are going to overwrite the skb->cb array. + */ +- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry->skb); ++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry); + + /* + * Determine if the frame has been successfully transmitted and +@@ -772,7 +772,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp) + */ + rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc); + rt2x00debug_update_crypto(rt2x00dev, &rxdesc); +- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); ++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry); + + /* + * Initialize RX status information, and send frame +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c +index b2364d378774..380daf4e1b8d 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c +@@ -544,7 +544,7 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, + * All processing on the frame has been completed, this means + * it is now ready to be dumped to userspace through debugfs. + */ +- rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry->skb); ++ rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry); + } + + static void rt2x00queue_kick_tx_queue(struct data_queue *queue, +diff --git a/drivers/net/wireless/ralink/rt2x00/rt61pci.c b/drivers/net/wireless/ralink/rt2x00/rt61pci.c +index 8adb5f3abe15..973d418b8113 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c +@@ -1988,7 +1988,7 @@ static void rt61pci_write_beacon(struct queue_entry *entry, + /* + * Dump beacon to userspace through debugfs. + */ +- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); ++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry); + + /* + * Write entire beacon with descriptor and padding to register. +diff --git a/drivers/net/wireless/ralink/rt2x00/rt73usb.c b/drivers/net/wireless/ralink/rt2x00/rt73usb.c +index 1a29c4d205a5..bb8d307a789f 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt73usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt73usb.c +@@ -1557,7 +1557,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry, + /* + * Dump beacon to userspace through debugfs. + */ +- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); ++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry); + + /* + * Write entire beacon with descriptor and padding to register. +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-06-rt2x00-remove-queue_entry-from-skbdesc.patch b/package/kernel/mac80211/patches/020-06-rt2x00-remove-queue_entry-from-skbdesc.patch new file mode 100644 index 0000000000..d8194acd23 --- /dev/null +++ b/package/kernel/mac80211/patches/020-06-rt2x00-remove-queue_entry-from-skbdesc.patch @@ -0,0 +1,59 @@ +From cf81db30a6edcca791b1bfa5348a162471121d11 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 8 Feb 2017 13:51:31 +0100 +Subject: [PATCH 06/19] rt2x00: remove queue_entry from skbdesc + +queue_entry field of skbdesc is not read any more, remove it to allow +skbdesc contain other data. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 3 --- + drivers/net/wireless/ralink/rt2x00/rt2x00queue.h | 2 -- + 2 files changed, 5 deletions(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c +index 380daf4e1b8d..e1660b92b20c 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c +@@ -83,7 +83,6 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry, gfp_t gfp) + */ + skbdesc = get_skb_frame_desc(skb); + memset(skbdesc, 0, sizeof(*skbdesc)); +- skbdesc->entry = entry; + + if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_DMA)) { + dma_addr_t skb_dma; +@@ -689,7 +688,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, + goto out; + } + +- skbdesc->entry = entry; + entry->skb = skb; + + /* +@@ -774,7 +772,6 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, + */ + skbdesc = get_skb_frame_desc(intf->beacon->skb); + memset(skbdesc, 0, sizeof(*skbdesc)); +- skbdesc->entry = intf->beacon; + + /* + * Send beacon to hardware. +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h +index 2233b911a1d7..22d18818e850 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h +@@ -116,8 +116,6 @@ struct skb_frame_desc { + __le32 iv[2]; + + dma_addr_t skb_dma; +- +- struct queue_entry *entry; + }; + + /** +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-07-rt2500usb-don-t-mark-register-accesses-as-inline.patch b/package/kernel/mac80211/patches/020-07-rt2500usb-don-t-mark-register-accesses-as-inline.patch new file mode 100644 index 0000000000..a82886d234 --- /dev/null +++ b/package/kernel/mac80211/patches/020-07-rt2500usb-don-t-mark-register-accesses-as-inline.patch @@ -0,0 +1,84 @@ +From 7272416609126e8910b7f0d0e3dba008aa87830c Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 14 Feb 2017 22:28:33 +0100 +Subject: [PATCH 07/19] rt2500usb: don't mark register accesses as inline + +When CONFIG_KASAN is set, we get a rather large stack here: + +drivers/net/wireless/ralink/rt2x00/rt2500usb.c: In function 'rt2500usb_set_device_state': +drivers/net/wireless/ralink/rt2x00/rt2500usb.c:1074:1: error: the frame size of 3032 bytes is larger than 100 bytes [-Werror=frame-larger-than=] + +If we don't force those functions to be inline, the compiler can figure this +out better itself and not inline the functions when doing so would be harmful, +reducing the stack size to a merge 256 bytes. + +Note that there is another problem that manifests in this driver, as a result +of the typecheck() macro causing even larger stack frames. + +Signed-off-by: Arnd Bergmann +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2500usb.c | 19 +++++-------------- + 1 file changed, 5 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c +index 62357465fe29..0d2670a56c4c 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c +@@ -55,7 +55,7 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); + * If the csr_mutex is already held then the _lock variants must + * be used instead. + */ +-static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev, ++static void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + u16 *value) + { +@@ -66,7 +66,7 @@ static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev, + *value = le16_to_cpu(reg); + } + +-static inline void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev, ++static void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + u16 *value) + { +@@ -77,16 +77,7 @@ static inline void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev, + *value = le16_to_cpu(reg); + } + +-static inline void rt2500usb_register_multiread(struct rt2x00_dev *rt2x00dev, +- const unsigned int offset, +- void *value, const u16 length) +-{ +- rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ, +- USB_VENDOR_REQUEST_IN, offset, +- value, length); +-} +- +-static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev, ++static void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + u16 value) + { +@@ -96,7 +87,7 @@ static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev, + ®, sizeof(reg)); + } + +-static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev, ++static void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + u16 value) + { +@@ -106,7 +97,7 @@ static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev, + ®, sizeof(reg), REGISTER_TIMEOUT); + } + +-static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, ++static void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + void *value, const u16 length) + { +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-08-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch b/package/kernel/mac80211/patches/020-08-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch new file mode 100644 index 0000000000..c2fa92641a --- /dev/null +++ b/package/kernel/mac80211/patches/020-08-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch @@ -0,0 +1,94 @@ +From 96609f366c6f792421e1939c5c834abbe24eb88a Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 15 Feb 2017 10:25:04 +0100 +Subject: [PATCH 08/19] rt2x00: rt2800lib: move rt2800_drv_data declaration + into rt2800lib.h + +The rt2800_drv_data structure contains driver specific +information. Move the declaration into the rt2800lib.h +header which is a more logical place for it. Also fix +the comment style to avoid checkpatch warning. + +The patch contains no functional changes, it is in +preparation for the next patch. + +Signed-off-by: Gabor Juhos +Signed-off-by: Daniel Golle +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2800.h | 25 ------------------------- + drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 23 +++++++++++++++++++++++ + 2 files changed, 23 insertions(+), 25 deletions(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800.h b/drivers/net/wireless/ralink/rt2x00/rt2800.h +index 256496bfbafb..0e7051d8132f 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -2987,29 +2987,4 @@ enum rt2800_eeprom_word { + */ + #define BCN_TBTT_OFFSET 64 + +-/* +- * Hardware has 255 WCID table entries. First 32 entries are reserved for +- * shared keys. Since parts of the pairwise key table might be shared with +- * the beacon frame buffers 6 & 7 we could only use the first 222 entries. +- */ +-#define WCID_START 33 +-#define WCID_END 222 +-#define STA_IDS_SIZE (WCID_END - WCID_START + 2) +- +-/* +- * RT2800 driver data structure +- */ +-struct rt2800_drv_data { +- u8 calibration_bw20; +- u8 calibration_bw40; +- u8 bbp25; +- u8 bbp26; +- u8 txmixer_gain_24g; +- u8 txmixer_gain_5g; +- u8 max_psdu; +- unsigned int tbtt_tick; +- unsigned int ampdu_factor_cnt[4]; +- DECLARE_BITMAP(sta_ids, STA_IDS_SIZE); +-}; +- + #endif /* RT2800_H */ +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +index 0a8b4df665fe..8e1ae138c3f1 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +@@ -20,6 +20,29 @@ + #ifndef RT2800LIB_H + #define RT2800LIB_H + ++/* ++ * Hardware has 255 WCID table entries. First 32 entries are reserved for ++ * shared keys. Since parts of the pairwise key table might be shared with ++ * the beacon frame buffers 6 & 7 we could only use the first 222 entries. ++ */ ++#define WCID_START 33 ++#define WCID_END 222 ++#define STA_IDS_SIZE (WCID_END - WCID_START + 2) ++ ++/* RT2800 driver data structure */ ++struct rt2800_drv_data { ++ u8 calibration_bw20; ++ u8 calibration_bw40; ++ u8 bbp25; ++ u8 bbp26; ++ u8 txmixer_gain_24g; ++ u8 txmixer_gain_5g; ++ u8 max_psdu; ++ unsigned int tbtt_tick; ++ unsigned int ampdu_factor_cnt[4]; ++ DECLARE_BITMAP(sta_ids, STA_IDS_SIZE); ++}; ++ + struct rt2800_ops { + void (*register_read)(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, u32 *value); +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-09-rt2800-identify-station-based-on-status-WCID.patch b/package/kernel/mac80211/patches/020-09-rt2800-identify-station-based-on-status-WCID.patch new file mode 100644 index 0000000000..e6c829cbf8 --- /dev/null +++ b/package/kernel/mac80211/patches/020-09-rt2800-identify-station-based-on-status-WCID.patch @@ -0,0 +1,94 @@ +From a13d985f26f6df07d5c5c0e190477628e236babc Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 15 Feb 2017 10:25:05 +0100 +Subject: [PATCH 09/19] rt2800: identify station based on status WCID + +Add framework to identify sta based on tx status WCID. This is currently +not used, will start be utilized in the future patch. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 5 +++++ + drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 1 + + drivers/net/wireless/ralink/rt2x00/rt2x00queue.h | 3 ++- + 3 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +index 8223a1520316..46405cce35e0 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -855,11 +855,13 @@ EXPORT_SYMBOL_GPL(rt2800_process_rxwi); + void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi) + { + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; ++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + struct txdone_entry_desc txdesc; + u32 word; + u16 mcs, real_mcs; + int aggr, ampdu; ++ int wcid; + + /* + * Obtain the status about this packet. +@@ -872,6 +874,7 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi) + + real_mcs = rt2x00_get_field32(status, TX_STA_FIFO_MCS); + aggr = rt2x00_get_field32(status, TX_STA_FIFO_TX_AGGRE); ++ wcid = rt2x00_get_field32(status, TX_STA_FIFO_WCID); + + /* + * If a frame was meant to be sent as a single non-aggregated MPDU +@@ -1468,6 +1471,7 @@ int rt2800_sta_add(struct rt2x00_dev *rt2x00dev, struct ieee80211_vif *vif, + return 0; + + __set_bit(wcid - WCID_START, drv_data->sta_ids); ++ drv_data->wcid_to_sta[wcid - WCID_START] = sta; + + /* + * Clean up WCID attributes and write STA address to the device. +@@ -1498,6 +1502,7 @@ int rt2800_sta_remove(struct rt2x00_dev *rt2x00dev, struct ieee80211_sta *sta) + * get renewed when the WCID is reused. + */ + rt2800_config_wcid(rt2x00dev, NULL, wcid); ++ drv_data->wcid_to_sta[wcid - WCID_START] = NULL; + __clear_bit(wcid - WCID_START, drv_data->sta_ids); + + return 0; +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +index 8e1ae138c3f1..6811d677a6e7 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +@@ -41,6 +41,7 @@ struct rt2800_drv_data { + unsigned int tbtt_tick; + unsigned int ampdu_factor_cnt[4]; + DECLARE_BITMAP(sta_ids, STA_IDS_SIZE); ++ struct ieee80211_sta *wcid_to_sta[STA_IDS_SIZE]; + }; + + struct rt2800_ops { +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h +index 22d18818e850..9b297fce4692 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h +@@ -102,7 +102,7 @@ enum skb_frame_desc_flags { + * of the scope of the skb->data pointer. + * @iv: IV/EIV data used during encryption/decryption. + * @skb_dma: (PCI-only) the DMA address associated with the sk buffer. +- * @entry: The entry to which this sk buffer belongs. ++ * @sta: The station where sk buffer was sent. + */ + struct skb_frame_desc { + u8 flags; +@@ -116,6 +116,7 @@ struct skb_frame_desc { + __le32 iv[2]; + + dma_addr_t skb_dma; ++ struct ieee80211_sta *sta; + }; + + /** +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-10-rt2x00-separte-filling-tx-status-from-rt2x00lib_txdo.patch b/package/kernel/mac80211/patches/020-10-rt2x00-separte-filling-tx-status-from-rt2x00lib_txdo.patch new file mode 100644 index 0000000000..278d2d6071 --- /dev/null +++ b/package/kernel/mac80211/patches/020-10-rt2x00-separte-filling-tx-status-from-rt2x00lib_txdo.patch @@ -0,0 +1,178 @@ +From 5edb05afebba8f488a30db29550e55c42eea6d6a Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 15 Feb 2017 10:25:06 +0100 +Subject: [PATCH 10/19] rt2x00: separte filling tx status from rt2x00lib_txdone + +This makes rt2x00lib_txdone a bit simpler and will allow to reuse code +in different variant of txdone which I'm preparing. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 141 +++++++++++++------------ + 1 file changed, 76 insertions(+), 65 deletions(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +index dd6678109b7e..b5d90fefc96b 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -313,73 +313,14 @@ static inline int rt2x00lib_txdone_bar_status(struct queue_entry *entry) + return ret; + } + +-void rt2x00lib_txdone(struct queue_entry *entry, +- struct txdone_entry_desc *txdesc) ++static void rt2x00lib_fill_tx_status(struct rt2x00_dev *rt2x00dev, ++ struct ieee80211_tx_info *tx_info, ++ struct skb_frame_desc *skbdesc, ++ struct txdone_entry_desc *txdesc, ++ bool success) + { +- struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; +- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); +- struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); +- unsigned int header_length, i; + u8 rate_idx, rate_flags, retry_rates; +- u8 skbdesc_flags = skbdesc->flags; +- bool success; +- +- /* +- * Unmap the skb. +- */ +- rt2x00queue_unmap_skb(entry); +- +- /* +- * Remove the extra tx headroom from the skb. +- */ +- skb_pull(entry->skb, rt2x00dev->extra_tx_headroom); +- +- /* +- * Signal that the TX descriptor is no longer in the skb. +- */ +- skbdesc->flags &= ~SKBDESC_DESC_IN_SKB; +- +- /* +- * Determine the length of 802.11 header. +- */ +- header_length = ieee80211_get_hdrlen_from_skb(entry->skb); +- +- /* +- * Remove L2 padding which was added during +- */ +- if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_L2PAD)) +- rt2x00queue_remove_l2pad(entry->skb, header_length); +- +- /* +- * If the IV/EIV data was stripped from the frame before it was +- * passed to the hardware, we should now reinsert it again because +- * mac80211 will expect the same data to be present it the +- * frame as it was passed to us. +- */ +- if (rt2x00_has_cap_hw_crypto(rt2x00dev)) +- rt2x00crypto_tx_insert_iv(entry->skb, header_length); +- +- /* +- * Send frame to debugfs immediately, after this call is completed +- * we are going to overwrite the skb->cb array. +- */ +- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry); +- +- /* +- * Determine if the frame has been successfully transmitted and +- * remove BARs from our check list while checking for their +- * TX status. +- */ +- success = +- rt2x00lib_txdone_bar_status(entry) || +- test_bit(TXDONE_SUCCESS, &txdesc->flags) || +- test_bit(TXDONE_UNKNOWN, &txdesc->flags); +- +- /* +- * Update TX statistics. +- */ +- rt2x00dev->link.qual.tx_success += success; +- rt2x00dev->link.qual.tx_failed += !success; ++ int i; + + rate_idx = skbdesc->tx_rate_idx; + rate_flags = skbdesc->tx_rate_flags; +@@ -448,6 +389,76 @@ void rt2x00lib_txdone(struct queue_entry *entry, + else + rt2x00dev->low_level_stats.dot11RTSFailureCount++; + } ++} ++ ++void rt2x00lib_txdone(struct queue_entry *entry, ++ struct txdone_entry_desc *txdesc) ++{ ++ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; ++ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); ++ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); ++ u8 skbdesc_flags = skbdesc->flags; ++ unsigned int header_length; ++ bool success; ++ ++ /* ++ * Unmap the skb. ++ */ ++ rt2x00queue_unmap_skb(entry); ++ ++ /* ++ * Remove the extra tx headroom from the skb. ++ */ ++ skb_pull(entry->skb, rt2x00dev->extra_tx_headroom); ++ ++ /* ++ * Signal that the TX descriptor is no longer in the skb. ++ */ ++ skbdesc->flags &= ~SKBDESC_DESC_IN_SKB; ++ ++ /* ++ * Determine the length of 802.11 header. ++ */ ++ header_length = ieee80211_get_hdrlen_from_skb(entry->skb); ++ ++ /* ++ * Remove L2 padding which was added during ++ */ ++ if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_L2PAD)) ++ rt2x00queue_remove_l2pad(entry->skb, header_length); ++ ++ /* ++ * If the IV/EIV data was stripped from the frame before it was ++ * passed to the hardware, we should now reinsert it again because ++ * mac80211 will expect the same data to be present it the ++ * frame as it was passed to us. ++ */ ++ if (rt2x00_has_cap_hw_crypto(rt2x00dev)) ++ rt2x00crypto_tx_insert_iv(entry->skb, header_length); ++ ++ /* ++ * Send frame to debugfs immediately, after this call is completed ++ * we are going to overwrite the skb->cb array. ++ */ ++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry); ++ ++ /* ++ * Determine if the frame has been successfully transmitted and ++ * remove BARs from our check list while checking for their ++ * TX status. ++ */ ++ success = ++ rt2x00lib_txdone_bar_status(entry) || ++ test_bit(TXDONE_SUCCESS, &txdesc->flags) || ++ test_bit(TXDONE_UNKNOWN, &txdesc->flags); ++ ++ /* ++ * Update TX statistics. ++ */ ++ rt2x00dev->link.qual.tx_success += success; ++ rt2x00dev->link.qual.tx_failed += !success; ++ ++ rt2x00lib_fill_tx_status(rt2x00dev, tx_info, skbdesc, txdesc, success); + + /* + * Only send the status report to mac80211 when it's a frame +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-11-rt2x00-separte-clearing-entry-from-rt2x00lib_txdone.patch b/package/kernel/mac80211/patches/020-11-rt2x00-separte-clearing-entry-from-rt2x00lib_txdone.patch new file mode 100644 index 0000000000..b28d894fc6 --- /dev/null +++ b/package/kernel/mac80211/patches/020-11-rt2x00-separte-clearing-entry-from-rt2x00lib_txdone.patch @@ -0,0 +1,88 @@ +From 56646adf9cd60b488ddc5633a2d9aa1f30efa5db Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 15 Feb 2017 10:25:07 +0100 +Subject: [PATCH 11/19] rt2x00: separte clearing entry from rt2x00lib_txdone + +This makes rt2x00lib_txdone a bit simpler and will allow to reuse +code in different variant of txdone which I'm preparing. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 51 +++++++++++++++----------- + 1 file changed, 29 insertions(+), 22 deletions(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +index b5d90fefc96b..03b368ac9cb6 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -391,6 +391,32 @@ static void rt2x00lib_fill_tx_status(struct rt2x00_dev *rt2x00dev, + } + } + ++static void rt2x00lib_clear_entry(struct rt2x00_dev *rt2x00dev, ++ struct queue_entry *entry) ++{ ++ /* ++ * Make this entry available for reuse. ++ */ ++ entry->skb = NULL; ++ entry->flags = 0; ++ ++ rt2x00dev->ops->lib->clear_entry(entry); ++ ++ rt2x00queue_index_inc(entry, Q_INDEX_DONE); ++ ++ /* ++ * If the data queue was below the threshold before the txdone ++ * handler we must make sure the packet queue in the mac80211 stack ++ * is reenabled when the txdone handler has finished. This has to be ++ * serialized with rt2x00mac_tx(), otherwise we can wake up queue ++ * before it was stopped. ++ */ ++ spin_lock_bh(&entry->queue->tx_lock); ++ if (!rt2x00queue_threshold(entry->queue)) ++ rt2x00queue_unpause_queue(entry->queue); ++ spin_unlock_bh(&entry->queue->tx_lock); ++} ++ + void rt2x00lib_txdone(struct queue_entry *entry, + struct txdone_entry_desc *txdesc) + { +@@ -471,30 +497,11 @@ void rt2x00lib_txdone(struct queue_entry *entry, + ieee80211_tx_status(rt2x00dev->hw, entry->skb); + else + ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb); +- } else ++ } else { + dev_kfree_skb_any(entry->skb); ++ } + +- /* +- * Make this entry available for reuse. +- */ +- entry->skb = NULL; +- entry->flags = 0; +- +- rt2x00dev->ops->lib->clear_entry(entry); +- +- rt2x00queue_index_inc(entry, Q_INDEX_DONE); +- +- /* +- * If the data queue was below the threshold before the txdone +- * handler we must make sure the packet queue in the mac80211 stack +- * is reenabled when the txdone handler has finished. This has to be +- * serialized with rt2x00mac_tx(), otherwise we can wake up queue +- * before it was stopped. +- */ +- spin_lock_bh(&entry->queue->tx_lock); +- if (!rt2x00queue_threshold(entry->queue)) +- rt2x00queue_unpause_queue(entry->queue); +- spin_unlock_bh(&entry->queue->tx_lock); ++ rt2x00lib_clear_entry(rt2x00dev, entry); + } + EXPORT_SYMBOL_GPL(rt2x00lib_txdone); + +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-12-rt2x00-add-txdone-nomatch-function.patch b/package/kernel/mac80211/patches/020-12-rt2x00-add-txdone-nomatch-function.patch new file mode 100644 index 0000000000..7bec546a9e --- /dev/null +++ b/package/kernel/mac80211/patches/020-12-rt2x00-add-txdone-nomatch-function.patch @@ -0,0 +1,92 @@ +From a09305d052166cb489402a63a5d275e954e0b923 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 15 Feb 2017 10:25:08 +0100 +Subject: [PATCH 12/19] rt2x00: add txdone nomatch function + +This txdone nomatch function will be used when we get status from the HW, +but we could not match it with any sent skb. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2x00.h | 2 ++ + drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 50 ++++++++++++++++++++++++++ + 2 files changed, 52 insertions(+) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +index 340787894c69..91ba10fdf732 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -1425,6 +1425,8 @@ void rt2x00lib_dmastart(struct queue_entry *entry); + void rt2x00lib_dmadone(struct queue_entry *entry); + void rt2x00lib_txdone(struct queue_entry *entry, + struct txdone_entry_desc *txdesc); ++void rt2x00lib_txdone_nomatch(struct queue_entry *entry, ++ struct txdone_entry_desc *txdesc); + void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status); + void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp); + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +index 03b368ac9cb6..90fc259fb5bc 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -417,6 +417,56 @@ static void rt2x00lib_clear_entry(struct rt2x00_dev *rt2x00dev, + spin_unlock_bh(&entry->queue->tx_lock); + } + ++void rt2x00lib_txdone_nomatch(struct queue_entry *entry, ++ struct txdone_entry_desc *txdesc) ++{ ++ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; ++ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); ++ struct ieee80211_tx_info txinfo = {}; ++ bool success; ++ ++ /* ++ * Unmap the skb. ++ */ ++ rt2x00queue_unmap_skb(entry); ++ ++ /* ++ * Signal that the TX descriptor is no longer in the skb. ++ */ ++ skbdesc->flags &= ~SKBDESC_DESC_IN_SKB; ++ ++ /* ++ * Send frame to debugfs immediately, after this call is completed ++ * we are going to overwrite the skb->cb array. ++ */ ++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry); ++ ++ /* ++ * Determine if the frame has been successfully transmitted and ++ * remove BARs from our check list while checking for their ++ * TX status. ++ */ ++ success = ++ rt2x00lib_txdone_bar_status(entry) || ++ test_bit(TXDONE_SUCCESS, &txdesc->flags); ++ ++ if (!test_bit(TXDONE_UNKNOWN, &txdesc->flags)) { ++ /* ++ * Update TX statistics. ++ */ ++ rt2x00dev->link.qual.tx_success += success; ++ rt2x00dev->link.qual.tx_failed += !success; ++ ++ rt2x00lib_fill_tx_status(rt2x00dev, &txinfo, skbdesc, txdesc, ++ success); ++ ieee80211_tx_status_noskb(rt2x00dev->hw, skbdesc->sta, &txinfo); ++ } ++ ++ dev_kfree_skb_any(entry->skb); ++ rt2x00lib_clear_entry(rt2x00dev, entry); ++} ++EXPORT_SYMBOL_GPL(rt2x00lib_txdone_nomatch); ++ + void rt2x00lib_txdone(struct queue_entry *entry, + struct txdone_entry_desc *txdesc) + { +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-13-rt2x00-fixup-fill_tx_status-for-nomatch-case.patch b/package/kernel/mac80211/patches/020-13-rt2x00-fixup-fill_tx_status-for-nomatch-case.patch new file mode 100644 index 0000000000..bb35f2d300 --- /dev/null +++ b/package/kernel/mac80211/patches/020-13-rt2x00-fixup-fill_tx_status-for-nomatch-case.patch @@ -0,0 +1,54 @@ +From ec80ad70d778af7665992672896633ebd3b02ac8 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 15 Feb 2017 10:25:09 +0100 +Subject: [PATCH 13/19] rt2x00: fixup fill_tx_status for nomatch case + +Add bits rt2x00lib_fill_tx_status() when filling status in nomatch +case and hopefully do not break the function for existing cases. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 6 +++++- + drivers/net/wireless/ralink/rt2x00/rt2x00queue.h | 1 + + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +index 90fc259fb5bc..e95d2aad3b3f 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -357,6 +357,9 @@ static void rt2x00lib_fill_tx_status(struct rt2x00_dev *rt2x00dev, + if (i < (IEEE80211_TX_MAX_RATES - 1)) + tx_info->status.rates[i].idx = -1; /* terminate */ + ++ if (test_bit(TXDONE_NO_ACK_REQ, &txdesc->flags)) ++ tx_info->flags |= IEEE80211_TX_CTL_NO_ACK; ++ + if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) { + if (success) + tx_info->flags |= IEEE80211_TX_STAT_ACK; +@@ -375,7 +378,8 @@ static void rt2x00lib_fill_tx_status(struct rt2x00_dev *rt2x00dev, + */ + if (test_bit(TXDONE_AMPDU, &txdesc->flags) || + tx_info->flags & IEEE80211_TX_CTL_AMPDU) { +- tx_info->flags |= IEEE80211_TX_STAT_AMPDU; ++ tx_info->flags |= IEEE80211_TX_STAT_AMPDU | ++ IEEE80211_TX_CTL_AMPDU; + tx_info->status.ampdu_len = 1; + tx_info->status.ampdu_ack_len = success ? 1 : 0; + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h +index 9b297fce4692..c78fb8c8838a 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h +@@ -215,6 +215,7 @@ enum txdone_entry_desc_flags { + TXDONE_FAILURE, + TXDONE_EXCESSIVE_RETRY, + TXDONE_AMPDU, ++ TXDONE_NO_ACK_REQ, + }; + + /** +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-14-rt2x00-use-txdone_nomatch-on-rt2800usb.patch b/package/kernel/mac80211/patches/020-14-rt2x00-use-txdone_nomatch-on-rt2800usb.patch new file mode 100644 index 0000000000..f4e4b8b075 --- /dev/null +++ b/package/kernel/mac80211/patches/020-14-rt2x00-use-txdone_nomatch-on-rt2800usb.patch @@ -0,0 +1,191 @@ +From 293dff78ee058ec1e0b90e05a803c512b6a2097f Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 15 Feb 2017 10:25:10 +0100 +Subject: [PATCH 14/19] rt2x00: use txdone_nomatch on rt2800usb + +If we do not match skb entry, provide tx status via nomatch procedure. + +Currently in that case we do rt2x00lib_txdone_noinfo(TXDONE_NOINFO), +which actually assume that entry->skb was posted without retries and +provide rate saved in skb desc as successful. Patch changed that to +rate read from TX_STAT_FIFO, however still do not provide correct +number of retries. + +On SoC/PCI devices we keep providing status via standard txdone +procedure, no change in those devices, though we should thing about it. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 31 ++++++++++++++++++++----- + drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 3 ++- + drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 2 +- + drivers/net/wireless/ralink/rt2x00/rt2800usb.c | 18 ++++++-------- + 4 files changed, 35 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +index 46405cce35e0..4a7bec708a13 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -852,7 +852,8 @@ void rt2800_process_rxwi(struct queue_entry *entry, + } + EXPORT_SYMBOL_GPL(rt2800_process_rxwi); + +-void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi) ++void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi, ++ bool match) + { + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; +@@ -860,8 +861,7 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi) + struct txdone_entry_desc txdesc; + u32 word; + u16 mcs, real_mcs; +- int aggr, ampdu; +- int wcid; ++ int aggr, ampdu, wcid, ack_req; + + /* + * Obtain the status about this packet. +@@ -875,6 +875,7 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi) + real_mcs = rt2x00_get_field32(status, TX_STA_FIFO_MCS); + aggr = rt2x00_get_field32(status, TX_STA_FIFO_TX_AGGRE); + wcid = rt2x00_get_field32(status, TX_STA_FIFO_WCID); ++ ack_req = rt2x00_get_field32(status, TX_STA_FIFO_TX_ACK_REQUIRED); + + /* + * If a frame was meant to be sent as a single non-aggregated MPDU +@@ -891,8 +892,12 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi) + * Hence, replace the requested rate with the real tx rate to not + * confuse the rate control algortihm by providing clearly wrong + * data. +- */ +- if (unlikely(aggr == 1 && ampdu == 0 && real_mcs != mcs)) { ++ * ++ * FIXME: if we do not find matching entry, we tell that frame was ++ * posted without any retries. We need to find a way to fix that ++ * and provide retry count. ++ */ ++ if (unlikely((aggr == 1 && ampdu == 0 && real_mcs != mcs)) || !match) { + skbdesc->tx_rate_idx = real_mcs; + mcs = real_mcs; + } +@@ -900,6 +905,9 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi) + if (aggr == 1 || ampdu == 1) + __set_bit(TXDONE_AMPDU, &txdesc.flags); + ++ if (!ack_req) ++ __set_bit(TXDONE_NO_ACK_REQ, &txdesc.flags); ++ + /* + * Ralink has a retry mechanism using a global fallback + * table. We setup this fallback table to try the immediate +@@ -931,7 +939,18 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi) + if (txdesc.retry) + __set_bit(TXDONE_FALLBACK, &txdesc.flags); + +- rt2x00lib_txdone(entry, &txdesc); ++ if (!match) { ++ /* RCU assures non-null sta will not be freed by mac80211. */ ++ rcu_read_lock(); ++ if (likely(wcid >= WCID_START && wcid <= WCID_END)) ++ skbdesc->sta = drv_data->wcid_to_sta[wcid - WCID_START]; ++ else ++ skbdesc->sta = NULL; ++ rt2x00lib_txdone_nomatch(entry, &txdesc); ++ rcu_read_unlock(); ++ } else { ++ rt2x00lib_txdone(entry, &txdesc); ++ } + } + EXPORT_SYMBOL_GPL(rt2800_txdone_entry); + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +index 6811d677a6e7..d9ef260d542a 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +@@ -191,7 +191,8 @@ void rt2800_write_tx_data(struct queue_entry *entry, + struct txentry_desc *txdesc); + void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc); + +-void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32* txwi); ++void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi, ++ bool match); + + void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); + void rt2800_clear_beacon(struct queue_entry *entry); +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c +index de4790b41be7..3ab3b5323897 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c +@@ -239,7 +239,7 @@ static bool rt2800mmio_txdone_release_entries(struct queue_entry *entry, + { + if (test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) { + rt2800_txdone_entry(entry, entry->status, +- rt2800mmio_get_txwi(entry)); ++ rt2800mmio_get_txwi(entry), true); + return false; + } + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c +index 205a7b8ac8a7..f11e3f532a84 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c +@@ -501,8 +501,7 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry) + /* + * TX control handlers + */ +-static enum txdone_entry_desc_flags +-rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) ++static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) + { + __le32 *txwi; + u32 word; +@@ -515,7 +514,7 @@ rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) + * frame. + */ + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) +- return TXDONE_FAILURE; ++ return false; + + wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); + ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); +@@ -537,10 +536,10 @@ rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) + rt2x00_dbg(entry->queue->rt2x00dev, + "TX status report missed for queue %d entry %d\n", + entry->queue->qid, entry->entry_idx); +- return TXDONE_UNKNOWN; ++ return false; + } + +- return TXDONE_SUCCESS; ++ return true; + } + + static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) +@@ -549,7 +548,7 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) + struct queue_entry *entry; + u32 reg; + u8 qid; +- enum txdone_entry_desc_flags done_status; ++ bool match; + + while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { + /* +@@ -574,11 +573,8 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) + break; + } + +- done_status = rt2800usb_txdone_entry_check(entry, reg); +- if (likely(done_status == TXDONE_SUCCESS)) +- rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry)); +- else +- rt2x00lib_txdone_noinfo(entry, done_status); ++ match = rt2800usb_txdone_entry_check(entry, reg); ++ rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry), match); + } + } + +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-15-rt2800-status-based-rate-flags-for-nomatch-case.patch b/package/kernel/mac80211/patches/020-15-rt2800-status-based-rate-flags-for-nomatch-case.patch new file mode 100644 index 0000000000..4e18dc8e2a --- /dev/null +++ b/package/kernel/mac80211/patches/020-15-rt2800-status-based-rate-flags-for-nomatch-case.patch @@ -0,0 +1,88 @@ +From 9d7a7a4d2b02bcd30fb5fe4270278212353cc332 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 15 Feb 2017 10:25:11 +0100 +Subject: [PATCH 15/19] rt2800: status based rate flags for nomatch case + +We use skb_desc->tx_rate_flags from entry as rate[].flags even if +skb does not match status. Patch corrects flags and also fixes +mcs for legacy rates. + +rt2800_rate_from_status() is based on Felix's mt76 +mt76x2_mac_process_tx_rate() function. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2800.h | 2 ++ + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 35 +++++++++++++++++++++++++- + 2 files changed, 36 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800.h b/drivers/net/wireless/ralink/rt2x00/rt2800.h +index 0e7051d8132f..480b08601785 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -1760,6 +1760,8 @@ + #define TX_STA_FIFO_WCID FIELD32(0x0000ff00) + #define TX_STA_FIFO_SUCCESS_RATE FIELD32(0xffff0000) + #define TX_STA_FIFO_MCS FIELD32(0x007f0000) ++#define TX_STA_FIFO_BW FIELD32(0x00800000) ++#define TX_STA_FIFO_SGI FIELD32(0x01000000) + #define TX_STA_FIFO_PHYMODE FIELD32(0xc0000000) + + /* +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +index 4a7bec708a13..8d00c599e47a 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -852,6 +852,39 @@ void rt2800_process_rxwi(struct queue_entry *entry, + } + EXPORT_SYMBOL_GPL(rt2800_process_rxwi); + ++static void rt2800_rate_from_status(struct skb_frame_desc *skbdesc, ++ u32 status, enum nl80211_band band) ++{ ++ u8 flags = 0; ++ u8 idx = rt2x00_get_field32(status, TX_STA_FIFO_MCS); ++ ++ switch (rt2x00_get_field32(status, TX_STA_FIFO_PHYMODE)) { ++ case RATE_MODE_HT_GREENFIELD: ++ flags |= IEEE80211_TX_RC_GREEN_FIELD; ++ /* fall through */ ++ case RATE_MODE_HT_MIX: ++ flags |= IEEE80211_TX_RC_MCS; ++ break; ++ case RATE_MODE_OFDM: ++ if (band == NL80211_BAND_2GHZ) ++ idx += 4; ++ break; ++ case RATE_MODE_CCK: ++ if (idx >= 8) ++ idx -= 8; ++ break; ++ } ++ ++ if (rt2x00_get_field32(status, TX_STA_FIFO_BW)) ++ flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; ++ ++ if (rt2x00_get_field32(status, TX_STA_FIFO_SGI)) ++ flags |= IEEE80211_TX_RC_SHORT_GI; ++ ++ skbdesc->tx_rate_idx = idx; ++ skbdesc->tx_rate_flags = flags; ++} ++ + void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi, + bool match) + { +@@ -898,7 +931,7 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi, + * and provide retry count. + */ + if (unlikely((aggr == 1 && ampdu == 0 && real_mcs != mcs)) || !match) { +- skbdesc->tx_rate_idx = real_mcs; ++ rt2800_rate_from_status(skbdesc, status, rt2x00dev->curr_band); + mcs = real_mcs; + } + +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-16-rt2800-use-TXOP_BACKOFF-for-probe-frames.patch b/package/kernel/mac80211/patches/020-16-rt2800-use-TXOP_BACKOFF-for-probe-frames.patch new file mode 100644 index 0000000000..31d79bb751 --- /dev/null +++ b/package/kernel/mac80211/patches/020-16-rt2800-use-TXOP_BACKOFF-for-probe-frames.patch @@ -0,0 +1,43 @@ +From fb47ada8dc3c30c8e7b415da155742b49536c61e Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 15 Feb 2017 10:25:12 +0100 +Subject: [PATCH 16/19] rt2800: use TXOP_BACKOFF for probe frames + +Even if we do not set AMPDU bit in TXWI, device still can aggregate +frame and send it with rate not corresponding to requested. That mean +we can do not sent probe frames with requested rate. To prevent that +use TXOP_BACKOFF for probe frames. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c +index e1660b92b20c..a2c1ca5c76d1 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c +@@ -372,15 +372,16 @@ static void rt2x00queue_create_tx_descriptor_ht(struct rt2x00_dev *rt2x00dev, + + /* + * Determine IFS values +- * - Use TXOP_BACKOFF for management frames except beacons ++ * - Use TXOP_BACKOFF for probe and management frames except beacons + * - Use TXOP_SIFS for fragment bursts + * - Use TXOP_HTTXOP for everything else + * + * Note: rt2800 devices won't use CTS protection (if used) + * for frames not transmitted with TXOP_HTTXOP + */ +- if (ieee80211_is_mgmt(hdr->frame_control) && +- !ieee80211_is_beacon(hdr->frame_control)) ++ if ((ieee80211_is_mgmt(hdr->frame_control) && ++ !ieee80211_is_beacon(hdr->frame_control)) || ++ (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) + txdesc->u.ht.txop = TXOP_BACKOFF; + else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)) + txdesc->u.ht.txop = TXOP_SIFS; +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-17-rt2x00-fix-rt2x00debug_dump_frame-comment.patch b/package/kernel/mac80211/patches/020-17-rt2x00-fix-rt2x00debug_dump_frame-comment.patch new file mode 100644 index 0000000000..4e53092d12 --- /dev/null +++ b/package/kernel/mac80211/patches/020-17-rt2x00-fix-rt2x00debug_dump_frame-comment.patch @@ -0,0 +1,28 @@ +From dd35cc0896faff5ed9d22eac9ea4a1920e2eec0c Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 15 Feb 2017 10:25:13 +0100 +Subject: [PATCH 17/19] rt2x00: fix rt2x00debug_dump_frame comment + +Reported-by: Jeroen Roovers +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2x00.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +index 91ba10fdf732..ce340bfd71a0 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -1396,7 +1396,7 @@ void rt2x00queue_flush_queues(struct rt2x00_dev *rt2x00dev, bool drop); + * rt2x00debug_dump_frame - Dump a frame to userspace through debugfs. + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * @type: The type of frame that is being dumped. +- * @skb: The skb containing the frame to be dumped. ++ * @entry: The queue entry containing the frame to be dumped. + */ + #ifdef CPTCFG_RT2X00_LIB_DEBUGFS + void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-18-rt2x00-fix-TX_PWR_CFG_4-register-definition.patch b/package/kernel/mac80211/patches/020-18-rt2x00-fix-TX_PWR_CFG_4-register-definition.patch new file mode 100644 index 0000000000..3cf342d690 --- /dev/null +++ b/package/kernel/mac80211/patches/020-18-rt2x00-fix-TX_PWR_CFG_4-register-definition.patch @@ -0,0 +1,37 @@ +From 5ce33b603063f36272fcfb1b4a5fde69f46eca88 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Thu, 9 Mar 2017 00:54:22 +0100 +Subject: [PATCH 18/19] rt2x00: fix TX_PWR_CFG_4 register definition + +Some of the macros used to describe the TX_PWR_CFG_4 register accidentally +refer to TX_PWR_CFG_3, probably a copy&paste error. Fix that. + +Signed-off-by: Daniel Golle +Acked-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2800.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800.h b/drivers/net/wireless/ralink/rt2x00/rt2800.h +index 480b08601785..fd1dbd956bad 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -1171,10 +1171,10 @@ + #define TX_PWR_CFG_4_UKNOWN7 FIELD32(0x00000f00) + #define TX_PWR_CFG_4_UKNOWN8 FIELD32(0x0000f000) + /* bits for 3T devices */ +-#define TX_PWR_CFG_3_STBC4_CH0 FIELD32(0x0000000f) +-#define TX_PWR_CFG_3_STBC4_CH1 FIELD32(0x000000f0) +-#define TX_PWR_CFG_3_STBC6_CH0 FIELD32(0x00000f00) +-#define TX_PWR_CFG_3_STBC6_CH1 FIELD32(0x0000f000) ++#define TX_PWR_CFG_4_STBC4_CH0 FIELD32(0x0000000f) ++#define TX_PWR_CFG_4_STBC4_CH1 FIELD32(0x000000f0) ++#define TX_PWR_CFG_4_STBC6_CH0 FIELD32(0x00000f00) ++#define TX_PWR_CFG_4_STBC6_CH1 FIELD32(0x0000f000) + + /* + * TX_PIN_CFG: +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/020-19-rt2x00-add-support-for-MT7620.patch b/package/kernel/mac80211/patches/020-19-rt2x00-add-support-for-MT7620.patch new file mode 100644 index 0000000000..7b99312744 --- /dev/null +++ b/package/kernel/mac80211/patches/020-19-rt2x00-add-support-for-MT7620.patch @@ -0,0 +1,2077 @@ +From 41977e86c984fcdddb454a3d7887de5d47b5f530 Mon Sep 17 00:00:00 2001 +From: Roman Yeryomin +Date: Tue, 21 Mar 2017 00:43:00 +0100 +Subject: [PATCH 19/19] rt2x00: add support for MT7620 + +Basic support for MT7620 built-in wireless radio was added to +OpenWrt in r41441. It has seen some heavy cleaning and refactoring +since in order to match the Kernel's code quality standards. + +Signed-off-by: Roman Yeryomin +Signed-off-by: Daniel Golle +Acked-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/Kconfig | 2 +- + drivers/net/wireless/ralink/rt2x00/rt2800.h | 177 +++ + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 1421 +++++++++++++++++++++++- + drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 4 + + drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 + + 5 files changed, 1578 insertions(+), 27 deletions(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/Kconfig b/drivers/net/wireless/ralink/rt2x00/Kconfig +index de62f5dcb62f..a1d1cfe214d2 100644 +--- a/drivers/net/wireless/ralink/rt2x00/Kconfig ++++ b/drivers/net/wireless/ralink/rt2x00/Kconfig +@@ -210,7 +210,7 @@ endif + config RT2800SOC + tristate "Ralink WiSoC support" + depends on m +- depends on SOC_RT288X || SOC_RT305X ++ depends on SOC_RT288X || SOC_RT305X || SOC_MT7620 + select RT2X00_LIB_SOC + select RT2X00_LIB_MMIO + select RT2X00_LIB_CRYPTO +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800.h b/drivers/net/wireless/ralink/rt2x00/rt2800.h +index fd1dbd956bad..6a8c93fb6a43 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -79,6 +79,7 @@ + #define RF5372 0x5372 + #define RF5390 0x5390 + #define RF5392 0x5392 ++#define RF7620 0x7620 + + /* + * Chipset revisions. +@@ -639,6 +640,24 @@ + #define RF_CSR_CFG_BUSY FIELD32(0x00020000) + + /* ++ * MT7620 RF registers (reversed order) ++ */ ++#define RF_CSR_CFG_DATA_MT7620 FIELD32(0x0000ff00) ++#define RF_CSR_CFG_REGNUM_MT7620 FIELD32(0x03ff0000) ++#define RF_CSR_CFG_WRITE_MT7620 FIELD32(0x00000010) ++#define RF_CSR_CFG_BUSY_MT7620 FIELD32(0x00000001) ++ ++/* undocumented registers for calibration of new MAC */ ++#define RF_CONTROL0 0x0518 ++#define RF_BYPASS0 0x051c ++#define RF_CONTROL1 0x0520 ++#define RF_BYPASS1 0x0524 ++#define RF_CONTROL2 0x0528 ++#define RF_BYPASS2 0x052c ++#define RF_CONTROL3 0x0530 ++#define RF_BYPASS3 0x0534 ++ ++/* + * EFUSE_CSR: RT30x0 EEPROM + */ + #define EFUSE_CTRL 0x0580 +@@ -1022,6 +1041,16 @@ + #define AUTOWAKEUP_CFG_AUTOWAKE FIELD32(0x00008000) + + /* ++ * MIMO_PS_CFG: MIMO Power-save Configuration ++ */ ++#define MIMO_PS_CFG 0x1210 ++#define MIMO_PS_CFG_MMPS_BB_EN FIELD32(0x00000001) ++#define MIMO_PS_CFG_MMPS_RX_ANT_NUM FIELD32(0x00000006) ++#define MIMO_PS_CFG_MMPS_RF_EN FIELD32(0x00000008) ++#define MIMO_PS_CFG_RX_STBY_POL FIELD32(0x00000010) ++#define MIMO_PS_CFG_RX_RX_STBY0 FIELD32(0x00000020) ++ ++/* + * EDCA_AC0_CFG: + */ + #define EDCA_AC0_CFG 0x1300 +@@ -1095,6 +1124,12 @@ + #define TX_PWR_CFG_0_OFDM6_CH1 FIELD32(0x00f00000) + #define TX_PWR_CFG_0_OFDM12_CH0 FIELD32(0x0f000000) + #define TX_PWR_CFG_0_OFDM12_CH1 FIELD32(0xf0000000) ++/* bits for new 2T devices */ ++#define TX_PWR_CFG_0B_1MBS_2MBS FIELD32(0x000000ff) ++#define TX_PWR_CFG_0B_5MBS_11MBS FIELD32(0x0000ff00) ++#define TX_PWR_CFG_0B_6MBS_9MBS FIELD32(0x00ff0000) ++#define TX_PWR_CFG_0B_12MBS_18MBS FIELD32(0xff000000) ++ + + /* + * TX_PWR_CFG_1: +@@ -1117,6 +1152,11 @@ + #define TX_PWR_CFG_1_MCS0_CH1 FIELD32(0x00f00000) + #define TX_PWR_CFG_1_MCS2_CH0 FIELD32(0x0f000000) + #define TX_PWR_CFG_1_MCS2_CH1 FIELD32(0xf0000000) ++/* bits for new 2T devices */ ++#define TX_PWR_CFG_1B_24MBS_36MBS FIELD32(0x000000ff) ++#define TX_PWR_CFG_1B_48MBS FIELD32(0x0000ff00) ++#define TX_PWR_CFG_1B_MCS0_MCS1 FIELD32(0x00ff0000) ++#define TX_PWR_CFG_1B_MCS2_MCS3 FIELD32(0xff000000) + + /* + * TX_PWR_CFG_2: +@@ -1139,6 +1179,11 @@ + #define TX_PWR_CFG_2_MCS8_CH1 FIELD32(0x00f00000) + #define TX_PWR_CFG_2_MCS10_CH0 FIELD32(0x0f000000) + #define TX_PWR_CFG_2_MCS10_CH1 FIELD32(0xf0000000) ++/* bits for new 2T devices */ ++#define TX_PWR_CFG_2B_MCS4_MCS5 FIELD32(0x000000ff) ++#define TX_PWR_CFG_2B_MCS6_MCS7 FIELD32(0x0000ff00) ++#define TX_PWR_CFG_2B_MCS8_MCS9 FIELD32(0x00ff0000) ++#define TX_PWR_CFG_2B_MCS10_MCS11 FIELD32(0xff000000) + + /* + * TX_PWR_CFG_3: +@@ -1161,6 +1206,11 @@ + #define TX_PWR_CFG_3_STBC0_CH1 FIELD32(0x00f00000) + #define TX_PWR_CFG_3_STBC2_CH0 FIELD32(0x0f000000) + #define TX_PWR_CFG_3_STBC2_CH1 FIELD32(0xf0000000) ++/* bits for new 2T devices */ ++#define TX_PWR_CFG_3B_MCS12_MCS13 FIELD32(0x000000ff) ++#define TX_PWR_CFG_3B_MCS14 FIELD32(0x0000ff00) ++#define TX_PWR_CFG_3B_STBC_MCS0_MCS1 FIELD32(0x00ff0000) ++#define TX_PWR_CFG_3B_STBC_MCS2_MSC3 FIELD32(0xff000000) + + /* + * TX_PWR_CFG_4: +@@ -1175,6 +1225,9 @@ + #define TX_PWR_CFG_4_STBC4_CH1 FIELD32(0x000000f0) + #define TX_PWR_CFG_4_STBC6_CH0 FIELD32(0x00000f00) + #define TX_PWR_CFG_4_STBC6_CH1 FIELD32(0x0000f000) ++/* bits for new 2T devices */ ++#define TX_PWR_CFG_4B_STBC_MCS4_MCS5 FIELD32(0x000000ff) ++#define TX_PWR_CFG_4B_STBC_MCS6 FIELD32(0x0000ff00) + + /* + * TX_PIN_CFG: +@@ -1201,6 +1254,8 @@ + #define TX_PIN_CFG_RFTR_POL FIELD32(0x00020000) + #define TX_PIN_CFG_TRSW_EN FIELD32(0x00040000) + #define TX_PIN_CFG_TRSW_POL FIELD32(0x00080000) ++#define TX_PIN_CFG_RFRX_EN FIELD32(0x00100000) ++#define TX_PIN_CFG_RFRX_POL FIELD32(0x00200000) + #define TX_PIN_CFG_PA_PE_A2_EN FIELD32(0x01000000) + #define TX_PIN_CFG_PA_PE_G2_EN FIELD32(0x02000000) + #define TX_PIN_CFG_PA_PE_A2_POL FIELD32(0x04000000) +@@ -1547,6 +1602,95 @@ + #define TX_PWR_CFG_4_EXT_STBC4_CH2 FIELD32(0x0000000f) + #define TX_PWR_CFG_4_EXT_STBC6_CH2 FIELD32(0x00000f00) + ++/* TXn_RF_GAIN_CORRECT: RF Gain Correction for each RF_ALC[3:2] ++ * Unit: 0.1 dB, Range: -3.2 dB to 3.1 dB ++ */ ++#define TX0_RF_GAIN_CORRECT 0x13a0 ++#define TX0_RF_GAIN_CORRECT_GAIN_CORR_0 FIELD32(0x0000003f) ++#define TX0_RF_GAIN_CORRECT_GAIN_CORR_1 FIELD32(0x00003f00) ++#define TX0_RF_GAIN_CORRECT_GAIN_CORR_2 FIELD32(0x003f0000) ++#define TX0_RF_GAIN_CORRECT_GAIN_CORR_3 FIELD32(0x3f000000) ++ ++#define TX1_RF_GAIN_CORRECT 0x13a4 ++#define TX1_RF_GAIN_CORRECT_GAIN_CORR_0 FIELD32(0x0000003f) ++#define TX1_RF_GAIN_CORRECT_GAIN_CORR_1 FIELD32(0x00003f00) ++#define TX1_RF_GAIN_CORRECT_GAIN_CORR_2 FIELD32(0x003f0000) ++#define TX1_RF_GAIN_CORRECT_GAIN_CORR_3 FIELD32(0x3f000000) ++ ++/* TXn_RF_GAIN_ATTEN: TXn RF Gain Attenuation Level ++ * Format: 7-bit, signed value ++ * Unit: 0.5 dB, Range: -20 dB to -5 dB ++ */ ++#define TX0_RF_GAIN_ATTEN 0x13a8 ++#define TX0_RF_GAIN_ATTEN_LEVEL_0 FIELD32(0x0000007f) ++#define TX0_RF_GAIN_ATTEN_LEVEL_1 FIELD32(0x00007f00) ++#define TX0_RF_GAIN_ATTEN_LEVEL_2 FIELD32(0x007f0000) ++#define TX0_RF_GAIN_ATTEN_LEVEL_3 FIELD32(0x7f000000) ++#define TX1_RF_GAIN_ATTEN 0x13ac ++#define TX1_RF_GAIN_ATTEN_LEVEL_0 FIELD32(0x0000007f) ++#define TX1_RF_GAIN_ATTEN_LEVEL_1 FIELD32(0x00007f00) ++#define TX1_RF_GAIN_ATTEN_LEVEL_2 FIELD32(0x007f0000) ++#define TX1_RF_GAIN_ATTEN_LEVEL_3 FIELD32(0x7f000000) ++ ++/* TX_ALC_CFG_0: TX Automatic Level Control Configuration 0 ++ * TX_ALC_LIMIT_n: TXn upper limit ++ * TX_ALC_CH_INIT_n: TXn channel initial transmission gain ++ * Unit: 0.5 dB, Range: 0 to 23.5 dB ++ */ ++#define TX_ALC_CFG_0 0x13b0 ++#define TX_ALC_CFG_0_CH_INIT_0 FIELD32(0x0000003f) ++#define TX_ALC_CFG_0_CH_INIT_1 FIELD32(0x00003f00) ++#define TX_ALC_CFG_0_LIMIT_0 FIELD32(0x003f0000) ++#define TX_ALC_CFG_0_LIMIT_1 FIELD32(0x3f000000) ++ ++/* TX_ALC_CFG_1: TX Automatic Level Control Configuration 1 ++ * TX_TEMP_COMP: TX Power Temperature Compensation ++ * Unit: 0.5 dB, Range: -10 dB to 10 dB ++ * TXn_GAIN_FINE: TXn Gain Fine Adjustment ++ * Unit: 0.1 dB, Range: -0.8 dB to 0.7 dB ++ * RF_TOS_DLY: Sets the RF_TOS_EN assertion delay after ++ * deassertion of PA_PE. ++ * Unit: 0.25 usec ++ * TXn_RF_GAIN_ATTEN: TXn RF gain attentuation selector ++ * RF_TOS_TIMEOUT: time-out value for RF_TOS_ENABLE ++ * deassertion if RF_TOS_DONE is missing. ++ * Unit: 0.25 usec ++ * RF_TOS_ENABLE: TX offset calibration enable ++ * ROS_BUSY_EN: RX offset calibration busy enable ++ */ ++#define TX_ALC_CFG_1 0x13b4 ++#define TX_ALC_CFG_1_TX_TEMP_COMP FIELD32(0x0000003f) ++#define TX_ALC_CFG_1_TX0_GAIN_FINE FIELD32(0x00000f00) ++#define TX_ALC_CFG_1_TX1_GAIN_FINE FIELD32(0x0000f000) ++#define TX_ALC_CFG_1_RF_TOS_DLY FIELD32(0x00070000) ++#define TX_ALC_CFG_1_TX0_RF_GAIN_ATTEN FIELD32(0x00300000) ++#define TX_ALC_CFG_1_TX1_RF_GAIN_ATTEN FIELD32(0x00c00000) ++#define TX_ALC_CFG_1_RF_TOS_TIMEOUT FIELD32(0x3f000000) ++#define TX_ALC_CFG_1_RF_TOS_ENABLE FIELD32(0x40000000) ++#define TX_ALC_CFG_1_ROS_BUSY_EN FIELD32(0x80000000) ++ ++/* TXn_BB_GAIN_ATTEN: TXn RF Gain Attenuation Level ++ * Format: 5-bit signed values ++ * Unit: 0.5 dB, Range: -8 dB to 7 dB ++ */ ++#define TX0_BB_GAIN_ATTEN 0x13c0 ++#define TX0_BB_GAIN_ATTEN_LEVEL_0 FIELD32(0x0000001f) ++#define TX0_BB_GAIN_ATTEN_LEVEL_1 FIELD32(0x00001f00) ++#define TX0_BB_GAIN_ATTEN_LEVEL_2 FIELD32(0x001f0000) ++#define TX0_BB_GAIN_ATTEN_LEVEL_3 FIELD32(0x1f000000) ++#define TX1_BB_GAIN_ATTEN 0x13c4 ++#define TX1_BB_GAIN_ATTEN_LEVEL_0 FIELD32(0x0000001f) ++#define TX1_BB_GAIN_ATTEN_LEVEL_1 FIELD32(0x00001f00) ++#define TX1_BB_GAIN_ATTEN_LEVEL_2 FIELD32(0x001f0000) ++#define TX1_BB_GAIN_ATTEN_LEVEL_3 FIELD32(0x1f000000) ++ ++/* TX_ALC_VGA3: TX Automatic Level Correction Variable Gain Amplifier 3 */ ++#define TX_ALC_VGA3 0x13c8 ++#define TX_ALC_VGA3_TX0_ALC_VGA3 FIELD32(0x0000001f) ++#define TX_ALC_VGA3_TX1_ALC_VGA3 FIELD32(0x00001f00) ++#define TX_ALC_VGA3_TX0_ALC_VGA2 FIELD32(0x001f0000) ++#define TX_ALC_VGA3_TX1_ALC_VGA2 FIELD32(0x1f000000) ++ + /* TX_PWR_CFG_7 */ + #define TX_PWR_CFG_7 0x13d4 + #define TX_PWR_CFG_7_OFDM54_CH0 FIELD32(0x0000000f) +@@ -1555,6 +1699,10 @@ + #define TX_PWR_CFG_7_MCS7_CH0 FIELD32(0x000f0000) + #define TX_PWR_CFG_7_MCS7_CH1 FIELD32(0x00f00000) + #define TX_PWR_CFG_7_MCS7_CH2 FIELD32(0x0f000000) ++/* bits for new 2T devices */ ++#define TX_PWR_CFG_7B_54MBS FIELD32(0x000000ff) ++#define TX_PWR_CFG_7B_MCS7 FIELD32(0x00ff0000) ++ + + /* TX_PWR_CFG_8 */ + #define TX_PWR_CFG_8 0x13d8 +@@ -1564,12 +1712,17 @@ + #define TX_PWR_CFG_8_MCS23_CH0 FIELD32(0x000f0000) + #define TX_PWR_CFG_8_MCS23_CH1 FIELD32(0x00f00000) + #define TX_PWR_CFG_8_MCS23_CH2 FIELD32(0x0f000000) ++/* bits for new 2T devices */ ++#define TX_PWR_CFG_8B_MCS15 FIELD32(0x000000ff) ++ + + /* TX_PWR_CFG_9 */ + #define TX_PWR_CFG_9 0x13dc + #define TX_PWR_CFG_9_STBC7_CH0 FIELD32(0x0000000f) + #define TX_PWR_CFG_9_STBC7_CH1 FIELD32(0x000000f0) + #define TX_PWR_CFG_9_STBC7_CH2 FIELD32(0x00000f00) ++/* bits for new 2T devices */ ++#define TX_PWR_CFG_9B_STBC_MCS7 FIELD32(0x000000ff) + + /* + * RX_FILTER_CFG: RX configuration register. +@@ -2137,11 +2290,14 @@ struct mac_iveiv_entry { + #define RFCSR1_TX1_PD FIELD8(0x20) + #define RFCSR1_RX2_PD FIELD8(0x40) + #define RFCSR1_TX2_PD FIELD8(0x80) ++#define RFCSR1_TX2_EN_MT7620 FIELD8(0x02) + + /* + * RFCSR 2: + */ + #define RFCSR2_RESCAL_EN FIELD8(0x80) ++#define RFCSR2_RX2_EN_MT7620 FIELD8(0x02) ++#define RFCSR2_TX2_EN_MT7620 FIELD8(0x20) + + /* + * RFCSR 3: +@@ -2160,6 +2316,12 @@ struct mac_iveiv_entry { + #define RFCSR3_BIT5 FIELD8(0x20) + + /* ++ * RFCSR 4: ++ * VCOCAL_EN used by MT7620 ++ */ ++#define RFCSR4_VCOCAL_EN FIELD8(0x80) ++ ++/* + * FRCSR 5: + */ + #define RFCSR5_R1 FIELD8(0x0c) +@@ -2214,6 +2376,7 @@ struct mac_iveiv_entry { + */ + #define RFCSR13_TX_POWER FIELD8(0x1f) + #define RFCSR13_DR0 FIELD8(0xe0) ++#define RFCSR13_RDIV_MT7620 FIELD8(0x03) + + /* + * RFCSR 15: +@@ -2224,6 +2387,8 @@ struct mac_iveiv_entry { + * RFCSR 16: + */ + #define RFCSR16_TXMIXER_GAIN FIELD8(0x07) ++#define RFCSR16_RF_PLL_FREQ_SEL_MT7620 FIELD8(0x0F) ++#define RFCSR16_SDM_MODE_MT7620 FIELD8(0xE0) + + /* + * RFCSR 17: +@@ -2236,6 +2401,8 @@ struct mac_iveiv_entry { + /* RFCSR 18 */ + #define RFCSR18_XO_TUNE_BYPASS FIELD8(0x40) + ++/* RFCSR 19 */ ++#define RFCSR19_K FIELD8(0x03) + + /* + * RFCSR 20: +@@ -2246,11 +2413,14 @@ struct mac_iveiv_entry { + * RFCSR 21: + */ + #define RFCSR21_RX_LO2_EN FIELD8(0x08) ++#define RFCSR21_BIT1 FIELD8(0x01) ++#define RFCSR21_BIT8 FIELD8(0x80) + + /* + * RFCSR 22: + */ + #define RFCSR22_BASEBAND_LOOPBACK FIELD8(0x01) ++#define RFCSR22_FREQPLAN_D_MT7620 FIELD8(0x07) + + /* + * RFCSR 23: +@@ -2273,6 +2443,11 @@ struct mac_iveiv_entry { + #define RFCSR27_R4 FIELD8(0x40) + + /* ++ * RFCSR 28: ++ */ ++#define RFCSR28_CH11_HT40 FIELD8(0x04) ++ ++/* + * RFCSR 29: + */ + #define RFCSR29_ADC6_TEST FIELD8(0x01) +@@ -2333,6 +2508,7 @@ struct mac_iveiv_entry { + */ + #define RFCSR42_BIT1 FIELD8(0x01) + #define RFCSR42_BIT4 FIELD8(0x08) ++#define RFCSR42_TX2_EN_MT7620 FIELD8(0x40) + + /* + * RFCSR 49: +@@ -2435,6 +2611,7 @@ enum rt2800_eeprom_word { + EEPROM_TSSI_BOUND_BG5, + EEPROM_TXPOWER_A1, + EEPROM_TXPOWER_A2, ++ EEPROM_TXPOWER_INIT, + EEPROM_TSSI_BOUND_A1, + EEPROM_TSSI_BOUND_A2, + EEPROM_TSSI_BOUND_A3, +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +index 8d00c599e47a..201b12ed90c6 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -59,6 +59,9 @@ + rt2800_regbusy_read((__dev), BBP_CSR_CFG, BBP_CSR_CFG_BUSY, (__reg)) + #define WAIT_FOR_RFCSR(__dev, __reg) \ + rt2800_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY, (__reg)) ++#define WAIT_FOR_RFCSR_MT7620(__dev, __reg) \ ++ rt2800_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY_MT7620, \ ++ (__reg)) + #define WAIT_FOR_RF(__dev, __reg) \ + rt2800_regbusy_read((__dev), RF_CSR_CFG0, RF_CSR_CFG0_BUSY, (__reg)) + #define WAIT_FOR_MCU(__dev, __reg) \ +@@ -150,19 +153,56 @@ static void rt2800_rfcsr_write(struct rt2x00_dev *rt2x00dev, + * Wait until the RFCSR becomes available, afterwards we + * can safely write the new data into the register. + */ +- if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { +- reg = 0; +- rt2x00_set_field32(®, RF_CSR_CFG_DATA, value); +- rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); +- rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 1); +- rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); ++ switch (rt2x00dev->chip.rt) { ++ case RT6352: ++ if (WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®)) { ++ reg = 0; ++ rt2x00_set_field32(®, RF_CSR_CFG_DATA_MT7620, value); ++ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM_MT7620, ++ word); ++ rt2x00_set_field32(®, RF_CSR_CFG_WRITE_MT7620, 1); ++ rt2x00_set_field32(®, RF_CSR_CFG_BUSY_MT7620, 1); ++ ++ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); ++ } ++ break; + +- rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); ++ default: ++ if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { ++ reg = 0; ++ rt2x00_set_field32(®, RF_CSR_CFG_DATA, value); ++ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); ++ rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 1); ++ rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); ++ ++ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); ++ } ++ break; + } + + mutex_unlock(&rt2x00dev->csr_mutex); + } + ++static void rt2800_rfcsr_write_bank(struct rt2x00_dev *rt2x00dev, const u8 bank, ++ const unsigned int reg, const u8 value) ++{ ++ rt2800_rfcsr_write(rt2x00dev, (reg | (bank << 6)), value); ++} ++ ++static void rt2800_rfcsr_write_chanreg(struct rt2x00_dev *rt2x00dev, ++ const unsigned int reg, const u8 value) ++{ ++ rt2800_rfcsr_write_bank(rt2x00dev, 4, reg, value); ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, reg, value); ++} ++ ++static void rt2800_rfcsr_write_dccal(struct rt2x00_dev *rt2x00dev, ++ const unsigned int reg, const u8 value) ++{ ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, reg, value); ++ rt2800_rfcsr_write_bank(rt2x00dev, 7, reg, value); ++} ++ + static void rt2800_rfcsr_read(struct rt2x00_dev *rt2x00dev, + const unsigned int word, u8 *value) + { +@@ -178,22 +218,48 @@ static void rt2800_rfcsr_read(struct rt2x00_dev *rt2x00dev, + * doesn't become available in time, reg will be 0xffffffff + * which means we return 0xff to the caller. + */ +- if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { +- reg = 0; +- rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); +- rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 0); +- rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); ++ switch (rt2x00dev->chip.rt) { ++ case RT6352: ++ if (WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®)) { ++ reg = 0; ++ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM_MT7620, ++ word); ++ rt2x00_set_field32(®, RF_CSR_CFG_WRITE_MT7620, 0); ++ rt2x00_set_field32(®, RF_CSR_CFG_BUSY_MT7620, 1); + +- rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); ++ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); + +- WAIT_FOR_RFCSR(rt2x00dev, ®); +- } ++ WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®); ++ } + +- *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA); ++ *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA_MT7620); ++ break; ++ ++ default: ++ if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { ++ reg = 0; ++ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); ++ rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 0); ++ rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); ++ ++ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); ++ ++ WAIT_FOR_RFCSR(rt2x00dev, ®); ++ } ++ ++ *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA); ++ break; ++ } + + mutex_unlock(&rt2x00dev->csr_mutex); + } + ++static void rt2800_rfcsr_read_bank(struct rt2x00_dev *rt2x00dev, const u8 bank, ++ const unsigned int reg, u8 *value) ++{ ++ rt2800_rfcsr_read(rt2x00dev, (reg | (bank << 6)), value); ++} ++ + static void rt2800_rf_write(struct rt2x00_dev *rt2x00dev, + const unsigned int word, const u32 value) + { +@@ -250,6 +316,7 @@ static const unsigned int rt2800_eeprom_map[EEPROM_WORD_COUNT] = { + [EEPROM_TSSI_BOUND_BG5] = 0x003b, + [EEPROM_TXPOWER_A1] = 0x003c, + [EEPROM_TXPOWER_A2] = 0x0053, ++ [EEPROM_TXPOWER_INIT] = 0x0068, + [EEPROM_TSSI_BOUND_A1] = 0x006a, + [EEPROM_TSSI_BOUND_A2] = 0x006b, + [EEPROM_TSSI_BOUND_A3] = 0x006c, +@@ -524,6 +591,7 @@ void rt2800_get_txwi_rxwi_size(struct rt2x00_dev *rt2x00dev, + break; + + case RT5592: ++ case RT6352: + *txwi_size = TXWI_DESC_SIZE_5WORDS; + *rxwi_size = RXWI_DESC_SIZE_6WORDS; + break; +@@ -2810,7 +2878,8 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, + rt2800_rfcsr_write(rt2x00dev, 59, + r59_nonbt_rev[idx]); + } else if (rt2x00_rt(rt2x00dev, RT5390) || +- rt2x00_rt(rt2x00dev, RT5392)) { ++ rt2x00_rt(rt2x00dev, RT5392) || ++ rt2x00_rt(rt2x00dev, RT6352)) { + static const char r59_non_bt[] = {0x8f, 0x8f, + 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, + 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86}; +@@ -3104,6 +3173,242 @@ static void rt2800_config_channel_rf55xx(struct rt2x00_dev *rt2x00dev, + rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x19 : 0x7F); + } + ++static void rt2800_config_channel_rf7620(struct rt2x00_dev *rt2x00dev, ++ struct ieee80211_conf *conf, ++ struct rf_channel *rf, ++ struct channel_info *info) ++{ ++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; ++ u8 rx_agc_fc, tx_agc_fc; ++ u8 rfcsr; ++ ++ /* Frequeny plan setting */ ++ /* Rdiv setting (set 0x03 if Xtal==20) ++ * R13[1:0] ++ */ ++ rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); ++ rt2x00_set_field8(&rfcsr, RFCSR13_RDIV_MT7620, ++ rt2800_clk_is_20mhz(rt2x00dev) ? 3 : 0); ++ rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); ++ ++ /* N setting ++ * R20[7:0] in rf->rf1 ++ * R21[0] always 0 ++ */ ++ rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr); ++ rfcsr = (rf->rf1 & 0x00ff); ++ rt2800_rfcsr_write(rt2x00dev, 20, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr); ++ rt2x00_set_field8(&rfcsr, RFCSR21_BIT1, 0); ++ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); ++ ++ /* K setting (always 0) ++ * R16[3:0] (RF PLL freq selection) ++ */ ++ rt2800_rfcsr_read(rt2x00dev, 16, &rfcsr); ++ rt2x00_set_field8(&rfcsr, RFCSR16_RF_PLL_FREQ_SEL_MT7620, 0); ++ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); ++ ++ /* D setting (always 0) ++ * R22[2:0] (D=15, R22[2:0]=<111>) ++ */ ++ rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); ++ rt2x00_set_field8(&rfcsr, RFCSR22_FREQPLAN_D_MT7620, 0); ++ rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); ++ ++ /* Ksd setting ++ * Ksd: R17<7:0> in rf->rf2 ++ * R18<7:0> in rf->rf3 ++ * R19<1:0> in rf->rf4 ++ */ ++ rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); ++ rfcsr = rf->rf2; ++ rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 18, &rfcsr); ++ rfcsr = rf->rf3; ++ rt2800_rfcsr_write(rt2x00dev, 18, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 19, &rfcsr); ++ rt2x00_set_field8(&rfcsr, RFCSR19_K, rf->rf4); ++ rt2800_rfcsr_write(rt2x00dev, 19, rfcsr); ++ ++ /* Default: XO=20MHz , SDM mode */ ++ rt2800_rfcsr_read(rt2x00dev, 16, &rfcsr); ++ rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 0x80); ++ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr); ++ rt2x00_set_field8(&rfcsr, RFCSR21_BIT8, 1); ++ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_EN_MT7620, ++ rt2x00dev->default_ant.tx_chain_num != 1); ++ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); ++ rt2x00_set_field8(&rfcsr, RFCSR2_TX2_EN_MT7620, ++ rt2x00dev->default_ant.tx_chain_num != 1); ++ rt2x00_set_field8(&rfcsr, RFCSR2_RX2_EN_MT7620, ++ rt2x00dev->default_ant.rx_chain_num != 1); ++ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 42, &rfcsr); ++ rt2x00_set_field8(&rfcsr, RFCSR42_TX2_EN_MT7620, ++ rt2x00dev->default_ant.tx_chain_num != 1); ++ rt2800_rfcsr_write(rt2x00dev, 42, rfcsr); ++ ++ /* RF for DC Cal BW */ ++ if (conf_is_ht40(conf)) { ++ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x10); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x10); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x04); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x10); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x10); ++ } else { ++ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x20); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x20); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x20); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x20); ++ } ++ ++ if (conf_is_ht40(conf)) { ++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x08); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x08); ++ } else { ++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x28); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x28); ++ } ++ ++ rt2800_rfcsr_read(rt2x00dev, 28, &rfcsr); ++ rt2x00_set_field8(&rfcsr, RFCSR28_CH11_HT40, ++ conf_is_ht40(conf) && (rf->channel == 11)); ++ rt2800_rfcsr_write(rt2x00dev, 28, rfcsr); ++ ++ if (!test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) { ++ if (conf_is_ht40(conf)) { ++ rx_agc_fc = drv_data->rx_calibration_bw40; ++ tx_agc_fc = drv_data->tx_calibration_bw40; ++ } else { ++ rx_agc_fc = drv_data->rx_calibration_bw20; ++ tx_agc_fc = drv_data->tx_calibration_bw20; ++ } ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 6, &rfcsr); ++ rfcsr &= (~0x3F); ++ rfcsr |= rx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 6, rfcsr); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 7, &rfcsr); ++ rfcsr &= (~0x3F); ++ rfcsr |= rx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 7, rfcsr); ++ rt2800_rfcsr_read_bank(rt2x00dev, 7, 6, &rfcsr); ++ rfcsr &= (~0x3F); ++ rfcsr |= rx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 6, rfcsr); ++ rt2800_rfcsr_read_bank(rt2x00dev, 7, 7, &rfcsr); ++ rfcsr &= (~0x3F); ++ rfcsr |= rx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 7, rfcsr); ++ ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 58, &rfcsr); ++ rfcsr &= (~0x3F); ++ rfcsr |= tx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 58, rfcsr); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 59, &rfcsr); ++ rfcsr &= (~0x3F); ++ rfcsr |= tx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 59, rfcsr); ++ rt2800_rfcsr_read_bank(rt2x00dev, 7, 58, &rfcsr); ++ rfcsr &= (~0x3F); ++ rfcsr |= tx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 58, rfcsr); ++ rt2800_rfcsr_read_bank(rt2x00dev, 7, 59, &rfcsr); ++ rfcsr &= (~0x3F); ++ rfcsr |= tx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 59, rfcsr); ++ } ++} ++ ++static void rt2800_config_alc(struct rt2x00_dev *rt2x00dev, ++ struct ieee80211_channel *chan, ++ int power_level) { ++ u16 eeprom, target_power, max_power; ++ u32 mac_sys_ctrl, mac_status; ++ u32 reg; ++ u8 bbp; ++ int i; ++ ++ /* hardware unit is 0.5dBm, limited to 23.5dBm */ ++ power_level *= 2; ++ if (power_level > 0x2f) ++ power_level = 0x2f; ++ ++ max_power = chan->max_power * 2; ++ if (max_power > 0x2f) ++ max_power = 0x2f; ++ ++ rt2800_register_read(rt2x00dev, TX_ALC_CFG_0, ®); ++ rt2x00_set_field32(®, TX_ALC_CFG_0_CH_INIT_0, power_level); ++ rt2x00_set_field32(®, TX_ALC_CFG_0_CH_INIT_1, power_level); ++ rt2x00_set_field32(®, TX_ALC_CFG_0_LIMIT_0, max_power); ++ rt2x00_set_field32(®, TX_ALC_CFG_0_LIMIT_1, max_power); ++ ++ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); ++ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_INTERNAL_TX_ALC)) { ++ /* init base power by eeprom target power */ ++ rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_INIT, ++ &target_power); ++ rt2x00_set_field32(®, TX_ALC_CFG_0_CH_INIT_0, target_power); ++ rt2x00_set_field32(®, TX_ALC_CFG_0_CH_INIT_1, target_power); ++ } ++ rt2800_register_write(rt2x00dev, TX_ALC_CFG_0, reg); ++ ++ rt2800_register_read(rt2x00dev, TX_ALC_CFG_1, ®); ++ rt2x00_set_field32(®, TX_ALC_CFG_1_TX_TEMP_COMP, 0); ++ rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg); ++ ++ /* Save MAC SYS CTRL registers */ ++ rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &mac_sys_ctrl); ++ /* Disable Tx/Rx */ ++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0); ++ /* Check MAC Tx/Rx idle */ ++ for (i = 0; i < 10000; i++) { ++ rt2800_register_read(rt2x00dev, MAC_STATUS_CFG, ++ &mac_status); ++ if (mac_status & 0x3) ++ usleep_range(50, 200); ++ else ++ break; ++ } ++ ++ if (i == 10000) ++ rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n"); ++ ++ if (chan->center_freq > 2457) { ++ rt2800_bbp_read(rt2x00dev, 30, &bbp); ++ bbp = 0x40; ++ rt2800_bbp_write(rt2x00dev, 30, bbp); ++ rt2800_rfcsr_write(rt2x00dev, 39, 0); ++ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) ++ rt2800_rfcsr_write(rt2x00dev, 42, 0xfb); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 42, 0x7b); ++ } else { ++ rt2800_bbp_read(rt2x00dev, 30, &bbp); ++ bbp = 0x1f; ++ rt2800_bbp_write(rt2x00dev, 30, bbp); ++ rt2800_rfcsr_write(rt2x00dev, 39, 0x80); ++ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) ++ rt2800_rfcsr_write(rt2x00dev, 42, 0xdb); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 42, 0x5b); ++ } ++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl); ++} ++ + static void rt2800_bbp_write_with_rx_chain(struct rt2x00_dev *rt2x00dev, + const unsigned int word, + const u8 value) +@@ -3228,7 +3533,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, + struct channel_info *info) + { + u32 reg; +- unsigned int tx_pin; ++ u32 tx_pin; + u8 bbp, rfcsr; + + info->default_power1 = rt2800_txpower_to_dev(rt2x00dev, rf->channel, +@@ -3273,6 +3578,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, + case RF5592: + rt2800_config_channel_rf55xx(rt2x00dev, conf, rf, info); + break; ++ case RF7620: ++ rt2800_config_channel_rf7620(rt2x00dev, conf, rf, info); ++ break; + default: + rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); + } +@@ -3347,7 +3655,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, + + if (rf->channel <= 14) { + if (!rt2x00_rt(rt2x00dev, RT5390) && +- !rt2x00_rt(rt2x00dev, RT5392)) { ++ !rt2x00_rt(rt2x00dev, RT5392) && ++ !rt2x00_rt(rt2x00dev, RT6352)) { + if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { + rt2800_bbp_write(rt2x00dev, 82, 0x62); + rt2800_bbp_write(rt2x00dev, 75, 0x46); +@@ -3367,7 +3676,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, + rt2800_bbp_write(rt2x00dev, 82, 0x94); + else if (rt2x00_rt(rt2x00dev, RT3593)) + rt2800_bbp_write(rt2x00dev, 82, 0x82); +- else ++ else if (!rt2x00_rt(rt2x00dev, RT6352)) + rt2800_bbp_write(rt2x00dev, 82, 0xf2); + + if (rt2x00_rt(rt2x00dev, RT3593)) +@@ -3388,7 +3697,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, + if (rt2x00_rt(rt2x00dev, RT3572)) + rt2800_rfcsr_write(rt2x00dev, 8, 0); + +- tx_pin = 0; ++ rt2800_register_read(rt2x00dev, TX_PIN_CFG, &tx_pin); + + switch (rt2x00dev->default_ant.tx_chain_num) { + case 3: +@@ -3437,6 +3746,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, + + rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1); + rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1); ++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFRX_EN, 1); /* mt7620 */ + + rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); + +@@ -3495,7 +3805,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, + usleep_range(1000, 1500); + } + +- if (rt2x00_rt(rt2x00dev, RT5592)) { ++ if (rt2x00_rt(rt2x00dev, RT5592) || rt2x00_rt(rt2x00dev, RT6352)) { + rt2800_bbp_write(rt2x00dev, 195, 141); + rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a); + +@@ -4182,6 +4492,128 @@ static void rt2800_config_txpower_rt3593(struct rt2x00_dev *rt2x00dev, + (unsigned long) regs[i]); + } + ++static void rt2800_config_txpower_rt6352(struct rt2x00_dev *rt2x00dev, ++ struct ieee80211_channel *chan, ++ int power_level) ++{ ++ u32 reg, pwreg; ++ u16 eeprom; ++ u32 data, gdata; ++ u8 t, i; ++ enum nl80211_band band = chan->band; ++ int delta; ++ ++ /* Warn user if bw_comp is set in EEPROM */ ++ delta = rt2800_get_txpower_bw_comp(rt2x00dev, band); ++ ++ if (delta) ++ rt2x00_warn(rt2x00dev, "ignoring EEPROM HT40 power delta: %d\n", ++ delta); ++ ++ /* populate TX_PWR_CFG_0 up to TX_PWR_CFG_4 from EEPROM for HT20, limit ++ * value to 0x3f and replace 0x20 by 0x21 as this is what the vendor ++ * driver does as well, though it looks kinda wrong. ++ * Maybe some misunderstanding of what a signed 8-bit value is? Maybe ++ * the hardware has a problem handling 0x20, and as the code initially ++ * used a fixed offset between HT20 and HT40 rates they had to work- ++ * around that issue and most likely just forgot about it later on. ++ * Maybe we should use rt2800_get_txpower_bw_comp() here as well, ++ * however, the corresponding EEPROM value is not respected by the ++ * vendor driver, so maybe this is rather being taken care of the ++ * TXALC and the driver doesn't need to handle it...? ++ * Though this is all very awkward, just do as they did, as that's what ++ * board vendors expected when they populated the EEPROM... ++ */ ++ for (i = 0; i < 5; i++) { ++ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE, ++ i * 2, &eeprom); ++ ++ data = eeprom; ++ ++ t = eeprom & 0x3f; ++ if (t == 32) ++ t++; ++ ++ gdata = t; ++ ++ t = (eeprom & 0x3f00) >> 8; ++ if (t == 32) ++ t++; ++ ++ gdata |= (t << 8); ++ ++ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE, ++ (i * 2) + 1, &eeprom); ++ ++ t = eeprom & 0x3f; ++ if (t == 32) ++ t++; ++ ++ gdata |= (t << 16); ++ ++ t = (eeprom & 0x3f00) >> 8; ++ if (t == 32) ++ t++; ++ ++ gdata |= (t << 24); ++ data |= (eeprom << 16); ++ ++ if (!test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)) { ++ /* HT20 */ ++ if (data != 0xffffffff) ++ rt2800_register_write(rt2x00dev, ++ TX_PWR_CFG_0 + (i * 4), ++ data); ++ } else { ++ /* HT40 */ ++ if (gdata != 0xffffffff) ++ rt2800_register_write(rt2x00dev, ++ TX_PWR_CFG_0 + (i * 4), ++ gdata); ++ } ++ } ++ ++ /* Aparently Ralink ran out of space in the BYRATE calibration section ++ * of the EERPOM which is copied to the corresponding TX_PWR_CFG_x ++ * registers. As recent 2T chips use 8-bit instead of 4-bit values for ++ * power-offsets more space would be needed. Ralink decided to keep the ++ * EEPROM layout untouched and rather have some shared values covering ++ * multiple bitrates. ++ * Populate the registers not covered by the EEPROM in the same way the ++ * vendor driver does. ++ */ ++ ++ /* For OFDM 54MBS use value from OFDM 48MBS */ ++ pwreg = 0; ++ rt2800_register_read(rt2x00dev, TX_PWR_CFG_1, ®); ++ t = rt2x00_get_field32(reg, TX_PWR_CFG_1B_48MBS); ++ rt2x00_set_field32(&pwreg, TX_PWR_CFG_7B_54MBS, t); ++ ++ /* For MCS 7 use value from MCS 6 */ ++ rt2800_register_read(rt2x00dev, TX_PWR_CFG_2, ®); ++ t = rt2x00_get_field32(reg, TX_PWR_CFG_2B_MCS6_MCS7); ++ rt2x00_set_field32(&pwreg, TX_PWR_CFG_7B_MCS7, t); ++ rt2800_register_write(rt2x00dev, TX_PWR_CFG_7, pwreg); ++ ++ /* For MCS 15 use value from MCS 14 */ ++ pwreg = 0; ++ rt2800_register_read(rt2x00dev, TX_PWR_CFG_3, ®); ++ t = rt2x00_get_field32(reg, TX_PWR_CFG_3B_MCS14); ++ rt2x00_set_field32(&pwreg, TX_PWR_CFG_8B_MCS15, t); ++ rt2800_register_write(rt2x00dev, TX_PWR_CFG_8, pwreg); ++ ++ /* For STBC MCS 7 use value from STBC MCS 6 */ ++ pwreg = 0; ++ rt2800_register_read(rt2x00dev, TX_PWR_CFG_4, ®); ++ t = rt2x00_get_field32(reg, TX_PWR_CFG_4B_STBC_MCS6); ++ rt2x00_set_field32(&pwreg, TX_PWR_CFG_9B_STBC_MCS7, t); ++ rt2800_register_write(rt2x00dev, TX_PWR_CFG_9, pwreg); ++ ++ rt2800_config_alc(rt2x00dev, chan, power_level); ++ ++ /* TODO: temperature compensation code! */ ++} ++ + /* + * We configure transmit power using MAC TX_PWR_CFG_{0,...,N} registers and + * BBP R1 register. TX_PWR_CFG_X allow to configure per rate TX power values, +@@ -4378,6 +4810,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, + { + if (rt2x00_rt(rt2x00dev, RT3593)) + rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level); ++ else if (rt2x00_rt(rt2x00dev, RT6352)) ++ rt2800_config_txpower_rt6352(rt2x00dev, chan, power_level); + else + rt2800_config_txpower_rt28xx(rt2x00dev, chan, power_level); + } +@@ -4393,6 +4827,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev) + { + u32 tx_pin; + u8 rfcsr; ++ unsigned long min_sleep = 0; + + /* + * A voltage-controlled oscillator(VCO) is an electronic oscillator +@@ -4431,6 +4866,15 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev) + rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1); + rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); ++ min_sleep = 1000; ++ break; ++ case RF7620: ++ rt2800_rfcsr_write(rt2x00dev, 5, 0x40); ++ rt2800_rfcsr_write(rt2x00dev, 4, 0x0C); ++ rt2800_rfcsr_read(rt2x00dev, 4, &rfcsr); ++ rt2x00_set_field8(&rfcsr, RFCSR4_VCOCAL_EN, 1); ++ rt2800_rfcsr_write(rt2x00dev, 4, rfcsr); ++ min_sleep = 2000; + break; + default: + WARN_ONCE(1, "Not supported RF chipet %x for VCO recalibration", +@@ -4438,7 +4882,8 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev) + return; + } + +- usleep_range(1000, 1500); ++ if (min_sleep > 0) ++ usleep_range(min_sleep, min_sleep * 2); + + rt2800_register_read(rt2x00dev, TX_PIN_CFG, &tx_pin); + if (rt2x00dev->rf_channel <= 14) { +@@ -4470,6 +4915,42 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev) + } + rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); + ++ if (rt2x00_rt(rt2x00dev, RT6352)) { ++ if (rt2x00dev->default_ant.tx_chain_num == 1) { ++ rt2800_bbp_write(rt2x00dev, 91, 0x07); ++ rt2800_bbp_write(rt2x00dev, 95, 0x1A); ++ rt2800_bbp_write(rt2x00dev, 195, 128); ++ rt2800_bbp_write(rt2x00dev, 196, 0xA0); ++ rt2800_bbp_write(rt2x00dev, 195, 170); ++ rt2800_bbp_write(rt2x00dev, 196, 0x12); ++ rt2800_bbp_write(rt2x00dev, 195, 171); ++ rt2800_bbp_write(rt2x00dev, 196, 0x10); ++ } else { ++ rt2800_bbp_write(rt2x00dev, 91, 0x06); ++ rt2800_bbp_write(rt2x00dev, 95, 0x9A); ++ rt2800_bbp_write(rt2x00dev, 195, 128); ++ rt2800_bbp_write(rt2x00dev, 196, 0xE0); ++ rt2800_bbp_write(rt2x00dev, 195, 170); ++ rt2800_bbp_write(rt2x00dev, 196, 0x30); ++ rt2800_bbp_write(rt2x00dev, 195, 171); ++ rt2800_bbp_write(rt2x00dev, 196, 0x30); ++ } ++ ++ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { ++ rt2800_bbp_write(rt2x00dev, 75, 0x60); ++ rt2800_bbp_write(rt2x00dev, 76, 0x44); ++ rt2800_bbp_write(rt2x00dev, 79, 0x1C); ++ rt2800_bbp_write(rt2x00dev, 80, 0x0C); ++ rt2800_bbp_write(rt2x00dev, 82, 0xB6); ++ } ++ ++ /* On 11A, We should delay and wait RF/BBP to be stable ++ * and the appropriate time should be 1000 micro seconds ++ * 2005/06/05 - On 11G, we also need this delay time. ++ * Otherwise it's difficult to pass the WHQL. ++ */ ++ usleep_range(1000, 1500); ++ } + } + EXPORT_SYMBOL_GPL(rt2800_vco_calibration); + +@@ -4568,7 +5049,8 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev) + rt2x00_rt(rt2x00dev, RT3593) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392) || +- rt2x00_rt(rt2x00dev, RT5592)) ++ rt2x00_rt(rt2x00dev, RT5592) || ++ rt2x00_rt(rt2x00dev, RT6352)) + vgc = 0x1c + (2 * rt2x00dev->lna_gain); + else + vgc = 0x2e + rt2x00dev->lna_gain; +@@ -4795,7 +5277,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) + 0x00000000); + } + } else if (rt2x00_rt(rt2x00dev, RT5390) || +- rt2x00_rt(rt2x00dev, RT5392)) { ++ rt2x00_rt(rt2x00dev, RT5392) || ++ rt2x00_rt(rt2x00dev, RT6352)) { + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); + rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); + rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); +@@ -4805,6 +5288,24 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) + rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); + } else if (rt2x00_rt(rt2x00dev, RT5350)) { + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); ++ } else if (rt2x00_rt(rt2x00dev, RT6352)) { ++ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401); ++ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000); ++ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); ++ rt2800_register_write(rt2x00dev, MIMO_PS_CFG, 0x00000002); ++ rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x00150F0F); ++ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x06060606); ++ rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0); ++ rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0); ++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C666C); ++ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, 0x6C6C666C); ++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, ++ 0x3630363A); ++ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_CORRECT, ++ 0x3630363A); ++ rt2800_register_read(rt2x00dev, TX_ALC_CFG_1, ®); ++ rt2x00_set_field32(®, TX_ALC_CFG_1_ROS_BUSY_EN, 0); ++ rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg); + } else { + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); + rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); +@@ -5786,6 +6287,231 @@ static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev) + rt2800_bbp_write(rt2x00dev, 103, 0xc0); + } + ++static void rt2800_bbp_glrt_write(struct rt2x00_dev *rt2x00dev, ++ const u8 reg, const u8 value) ++{ ++ rt2800_bbp_write(rt2x00dev, 195, reg); ++ rt2800_bbp_write(rt2x00dev, 196, value); ++} ++ ++static void rt2800_bbp_dcoc_write(struct rt2x00_dev *rt2x00dev, ++ const u8 reg, const u8 value) ++{ ++ rt2800_bbp_write(rt2x00dev, 158, reg); ++ rt2800_bbp_write(rt2x00dev, 159, value); ++} ++ ++static void rt2800_bbp_dcoc_read(struct rt2x00_dev *rt2x00dev, ++ const u8 reg, u8 *value) ++{ ++ rt2800_bbp_write(rt2x00dev, 158, reg); ++ rt2800_bbp_read(rt2x00dev, 159, value); ++} ++ ++static void rt2800_init_bbp_6352(struct rt2x00_dev *rt2x00dev) ++{ ++ u8 bbp; ++ ++ /* Apply Maximum Likelihood Detection (MLD) for 2 stream case */ ++ rt2800_bbp_read(rt2x00dev, 105, &bbp); ++ rt2x00_set_field8(&bbp, BBP105_MLD, ++ rt2x00dev->default_ant.rx_chain_num == 2); ++ rt2800_bbp_write(rt2x00dev, 105, bbp); ++ ++ /* Avoid data loss and CRC errors */ ++ rt2800_bbp4_mac_if_ctrl(rt2x00dev); ++ ++ /* Fix I/Q swap issue */ ++ rt2800_bbp_read(rt2x00dev, 1, &bbp); ++ bbp |= 0x04; ++ rt2800_bbp_write(rt2x00dev, 1, bbp); ++ ++ /* BBP for G band */ ++ rt2800_bbp_write(rt2x00dev, 3, 0x08); ++ rt2800_bbp_write(rt2x00dev, 4, 0x00); /* rt2800_bbp4_mac_if_ctrl? */ ++ rt2800_bbp_write(rt2x00dev, 6, 0x08); ++ rt2800_bbp_write(rt2x00dev, 14, 0x09); ++ rt2800_bbp_write(rt2x00dev, 15, 0xFF); ++ rt2800_bbp_write(rt2x00dev, 16, 0x01); ++ rt2800_bbp_write(rt2x00dev, 20, 0x06); ++ rt2800_bbp_write(rt2x00dev, 21, 0x00); ++ rt2800_bbp_write(rt2x00dev, 22, 0x00); ++ rt2800_bbp_write(rt2x00dev, 27, 0x00); ++ rt2800_bbp_write(rt2x00dev, 28, 0x00); ++ rt2800_bbp_write(rt2x00dev, 30, 0x00); ++ rt2800_bbp_write(rt2x00dev, 31, 0x48); ++ rt2800_bbp_write(rt2x00dev, 47, 0x40); ++ rt2800_bbp_write(rt2x00dev, 62, 0x00); ++ rt2800_bbp_write(rt2x00dev, 63, 0x00); ++ rt2800_bbp_write(rt2x00dev, 64, 0x00); ++ rt2800_bbp_write(rt2x00dev, 65, 0x2C); ++ rt2800_bbp_write(rt2x00dev, 66, 0x1C); ++ rt2800_bbp_write(rt2x00dev, 67, 0x20); ++ rt2800_bbp_write(rt2x00dev, 68, 0xDD); ++ rt2800_bbp_write(rt2x00dev, 69, 0x10); ++ rt2800_bbp_write(rt2x00dev, 70, 0x05); ++ rt2800_bbp_write(rt2x00dev, 73, 0x18); ++ rt2800_bbp_write(rt2x00dev, 74, 0x0F); ++ rt2800_bbp_write(rt2x00dev, 75, 0x60); ++ rt2800_bbp_write(rt2x00dev, 76, 0x44); ++ rt2800_bbp_write(rt2x00dev, 77, 0x59); ++ rt2800_bbp_write(rt2x00dev, 78, 0x1E); ++ rt2800_bbp_write(rt2x00dev, 79, 0x1C); ++ rt2800_bbp_write(rt2x00dev, 80, 0x0C); ++ rt2800_bbp_write(rt2x00dev, 81, 0x3A); ++ rt2800_bbp_write(rt2x00dev, 82, 0xB6); ++ rt2800_bbp_write(rt2x00dev, 83, 0x9A); ++ rt2800_bbp_write(rt2x00dev, 84, 0x9A); ++ rt2800_bbp_write(rt2x00dev, 86, 0x38); ++ rt2800_bbp_write(rt2x00dev, 88, 0x90); ++ rt2800_bbp_write(rt2x00dev, 91, 0x04); ++ rt2800_bbp_write(rt2x00dev, 92, 0x02); ++ rt2800_bbp_write(rt2x00dev, 95, 0x9A); ++ rt2800_bbp_write(rt2x00dev, 96, 0x00); ++ rt2800_bbp_write(rt2x00dev, 103, 0xC0); ++ rt2800_bbp_write(rt2x00dev, 104, 0x92); ++ /* FIXME BBP105 owerwrite */ ++ rt2800_bbp_write(rt2x00dev, 105, 0x3C); ++ rt2800_bbp_write(rt2x00dev, 106, 0x12); ++ rt2800_bbp_write(rt2x00dev, 109, 0x00); ++ rt2800_bbp_write(rt2x00dev, 134, 0x10); ++ rt2800_bbp_write(rt2x00dev, 135, 0xA6); ++ rt2800_bbp_write(rt2x00dev, 137, 0x04); ++ rt2800_bbp_write(rt2x00dev, 142, 0x30); ++ rt2800_bbp_write(rt2x00dev, 143, 0xF7); ++ rt2800_bbp_write(rt2x00dev, 160, 0xEC); ++ rt2800_bbp_write(rt2x00dev, 161, 0xC4); ++ rt2800_bbp_write(rt2x00dev, 162, 0x77); ++ rt2800_bbp_write(rt2x00dev, 163, 0xF9); ++ rt2800_bbp_write(rt2x00dev, 164, 0x00); ++ rt2800_bbp_write(rt2x00dev, 165, 0x00); ++ rt2800_bbp_write(rt2x00dev, 186, 0x00); ++ rt2800_bbp_write(rt2x00dev, 187, 0x00); ++ rt2800_bbp_write(rt2x00dev, 188, 0x00); ++ rt2800_bbp_write(rt2x00dev, 186, 0x00); ++ rt2800_bbp_write(rt2x00dev, 187, 0x01); ++ rt2800_bbp_write(rt2x00dev, 188, 0x00); ++ rt2800_bbp_write(rt2x00dev, 189, 0x00); ++ ++ rt2800_bbp_write(rt2x00dev, 91, 0x06); ++ rt2800_bbp_write(rt2x00dev, 92, 0x04); ++ rt2800_bbp_write(rt2x00dev, 93, 0x54); ++ rt2800_bbp_write(rt2x00dev, 99, 0x50); ++ rt2800_bbp_write(rt2x00dev, 148, 0x84); ++ rt2800_bbp_write(rt2x00dev, 167, 0x80); ++ rt2800_bbp_write(rt2x00dev, 178, 0xFF); ++ rt2800_bbp_write(rt2x00dev, 106, 0x13); ++ ++ /* BBP for G band GLRT function (BBP_128 ~ BBP_221) */ ++ rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00); ++ rt2800_bbp_glrt_write(rt2x00dev, 1, 0x14); ++ rt2800_bbp_glrt_write(rt2x00dev, 2, 0x20); ++ rt2800_bbp_glrt_write(rt2x00dev, 3, 0x0A); ++ rt2800_bbp_glrt_write(rt2x00dev, 10, 0x16); ++ rt2800_bbp_glrt_write(rt2x00dev, 11, 0x06); ++ rt2800_bbp_glrt_write(rt2x00dev, 12, 0x02); ++ rt2800_bbp_glrt_write(rt2x00dev, 13, 0x07); ++ rt2800_bbp_glrt_write(rt2x00dev, 14, 0x05); ++ rt2800_bbp_glrt_write(rt2x00dev, 15, 0x09); ++ rt2800_bbp_glrt_write(rt2x00dev, 16, 0x20); ++ rt2800_bbp_glrt_write(rt2x00dev, 17, 0x08); ++ rt2800_bbp_glrt_write(rt2x00dev, 18, 0x4A); ++ rt2800_bbp_glrt_write(rt2x00dev, 19, 0x00); ++ rt2800_bbp_glrt_write(rt2x00dev, 20, 0x00); ++ rt2800_bbp_glrt_write(rt2x00dev, 128, 0xE0); ++ rt2800_bbp_glrt_write(rt2x00dev, 129, 0x1F); ++ rt2800_bbp_glrt_write(rt2x00dev, 130, 0x4F); ++ rt2800_bbp_glrt_write(rt2x00dev, 131, 0x32); ++ rt2800_bbp_glrt_write(rt2x00dev, 132, 0x08); ++ rt2800_bbp_glrt_write(rt2x00dev, 133, 0x28); ++ rt2800_bbp_glrt_write(rt2x00dev, 134, 0x19); ++ rt2800_bbp_glrt_write(rt2x00dev, 135, 0x0A); ++ rt2800_bbp_glrt_write(rt2x00dev, 138, 0x16); ++ rt2800_bbp_glrt_write(rt2x00dev, 139, 0x10); ++ rt2800_bbp_glrt_write(rt2x00dev, 140, 0x10); ++ rt2800_bbp_glrt_write(rt2x00dev, 141, 0x1A); ++ rt2800_bbp_glrt_write(rt2x00dev, 142, 0x36); ++ rt2800_bbp_glrt_write(rt2x00dev, 143, 0x2C); ++ rt2800_bbp_glrt_write(rt2x00dev, 144, 0x26); ++ rt2800_bbp_glrt_write(rt2x00dev, 145, 0x24); ++ rt2800_bbp_glrt_write(rt2x00dev, 146, 0x42); ++ rt2800_bbp_glrt_write(rt2x00dev, 147, 0x40); ++ rt2800_bbp_glrt_write(rt2x00dev, 148, 0x30); ++ rt2800_bbp_glrt_write(rt2x00dev, 149, 0x29); ++ rt2800_bbp_glrt_write(rt2x00dev, 150, 0x4C); ++ rt2800_bbp_glrt_write(rt2x00dev, 151, 0x46); ++ rt2800_bbp_glrt_write(rt2x00dev, 152, 0x3D); ++ rt2800_bbp_glrt_write(rt2x00dev, 153, 0x40); ++ rt2800_bbp_glrt_write(rt2x00dev, 154, 0x3E); ++ rt2800_bbp_glrt_write(rt2x00dev, 155, 0x38); ++ rt2800_bbp_glrt_write(rt2x00dev, 156, 0x3D); ++ rt2800_bbp_glrt_write(rt2x00dev, 157, 0x2F); ++ rt2800_bbp_glrt_write(rt2x00dev, 158, 0x3C); ++ rt2800_bbp_glrt_write(rt2x00dev, 159, 0x34); ++ rt2800_bbp_glrt_write(rt2x00dev, 160, 0x2C); ++ rt2800_bbp_glrt_write(rt2x00dev, 161, 0x2F); ++ rt2800_bbp_glrt_write(rt2x00dev, 162, 0x3C); ++ rt2800_bbp_glrt_write(rt2x00dev, 163, 0x35); ++ rt2800_bbp_glrt_write(rt2x00dev, 164, 0x2E); ++ rt2800_bbp_glrt_write(rt2x00dev, 165, 0x2F); ++ rt2800_bbp_glrt_write(rt2x00dev, 166, 0x49); ++ rt2800_bbp_glrt_write(rt2x00dev, 167, 0x41); ++ rt2800_bbp_glrt_write(rt2x00dev, 168, 0x36); ++ rt2800_bbp_glrt_write(rt2x00dev, 169, 0x39); ++ rt2800_bbp_glrt_write(rt2x00dev, 170, 0x30); ++ rt2800_bbp_glrt_write(rt2x00dev, 171, 0x30); ++ rt2800_bbp_glrt_write(rt2x00dev, 172, 0x0E); ++ rt2800_bbp_glrt_write(rt2x00dev, 173, 0x0D); ++ rt2800_bbp_glrt_write(rt2x00dev, 174, 0x28); ++ rt2800_bbp_glrt_write(rt2x00dev, 175, 0x21); ++ rt2800_bbp_glrt_write(rt2x00dev, 176, 0x1C); ++ rt2800_bbp_glrt_write(rt2x00dev, 177, 0x16); ++ rt2800_bbp_glrt_write(rt2x00dev, 178, 0x50); ++ rt2800_bbp_glrt_write(rt2x00dev, 179, 0x4A); ++ rt2800_bbp_glrt_write(rt2x00dev, 180, 0x43); ++ rt2800_bbp_glrt_write(rt2x00dev, 181, 0x50); ++ rt2800_bbp_glrt_write(rt2x00dev, 182, 0x10); ++ rt2800_bbp_glrt_write(rt2x00dev, 183, 0x10); ++ rt2800_bbp_glrt_write(rt2x00dev, 184, 0x10); ++ rt2800_bbp_glrt_write(rt2x00dev, 185, 0x10); ++ rt2800_bbp_glrt_write(rt2x00dev, 200, 0x7D); ++ rt2800_bbp_glrt_write(rt2x00dev, 201, 0x14); ++ rt2800_bbp_glrt_write(rt2x00dev, 202, 0x32); ++ rt2800_bbp_glrt_write(rt2x00dev, 203, 0x2C); ++ rt2800_bbp_glrt_write(rt2x00dev, 204, 0x36); ++ rt2800_bbp_glrt_write(rt2x00dev, 205, 0x4C); ++ rt2800_bbp_glrt_write(rt2x00dev, 206, 0x43); ++ rt2800_bbp_glrt_write(rt2x00dev, 207, 0x2C); ++ rt2800_bbp_glrt_write(rt2x00dev, 208, 0x2E); ++ rt2800_bbp_glrt_write(rt2x00dev, 209, 0x36); ++ rt2800_bbp_glrt_write(rt2x00dev, 210, 0x30); ++ rt2800_bbp_glrt_write(rt2x00dev, 211, 0x6E); ++ ++ /* BBP for G band DCOC function */ ++ rt2800_bbp_dcoc_write(rt2x00dev, 140, 0x0C); ++ rt2800_bbp_dcoc_write(rt2x00dev, 141, 0x00); ++ rt2800_bbp_dcoc_write(rt2x00dev, 142, 0x10); ++ rt2800_bbp_dcoc_write(rt2x00dev, 143, 0x10); ++ rt2800_bbp_dcoc_write(rt2x00dev, 144, 0x10); ++ rt2800_bbp_dcoc_write(rt2x00dev, 145, 0x10); ++ rt2800_bbp_dcoc_write(rt2x00dev, 146, 0x08); ++ rt2800_bbp_dcoc_write(rt2x00dev, 147, 0x40); ++ rt2800_bbp_dcoc_write(rt2x00dev, 148, 0x04); ++ rt2800_bbp_dcoc_write(rt2x00dev, 149, 0x04); ++ rt2800_bbp_dcoc_write(rt2x00dev, 150, 0x08); ++ rt2800_bbp_dcoc_write(rt2x00dev, 151, 0x08); ++ rt2800_bbp_dcoc_write(rt2x00dev, 152, 0x03); ++ rt2800_bbp_dcoc_write(rt2x00dev, 153, 0x03); ++ rt2800_bbp_dcoc_write(rt2x00dev, 154, 0x03); ++ rt2800_bbp_dcoc_write(rt2x00dev, 155, 0x02); ++ rt2800_bbp_dcoc_write(rt2x00dev, 156, 0x40); ++ rt2800_bbp_dcoc_write(rt2x00dev, 157, 0x40); ++ rt2800_bbp_dcoc_write(rt2x00dev, 158, 0x64); ++ rt2800_bbp_dcoc_write(rt2x00dev, 159, 0x64); ++ ++ rt2800_bbp4_mac_if_ctrl(rt2x00dev); ++} ++ + static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) + { + unsigned int i; +@@ -5830,6 +6556,9 @@ static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) + case RT5592: + rt2800_init_bbp_5592(rt2x00dev); + return; ++ case RT6352: ++ rt2800_init_bbp_6352(rt2x00dev); ++ break; + } + + for (i = 0; i < EEPROM_BBP_SIZE; i++) { +@@ -6901,6 +7630,615 @@ static void rt2800_init_rfcsr_5592(struct rt2x00_dev *rt2x00dev) + rt2800_led_open_drain_enable(rt2x00dev); + } + ++static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, ++ bool set_bw, bool is_ht40) ++{ ++ u8 bbp_val; ++ ++ rt2800_bbp_read(rt2x00dev, 21, &bbp_val); ++ bbp_val |= 0x1; ++ rt2800_bbp_write(rt2x00dev, 21, bbp_val); ++ usleep_range(100, 200); ++ ++ if (set_bw) { ++ rt2800_bbp_read(rt2x00dev, 4, &bbp_val); ++ rt2x00_set_field8(&bbp_val, BBP4_BANDWIDTH, 2 * is_ht40); ++ rt2800_bbp_write(rt2x00dev, 4, bbp_val); ++ usleep_range(100, 200); ++ } ++ ++ rt2800_bbp_read(rt2x00dev, 21, &bbp_val); ++ bbp_val &= (~0x1); ++ rt2800_bbp_write(rt2x00dev, 21, bbp_val); ++ usleep_range(100, 200); ++} ++ ++static int rt2800_rf_lp_config(struct rt2x00_dev *rt2x00dev, bool btxcal) ++{ ++ u8 rf_val; ++ ++ if (btxcal) ++ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x04); ++ else ++ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x02); ++ ++ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x06); ++ ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 17, &rf_val); ++ rf_val |= 0x80; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, rf_val); ++ ++ if (btxcal) { ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, 0xC1); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, 0x20); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, 0x02); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 3, &rf_val); ++ rf_val &= (~0x3F); ++ rf_val |= 0x3F; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 3, rf_val); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 4, &rf_val); ++ rf_val &= (~0x3F); ++ rf_val |= 0x3F; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, rf_val); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 5, 0x31); ++ } else { ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, 0xF1); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, 0x18); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, 0x02); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 3, &rf_val); ++ rf_val &= (~0x3F); ++ rf_val |= 0x34; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 3, rf_val); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 4, &rf_val); ++ rf_val &= (~0x3F); ++ rf_val |= 0x34; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, rf_val); ++ } ++ ++ return 0; ++} ++ ++static char rt2800_lp_tx_filter_bw_cal(struct rt2x00_dev *rt2x00dev) ++{ ++ unsigned int cnt; ++ u8 bbp_val; ++ char cal_val; ++ ++ rt2800_bbp_dcoc_write(rt2x00dev, 0, 0x82); ++ ++ cnt = 0; ++ do { ++ usleep_range(500, 2000); ++ rt2800_bbp_read(rt2x00dev, 159, &bbp_val); ++ if (bbp_val == 0x02 || cnt == 20) ++ break; ++ ++ cnt++; ++ } while (cnt < 20); ++ ++ rt2800_bbp_dcoc_read(rt2x00dev, 0x39, &bbp_val); ++ cal_val = bbp_val & 0x7F; ++ if (cal_val >= 0x40) ++ cal_val -= 128; ++ ++ return cal_val; ++} ++ ++static void rt2800_bw_filter_calibration(struct rt2x00_dev *rt2x00dev, ++ bool btxcal) ++{ ++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; ++ u8 tx_agc_fc = 0, rx_agc_fc = 0, cmm_agc_fc; ++ u8 filter_target; ++ u8 tx_filter_target_20m = 0x09, tx_filter_target_40m = 0x02; ++ u8 rx_filter_target_20m = 0x27, rx_filter_target_40m = 0x31; ++ int loop = 0, is_ht40, cnt; ++ u8 bbp_val, rf_val; ++ char cal_r32_init, cal_r32_val, cal_diff; ++ u8 saverfb5r00, saverfb5r01, saverfb5r03, saverfb5r04, saverfb5r05; ++ u8 saverfb5r06, saverfb5r07; ++ u8 saverfb5r08, saverfb5r17, saverfb5r18, saverfb5r19, saverfb5r20; ++ u8 saverfb5r37, saverfb5r38, saverfb5r39, saverfb5r40, saverfb5r41; ++ u8 saverfb5r42, saverfb5r43, saverfb5r44, saverfb5r45, saverfb5r46; ++ u8 saverfb5r58, saverfb5r59; ++ u8 savebbp159r0, savebbp159r2, savebbpr23; ++ u32 MAC_RF_CONTROL0, MAC_RF_BYPASS0; ++ ++ /* Save MAC registers */ ++ rt2800_register_read(rt2x00dev, RF_CONTROL0, &MAC_RF_CONTROL0); ++ rt2800_register_read(rt2x00dev, RF_BYPASS0, &MAC_RF_BYPASS0); ++ ++ /* save BBP registers */ ++ rt2800_bbp_read(rt2x00dev, 23, &savebbpr23); ++ ++ rt2800_bbp_dcoc_read(rt2x00dev, 0, &savebbp159r0); ++ rt2800_bbp_dcoc_read(rt2x00dev, 2, &savebbp159r2); ++ ++ /* Save RF registers */ ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 0, &saverfb5r00); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 1, &saverfb5r01); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 3, &saverfb5r03); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 4, &saverfb5r04); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 5, &saverfb5r05); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 6, &saverfb5r06); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 7, &saverfb5r07); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 8, &saverfb5r08); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 17, &saverfb5r17); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 18, &saverfb5r18); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 19, &saverfb5r19); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 20, &saverfb5r20); ++ ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 37, &saverfb5r37); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 38, &saverfb5r38); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 39, &saverfb5r39); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 40, &saverfb5r40); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 41, &saverfb5r41); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 42, &saverfb5r42); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 43, &saverfb5r43); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 44, &saverfb5r44); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 45, &saverfb5r45); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 46, &saverfb5r46); ++ ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 58, &saverfb5r58); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 59, &saverfb5r59); ++ ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 0, &rf_val); ++ rf_val |= 0x3; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 0, rf_val); ++ ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 1, &rf_val); ++ rf_val |= 0x1; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 1, rf_val); ++ ++ cnt = 0; ++ do { ++ usleep_range(500, 2000); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 1, &rf_val); ++ if (((rf_val & 0x1) == 0x00) || (cnt == 40)) ++ break; ++ cnt++; ++ } while (cnt < 40); ++ ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 0, &rf_val); ++ rf_val &= (~0x3); ++ rf_val |= 0x1; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 0, rf_val); ++ ++ /* I-3 */ ++ rt2800_bbp_read(rt2x00dev, 23, &bbp_val); ++ bbp_val &= (~0x1F); ++ bbp_val |= 0x10; ++ rt2800_bbp_write(rt2x00dev, 23, bbp_val); ++ ++ do { ++ /* I-4,5,6,7,8,9 */ ++ if (loop == 0) { ++ is_ht40 = false; ++ ++ if (btxcal) ++ filter_target = tx_filter_target_20m; ++ else ++ filter_target = rx_filter_target_20m; ++ } else { ++ is_ht40 = true; ++ ++ if (btxcal) ++ filter_target = tx_filter_target_40m; ++ else ++ filter_target = rx_filter_target_40m; ++ } ++ ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 8, &rf_val); ++ rf_val &= (~0x04); ++ if (loop == 1) ++ rf_val |= 0x4; ++ ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 8, rf_val); ++ ++ rt2800_bbp_core_soft_reset(rt2x00dev, true, is_ht40); ++ ++ rt2800_rf_lp_config(rt2x00dev, btxcal); ++ if (btxcal) { ++ tx_agc_fc = 0; ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 58, &rf_val); ++ rf_val &= (~0x7F); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 58, rf_val); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 59, &rf_val); ++ rf_val &= (~0x7F); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 59, rf_val); ++ } else { ++ rx_agc_fc = 0; ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 6, &rf_val); ++ rf_val &= (~0x7F); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 6, rf_val); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 7, &rf_val); ++ rf_val &= (~0x7F); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 7, rf_val); ++ } ++ ++ usleep_range(1000, 2000); ++ ++ rt2800_bbp_dcoc_read(rt2x00dev, 2, &bbp_val); ++ bbp_val &= (~0x6); ++ rt2800_bbp_dcoc_write(rt2x00dev, 2, bbp_val); ++ ++ rt2800_bbp_core_soft_reset(rt2x00dev, false, is_ht40); ++ ++ cal_r32_init = rt2800_lp_tx_filter_bw_cal(rt2x00dev); ++ ++ rt2800_bbp_dcoc_read(rt2x00dev, 2, &bbp_val); ++ bbp_val |= 0x6; ++ rt2800_bbp_dcoc_write(rt2x00dev, 2, bbp_val); ++do_cal: ++ if (btxcal) { ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 58, &rf_val); ++ rf_val &= (~0x7F); ++ rf_val |= tx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 58, rf_val); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 59, &rf_val); ++ rf_val &= (~0x7F); ++ rf_val |= tx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 59, rf_val); ++ } else { ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 6, &rf_val); ++ rf_val &= (~0x7F); ++ rf_val |= rx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 6, rf_val); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 7, &rf_val); ++ rf_val &= (~0x7F); ++ rf_val |= rx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 7, rf_val); ++ } ++ ++ usleep_range(500, 1000); ++ ++ rt2800_bbp_core_soft_reset(rt2x00dev, false, is_ht40); ++ ++ cal_r32_val = rt2800_lp_tx_filter_bw_cal(rt2x00dev); ++ ++ cal_diff = cal_r32_init - cal_r32_val; ++ ++ if (btxcal) ++ cmm_agc_fc = tx_agc_fc; ++ else ++ cmm_agc_fc = rx_agc_fc; ++ ++ if (((cal_diff > filter_target) && (cmm_agc_fc == 0)) || ++ ((cal_diff < filter_target) && (cmm_agc_fc == 0x3f))) { ++ if (btxcal) ++ tx_agc_fc = 0; ++ else ++ rx_agc_fc = 0; ++ } else if ((cal_diff <= filter_target) && (cmm_agc_fc < 0x3f)) { ++ if (btxcal) ++ tx_agc_fc++; ++ else ++ rx_agc_fc++; ++ goto do_cal; ++ } ++ ++ if (btxcal) { ++ if (loop == 0) ++ drv_data->tx_calibration_bw20 = tx_agc_fc; ++ else ++ drv_data->tx_calibration_bw40 = tx_agc_fc; ++ } else { ++ if (loop == 0) ++ drv_data->rx_calibration_bw20 = rx_agc_fc; ++ else ++ drv_data->rx_calibration_bw40 = rx_agc_fc; ++ } ++ ++ loop++; ++ } while (loop <= 1); ++ ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 0, saverfb5r00); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 1, saverfb5r01); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 3, saverfb5r03); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, saverfb5r04); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 5, saverfb5r05); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 6, saverfb5r06); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 7, saverfb5r07); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 8, saverfb5r08); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, saverfb5r17); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, saverfb5r18); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, saverfb5r19); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, saverfb5r20); ++ ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 37, saverfb5r37); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 38, saverfb5r38); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 39, saverfb5r39); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 40, saverfb5r40); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 41, saverfb5r41); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 42, saverfb5r42); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 43, saverfb5r43); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 44, saverfb5r44); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 45, saverfb5r45); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 46, saverfb5r46); ++ ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 58, saverfb5r58); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 59, saverfb5r59); ++ ++ rt2800_bbp_write(rt2x00dev, 23, savebbpr23); ++ ++ rt2800_bbp_dcoc_write(rt2x00dev, 0, savebbp159r0); ++ rt2800_bbp_dcoc_write(rt2x00dev, 2, savebbp159r2); ++ ++ rt2800_bbp_read(rt2x00dev, 4, &bbp_val); ++ rt2x00_set_field8(&bbp_val, BBP4_BANDWIDTH, ++ 2 * test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)); ++ rt2800_bbp_write(rt2x00dev, 4, bbp_val); ++ ++ rt2800_register_write(rt2x00dev, RF_CONTROL0, MAC_RF_CONTROL0); ++ rt2800_register_write(rt2x00dev, RF_BYPASS0, MAC_RF_BYPASS0); ++} ++ ++static void rt2800_init_rfcsr_6352(struct rt2x00_dev *rt2x00dev) ++{ ++ /* Initialize RF central register to default value */ ++ rt2800_rfcsr_write(rt2x00dev, 0, 0x02); ++ rt2800_rfcsr_write(rt2x00dev, 1, 0x03); ++ rt2800_rfcsr_write(rt2x00dev, 2, 0x33); ++ rt2800_rfcsr_write(rt2x00dev, 3, 0xFF); ++ rt2800_rfcsr_write(rt2x00dev, 4, 0x0C); ++ rt2800_rfcsr_write(rt2x00dev, 5, 0x40); ++ rt2800_rfcsr_write(rt2x00dev, 6, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 7, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 8, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 9, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 10, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 11, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 12, rt2x00dev->freq_offset); ++ rt2800_rfcsr_write(rt2x00dev, 13, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 14, 0x40); ++ rt2800_rfcsr_write(rt2x00dev, 15, 0x22); ++ rt2800_rfcsr_write(rt2x00dev, 16, 0x4C); ++ rt2800_rfcsr_write(rt2x00dev, 17, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 18, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 19, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 20, 0xA0); ++ rt2800_rfcsr_write(rt2x00dev, 21, 0x12); ++ rt2800_rfcsr_write(rt2x00dev, 22, 0x07); ++ rt2800_rfcsr_write(rt2x00dev, 23, 0x13); ++ rt2800_rfcsr_write(rt2x00dev, 24, 0xFE); ++ rt2800_rfcsr_write(rt2x00dev, 25, 0x24); ++ rt2800_rfcsr_write(rt2x00dev, 26, 0x7A); ++ rt2800_rfcsr_write(rt2x00dev, 27, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 28, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 29, 0x05); ++ rt2800_rfcsr_write(rt2x00dev, 30, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 31, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 32, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 33, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 34, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 35, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 36, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 37, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 38, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 39, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 40, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 41, 0xD0); ++ rt2800_rfcsr_write(rt2x00dev, 42, 0x5B); ++ rt2800_rfcsr_write(rt2x00dev, 43, 0x00); ++ ++ rt2800_rfcsr_write(rt2x00dev, 11, 0x21); ++ if (rt2800_clk_is_20mhz(rt2x00dev)) ++ rt2800_rfcsr_write(rt2x00dev, 13, 0x03); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 13, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 14, 0x7C); ++ rt2800_rfcsr_write(rt2x00dev, 16, 0x80); ++ rt2800_rfcsr_write(rt2x00dev, 17, 0x99); ++ rt2800_rfcsr_write(rt2x00dev, 18, 0x99); ++ rt2800_rfcsr_write(rt2x00dev, 19, 0x09); ++ rt2800_rfcsr_write(rt2x00dev, 20, 0x50); ++ rt2800_rfcsr_write(rt2x00dev, 21, 0xB0); ++ rt2800_rfcsr_write(rt2x00dev, 22, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 23, 0x06); ++ rt2800_rfcsr_write(rt2x00dev, 24, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 25, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 26, 0x5D); ++ rt2800_rfcsr_write(rt2x00dev, 27, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 28, 0x61); ++ rt2800_rfcsr_write(rt2x00dev, 29, 0xB5); ++ rt2800_rfcsr_write(rt2x00dev, 43, 0x02); ++ ++ rt2800_rfcsr_write(rt2x00dev, 28, 0x62); ++ rt2800_rfcsr_write(rt2x00dev, 29, 0xAD); ++ rt2800_rfcsr_write(rt2x00dev, 39, 0x80); ++ ++ /* Initialize RF channel register to default value */ ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 1, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 2, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 3, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 4, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 5, 0x08); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 6, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 7, 0x51); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x53); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x16); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x61); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 12, 0x22); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 13, 0x3D); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 15, 0x13); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 16, 0x22); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x27); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x02); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x01); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x52); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 22, 0x80); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 23, 0xB3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 24, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 25, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 26, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 27, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x5C); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0x6B); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 30, 0x6B); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 31, 0x31); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x5D); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 33, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xE6); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 35, 0x55); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 37, 0xBB); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 39, 0xB3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 40, 0x03); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 41, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 42, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xB3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xD3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x07); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x68); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xEF); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1C); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x07); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xA8); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0x85); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x10); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x07); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6A); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0x85); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x10); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 62, 0x1C); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 63, 0x00); ++ ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5); ++ ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x33); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x0E); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA4); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x02); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x12); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x1C); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0xEB); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x7D); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xD6); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x08); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB4); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x69); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFF); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x20); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09); ++ ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16); ++ ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); ++ ++ /* Initialize RF channel register for DRQFN */ ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7); ++ ++ /* Initialize RF DC calibration register to default value */ ++ rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 1, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 2, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x10); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x10); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x04); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 9, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 10, 0x07); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 11, 0x01); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 12, 0x07); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 13, 0x07); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 14, 0x07); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 15, 0x20); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 16, 0x22); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 18, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 19, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 20, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 21, 0xF1); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 22, 0x11); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 23, 0x02); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 24, 0x41); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 25, 0x20); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 26, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 27, 0xD7); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 28, 0xA2); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 29, 0x20); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 30, 0x49); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 31, 0x20); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 32, 0x04); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 33, 0xF1); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 34, 0xA1); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 35, 0x01); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 41, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 42, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 43, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 44, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 45, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 46, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 47, 0x3E); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 48, 0x3D); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 49, 0x3E); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 50, 0x3D); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 51, 0x3E); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 52, 0x3D); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 53, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 54, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 55, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 56, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 57, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x10); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x10); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 60, 0x0A); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 61, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00); ++ ++ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x08); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x04); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x20); ++ ++ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); ++ ++ rt2800_bw_filter_calibration(rt2x00dev, true); ++ rt2800_bw_filter_calibration(rt2x00dev, false); ++} ++ + static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) + { + if (rt2800_is_305x_soc(rt2x00dev)) { +@@ -6941,6 +8279,9 @@ static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) + case RT5592: + rt2800_init_rfcsr_5592(rt2x00dev); + break; ++ case RT6352: ++ rt2800_init_rfcsr_6352(rt2x00dev); ++ break; + } + } + +@@ -7307,7 +8648,8 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) + */ + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || +- rt2x00_rt(rt2x00dev, RT5392)) ++ rt2x00_rt(rt2x00dev, RT5392) || ++ rt2x00_rt(rt2x00dev, RT6352)) + rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); + else if (rt2x00_rt(rt2x00dev, RT3352)) + rf = RF3322; +@@ -7339,6 +8681,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) + case RF5390: + case RF5392: + case RF5592: ++ case RF7620: + break; + default: + rt2x00_err(rt2x00dev, "Invalid RF chipset 0x%04x detected\n", +@@ -7746,6 +9089,23 @@ static const struct rf_channel rf_vals_5592_xtal40[] = { + {196, 83, 0, 12, 1}, + }; + ++static const struct rf_channel rf_vals_7620[] = { ++ {1, 0x50, 0x99, 0x99, 1}, ++ {2, 0x50, 0x44, 0x44, 2}, ++ {3, 0x50, 0xEE, 0xEE, 2}, ++ {4, 0x50, 0x99, 0x99, 3}, ++ {5, 0x51, 0x44, 0x44, 0}, ++ {6, 0x51, 0xEE, 0xEE, 0}, ++ {7, 0x51, 0x99, 0x99, 1}, ++ {8, 0x51, 0x44, 0x44, 2}, ++ {9, 0x51, 0xEE, 0xEE, 2}, ++ {10, 0x51, 0x99, 0x99, 3}, ++ {11, 0x52, 0x44, 0x44, 0}, ++ {12, 0x52, 0xEE, 0xEE, 0}, ++ {13, 0x52, 0x99, 0x99, 1}, ++ {14, 0x52, 0x33, 0x33, 3}, ++}; ++ + static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) + { + struct hw_mode_spec *spec = &rt2x00dev->spec; +@@ -7849,6 +9209,11 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) + spec->channels = rf_vals_3x; + break; + ++ case RF7620: ++ spec->num_channels = ARRAY_SIZE(rf_vals_7620); ++ spec->channels = rf_vals_7620; ++ break; ++ + case RF3052: + case RF3053: + spec->num_channels = ARRAY_SIZE(rf_vals_3x); +@@ -7980,6 +9345,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) + case RF5390: + case RF5392: + case RF5592: ++ case RF7620: + __set_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags); + break; + } +@@ -8024,6 +9390,9 @@ static int rt2800_probe_rt(struct rt2x00_dev *rt2x00dev) + return -ENODEV; + } + ++ if (rt == RT5390 && rt2x00_is_soc(rt2x00dev)) ++ rt = RT6352; ++ + rt2x00_set_rt(rt2x00dev, rt, rev); + + return 0; +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +index d9ef260d542a..f357531d9488 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +@@ -33,6 +33,10 @@ + struct rt2800_drv_data { + u8 calibration_bw20; + u8 calibration_bw40; ++ char rx_calibration_bw20; ++ char rx_calibration_bw40; ++ char tx_calibration_bw20; ++ char tx_calibration_bw40; + u8 bbp25; + u8 bbp26; + u8 txmixer_gain_24g; +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +index ce340bfd71a0..8fdd2f9726ee 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -174,6 +174,7 @@ struct rt2x00_chip { + #define RT5390 0x5390 /* 2.4GHz */ + #define RT5392 0x5392 /* 2.4GHz */ + #define RT5592 0x5592 ++#define RT6352 0x6352 /* WSOC 2.4GHz */ + + u16 rf; + u16 rev; +-- +2.12.1 + diff --git a/package/kernel/mac80211/patches/030-rt2x00_options.patch b/package/kernel/mac80211/patches/030-rt2x00_options.patch index a4ca8848c6..9dd348151c 100644 --- a/package/kernel/mac80211/patches/030-rt2x00_options.patch +++ b/package/kernel/mac80211/patches/030-rt2x00_options.patch @@ -29,7 +29,7 @@ config RT2X00_LIB_SOC - tristate + tristate "RT2x00 SoC support" -+ depends on SOC_RT288X || SOC_RT305X ++ depends on SOC_RT288X || SOC_RT305X || SOC_MT7620 depends on m select RT2X00_LIB diff --git a/package/kernel/mac80211/patches/317-rt2x00-avoid-introducing-a-USB-dependency-in-the-rt2.patch b/package/kernel/mac80211/patches/317-rt2x00-avoid-introducing-a-USB-dependency-in-the-rt2.patch deleted file mode 100644 index c0274ddde9..0000000000 --- a/package/kernel/mac80211/patches/317-rt2x00-avoid-introducing-a-USB-dependency-in-the-rt2.patch +++ /dev/null @@ -1,73 +0,0 @@ -From: Stanislaw Gruszka -Date: Thu, 2 Feb 2017 10:57:40 +0100 -Subject: [PATCH] rt2x00: avoid introducing a USB dependency in the - rt2x00lib module - -As reported by Felix: - -Though protected by an ifdef, introducing an usb symbol dependency in -the rt2x00lib module is a major inconvenience for distributions that -package kernel modules split into individual packages. - -Get rid of this unnecessary dependency by calling the usb related -function from a more suitable place. - -Cc: Vishal Thanki -Reported-by: Felix Fietkau -Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB") -Signed-off-by: Stanislaw Gruszka ---- - ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -1436,21 +1436,6 @@ void rt2x00lib_remove_dev(struct rt2x00_ - cancel_work_sync(&rt2x00dev->intf_work); - cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); - cancel_work_sync(&rt2x00dev->sleep_work); --#if IS_ENABLED(CPTCFG_RT2X00_LIB_USB) -- if (rt2x00_is_usb(rt2x00dev)) { -- usb_kill_anchored_urbs(rt2x00dev->anchor); -- hrtimer_cancel(&rt2x00dev->txstatus_timer); -- cancel_work_sync(&rt2x00dev->rxdone_work); -- cancel_work_sync(&rt2x00dev->txdone_work); -- } --#endif -- if (rt2x00dev->workqueue) -- destroy_workqueue(rt2x00dev->workqueue); -- -- /* -- * Free the tx status fifo. -- */ -- kfifo_free(&rt2x00dev->txstatus_fifo); - - /* - * Kill the tx status tasklet. -@@ -1466,6 +1451,14 @@ void rt2x00lib_remove_dev(struct rt2x00_ - */ - rt2x00lib_uninitialize(rt2x00dev); - -+ if (rt2x00dev->workqueue) -+ destroy_workqueue(rt2x00dev->workqueue); -+ -+ /* -+ * Free the tx status fifo. -+ */ -+ kfifo_free(&rt2x00dev->txstatus_fifo); -+ - /* - * Free extra components - */ ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c -@@ -744,6 +744,11 @@ void rt2x00usb_uninitialize(struct rt2x0 - { - struct data_queue *queue; - -+ usb_kill_anchored_urbs(rt2x00dev->anchor); -+ hrtimer_cancel(&rt2x00dev->txstatus_timer); -+ cancel_work_sync(&rt2x00dev->rxdone_work); -+ cancel_work_sync(&rt2x00dev->txdone_work); -+ - queue_for_each(rt2x00dev, queue) - rt2x00usb_free_entries(queue); - } diff --git a/package/kernel/mac80211/patches/600-01-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch b/package/kernel/mac80211/patches/600-01-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch index 565e39de5f..699989baa0 100644 --- a/package/kernel/mac80211/patches/600-01-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch +++ b/package/kernel/mac80211/patches/600-01-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch @@ -14,8 +14,8 @@ Signed-off-by: Gabor Juhos config RT2800SOC tristate "Ralink WiSoC support" depends on m -- depends on SOC_RT288X || SOC_RT305X -+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 +- depends on SOC_RT288X || SOC_RT305X || SOC_MT7620 ++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620 select RT2X00_LIB_SOC select RT2X00_LIB_MMIO select RT2X00_LIB_CRYPTO @@ -23,8 +23,8 @@ Signed-off-by: Gabor Juhos config RT2X00_LIB_SOC tristate "RT2x00 SoC support" -- depends on SOC_RT288X || SOC_RT305X -+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 +- depends on SOC_RT288X || SOC_RT305X || SOC_MT7620 ++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620 depends on m select RT2X00_LIB diff --git a/package/kernel/mac80211/patches/600-02-rt2x00-rt2800lib-enable-support-for-RT3883.patch b/package/kernel/mac80211/patches/600-02-rt2x00-rt2800lib-enable-support-for-RT3883.patch index f8680108c8..2325f37670 100644 --- a/package/kernel/mac80211/patches/600-02-rt2x00-rt2800lib-enable-support-for-RT3883.patch +++ b/package/kernel/mac80211/patches/600-02-rt2x00-rt2800lib-enable-support-for-RT3883.patch @@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -7956,6 +7956,7 @@ static int rt2800_probe_rt(struct rt2x00 +@@ -9379,6 +9379,7 @@ static int rt2800_probe_rt(struct rt2x00 case RT3390: case RT3572: case RT3593: diff --git a/package/kernel/mac80211/patches/600-03-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch b/package/kernel/mac80211/patches/600-03-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch index 46e98aff0f..9775664deb 100644 --- a/package/kernel/mac80211/patches/600-03-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch +++ b/package/kernel/mac80211/patches/600-03-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch @@ -31,7 +31,7 @@ Signed-off-by: Gabor Juhos #define RF5362 0x5362 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -7557,6 +7557,66 @@ static const struct rf_channel rf_vals_3 +@@ -8957,6 +8957,66 @@ static const struct rf_channel rf_vals_3 {14, 0xF0, 2, 0x18}, }; @@ -98,7 +98,7 @@ Signed-off-by: Gabor Juhos static const struct rf_channel rf_vals_5592_xtal20[] = { /* Channel, N, K, mod, R */ {1, 482, 4, 10, 3}, -@@ -7798,6 +7858,11 @@ static int rt2800_probe_hw_mode(struct r +@@ -9220,6 +9280,11 @@ static int rt2800_probe_hw_mode(struct r spec->channels = rf_vals_3x; break; diff --git a/package/kernel/mac80211/patches/600-04-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch b/package/kernel/mac80211/patches/600-04-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch index eca49773ec..5737e015c1 100644 --- a/package/kernel/mac80211/patches/600-04-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch +++ b/package/kernel/mac80211/patches/600-04-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch @@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -4363,6 +4363,7 @@ void rt2800_vco_calibration(struct rt2x0 +@@ -4855,6 +4855,7 @@ void rt2800_vco_calibration(struct rt2x0 case RF3053: case RF3070: case RF3290: @@ -18,7 +18,7 @@ Signed-off-by: Gabor Juhos case RF5350: case RF5360: case RF5362: -@@ -7980,6 +7981,7 @@ static int rt2800_probe_hw_mode(struct r +@@ -9402,6 +9403,7 @@ static int rt2800_probe_hw_mode(struct r case RF3053: case RF3070: case RF3290: diff --git a/package/kernel/mac80211/patches/600-05-rt2x00-rt2800lib-add-channel-configuration-function-.patch b/package/kernel/mac80211/patches/600-05-rt2x00-rt2800lib-add-channel-configuration-function-.patch index a1e5883035..afcb6bdf4a 100644 --- a/package/kernel/mac80211/patches/600-05-rt2x00-rt2800lib-add-channel-configuration-function-.patch +++ b/package/kernel/mac80211/patches/600-05-rt2x00-rt2800lib-add-channel-configuration-function-.patch @@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -2584,6 +2584,211 @@ static void rt2800_config_channel_rf3053 +@@ -2709,6 +2709,211 @@ static void rt2800_config_channel_rf3053 } } @@ -223,7 +223,7 @@ Signed-off-by: Gabor Juhos #define POWER_BOUND 0x27 #define POWER_BOUND_5G 0x2b -@@ -3203,6 +3408,9 @@ static void rt2800_config_channel(struct +@@ -3565,6 +3770,9 @@ static void rt2800_config_channel(struct case RF3322: rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info); break; diff --git a/package/kernel/mac80211/patches/600-06-rt2x00-rt2800lib-enable-RF3853-support.patch b/package/kernel/mac80211/patches/600-06-rt2x00-rt2800lib-enable-RF3853-support.patch index 2d65119fd0..9579016595 100644 --- a/package/kernel/mac80211/patches/600-06-rt2x00-rt2800lib-enable-RF3853-support.patch +++ b/package/kernel/mac80211/patches/600-06-rt2x00-rt2800lib-enable-RF3853-support.patch @@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -7483,6 +7483,7 @@ static int rt2800_init_eeprom(struct rt2 +@@ -8882,6 +8882,7 @@ static int rt2800_init_eeprom(struct rt2 case RF3290: case RF3320: case RF3322: diff --git a/package/kernel/mac80211/patches/600-07-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch b/package/kernel/mac80211/patches/600-07-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch index d073c01697..08b54f6726 100644 --- a/package/kernel/mac80211/patches/600-07-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch +++ b/package/kernel/mac80211/patches/600-07-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch @@ -12,8 +12,8 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h -@@ -1574,6 +1574,20 @@ - #define TX_PWR_CFG_9_STBC7_CH2 FIELD32(0x00000f00) +@@ -1727,6 +1727,20 @@ + #define TX_PWR_CFG_9B_STBC_MCS7 FIELD32(0x000000ff) /* + * TX_TXBF_CFG: @@ -35,7 +35,7 @@ Signed-off-by: Gabor Juhos #define RX_FILTER_CFG 0x1400 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -4946,6 +4946,12 @@ static int rt2800_init_registers(struct +@@ -5485,6 +5485,12 @@ static int rt2800_init_registers(struct rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); } @@ -46,9 +46,9 @@ Signed-off-by: Gabor Juhos + rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21); + rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40); } else if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) { - rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); -@@ -5140,6 +5146,11 @@ static int rt2800_init_registers(struct + rt2x00_rt(rt2x00dev, RT5392) || + rt2x00_rt(rt2x00dev, RT6352)) { +@@ -5698,6 +5704,11 @@ static int rt2800_init_registers(struct reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002; rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg); diff --git a/package/kernel/mac80211/patches/600-09-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch b/package/kernel/mac80211/patches/600-09-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch index 41ed4d3de9..ced3645aef 100644 --- a/package/kernel/mac80211/patches/600-09-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch +++ b/package/kernel/mac80211/patches/600-09-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch @@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -5767,6 +5767,47 @@ static void rt2800_init_bbp_3593(struct +@@ -6325,6 +6325,47 @@ static void rt2800_init_bbp_3593(struct rt2800_bbp_write(rt2x00dev, 103, 0xc0); } @@ -59,7 +59,7 @@ Signed-off-by: Gabor Juhos static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev) { int ant, div_mode; -@@ -5986,6 +6027,9 @@ static void rt2800_init_bbp(struct rt2x0 +@@ -6769,6 +6810,9 @@ static void rt2800_init_bbp(struct rt2x0 case RT3593: rt2800_init_bbp_3593(rt2x00dev); return; diff --git a/package/kernel/mac80211/patches/600-10-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch b/package/kernel/mac80211/patches/600-10-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch index 7e772ec676..08e4ffe9ba 100644 --- a/package/kernel/mac80211/patches/600-10-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch +++ b/package/kernel/mac80211/patches/600-10-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch @@ -11,17 +11,17 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h -@@ -2155,6 +2155,7 @@ struct mac_iveiv_entry { +@@ -2311,6 +2311,7 @@ struct mac_iveiv_entry { /* * RFCSR 2: */ +#define RFCSR2_RESCAL_BP FIELD8(0x40) #define RFCSR2_RESCAL_EN FIELD8(0x80) - - /* + #define RFCSR2_RX2_EN_MT7620 FIELD8(0x02) + #define RFCSR2_TX2_EN_MT7620 FIELD8(0x20) --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -6899,6 +6899,144 @@ static void rt2800_init_rfcsr_5350(struc +@@ -7685,6 +7685,144 @@ static void rt2800_init_rfcsr_5350(struc rt2800_rfcsr_write(rt2x00dev, 63, 0x00); } @@ -166,7 +166,7 @@ Signed-off-by: Gabor Juhos static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) { rt2800_rf_init_calibration(rt2x00dev, 2); -@@ -7130,6 +7268,9 @@ static void rt2800_init_rfcsr(struct rt2 +@@ -8525,6 +8663,9 @@ static void rt2800_init_rfcsr(struct rt2 case RT3390: rt2800_init_rfcsr_3390(rt2x00dev); break; diff --git a/package/kernel/mac80211/patches/600-11-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch b/package/kernel/mac80211/patches/600-11-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch index 00e00b959f..0e9496c056 100644 --- a/package/kernel/mac80211/patches/600-11-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch +++ b/package/kernel/mac80211/patches/600-11-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch @@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -309,7 +309,8 @@ static unsigned int rt2800_eeprom_word_i +@@ -376,7 +376,8 @@ static unsigned int rt2800_eeprom_word_i wiphy_name(rt2x00dev->hw->wiphy), word)) return 0; diff --git a/package/kernel/mac80211/patches/600-12-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch b/package/kernel/mac80211/patches/600-12-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch index 11d3c8ccec..c03527b4f7 100644 --- a/package/kernel/mac80211/patches/600-12-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch +++ b/package/kernel/mac80211/patches/600-12-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch @@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -7660,6 +7660,8 @@ static int rt2800_init_eeprom(struct rt2 +@@ -9059,6 +9059,8 @@ static int rt2800_init_eeprom(struct rt2 rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); else if (rt2x00_rt(rt2x00dev, RT3352)) rf = RF3322; diff --git a/package/kernel/mac80211/patches/600-13-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch b/package/kernel/mac80211/patches/600-13-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch index beebe90d36..04574db7c1 100644 --- a/package/kernel/mac80211/patches/600-13-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch +++ b/package/kernel/mac80211/patches/600-13-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch @@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -3371,6 +3371,36 @@ static char rt2800_txpower_to_dev(struct +@@ -3733,6 +3733,36 @@ static char rt2800_txpower_to_dev(struct return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER); } @@ -47,7 +47,7 @@ Signed-off-by: Gabor Juhos static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf, struct rf_channel *rf, -@@ -3389,6 +3419,12 @@ static void rt2800_config_channel(struct +@@ -3751,6 +3781,12 @@ static void rt2800_config_channel(struct rt2800_txpower_to_dev(rt2x00dev, rf->channel, info->default_power3); @@ -60,7 +60,7 @@ Signed-off-by: Gabor Juhos switch (rt2x00dev->chip.rf) { case RF2020: case RF3020: -@@ -3490,6 +3526,15 @@ static void rt2800_config_channel(struct +@@ -3855,6 +3891,15 @@ static void rt2800_config_channel(struct rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); rt2800_bbp_write(rt2x00dev, 77, 0x98); @@ -76,15 +76,15 @@ Signed-off-by: Gabor Juhos } else { rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); -@@ -3502,6 +3547,7 @@ static void rt2800_config_channel(struct - !rt2x00_rt(rt2x00dev, RT5392)) { +@@ -3868,6 +3913,7 @@ static void rt2800_config_channel(struct + !rt2x00_rt(rt2x00dev, RT6352)) { if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { rt2800_bbp_write(rt2x00dev, 82, 0x62); + rt2800_bbp_write(rt2x00dev, 82, 0x62); rt2800_bbp_write(rt2x00dev, 75, 0x46); } else { if (rt2x00_rt(rt2x00dev, RT3593)) -@@ -3510,19 +3556,22 @@ static void rt2800_config_channel(struct +@@ -3876,19 +3922,22 @@ static void rt2800_config_channel(struct rt2800_bbp_write(rt2x00dev, 82, 0x84); rt2800_bbp_write(rt2x00dev, 75, 0x50); } @@ -101,7 +101,7 @@ Signed-off-by: Gabor Juhos + else if (rt2x00_rt(rt2x00dev, RT3593) || + rt2x00_rt(rt2x00dev, RT3883)) rt2800_bbp_write(rt2x00dev, 82, 0x82); - else + else if (!rt2x00_rt(rt2x00dev, RT6352)) rt2800_bbp_write(rt2x00dev, 82, 0xf2); - if (rt2x00_rt(rt2x00dev, RT3593)) @@ -110,7 +110,7 @@ Signed-off-by: Gabor Juhos rt2800_bbp_write(rt2x00dev, 83, 0x9a); if (rt2x00_has_cap_external_lna_a(rt2x00dev)) -@@ -3644,6 +3693,23 @@ static void rt2800_config_channel(struct +@@ -4011,6 +4060,23 @@ static void rt2800_config_channel(struct rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); diff --git a/package/kernel/mac80211/patches/600-14-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch b/package/kernel/mac80211/patches/600-14-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch index f18f9d5714..3412a3e133 100644 --- a/package/kernel/mac80211/patches/600-14-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch +++ b/package/kernel/mac80211/patches/600-14-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch @@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -3358,13 +3358,15 @@ static char rt2800_txpower_to_dev(struct +@@ -3720,13 +3720,15 @@ static char rt2800_txpower_to_dev(struct unsigned int channel, char txpower) { diff --git a/package/kernel/mac80211/patches/600-15-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch b/package/kernel/mac80211/patches/600-15-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch index 0acdf2af79..8d1df8cf77 100644 --- a/package/kernel/mac80211/patches/600-15-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch +++ b/package/kernel/mac80211/patches/600-15-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch @@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -4596,7 +4596,8 @@ static void rt2800_config_txpower(struct +@@ -5085,7 +5085,8 @@ static void rt2800_config_txpower(struct struct ieee80211_channel *chan, int power_level) { @@ -19,5 +19,5 @@ Signed-off-by: Gabor Juhos + if (rt2x00_rt(rt2x00dev, RT3593) || + rt2x00_rt(rt2x00dev, RT3883)) rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level); - else - rt2800_config_txpower_rt28xx(rt2x00dev, chan, power_level); + else if (rt2x00_rt(rt2x00dev, RT6352)) + rt2800_config_txpower_rt6352(rt2x00dev, chan, power_level); diff --git a/package/kernel/mac80211/patches/600-16-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch b/package/kernel/mac80211/patches/600-16-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch index 5877a32bd8..9aeb41fe6b 100644 --- a/package/kernel/mac80211/patches/600-16-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch +++ b/package/kernel/mac80211/patches/600-16-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch @@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -7543,7 +7543,8 @@ static u8 rt2800_get_txmixer_gain_24g(st +@@ -8941,7 +8941,8 @@ static u8 rt2800_get_txmixer_gain_24g(st { u16 word; @@ -21,7 +21,7 @@ Signed-off-by: Gabor Juhos return 0; rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word); -@@ -7557,7 +7558,8 @@ static u8 rt2800_get_txmixer_gain_5g(str +@@ -8955,7 +8956,8 @@ static u8 rt2800_get_txmixer_gain_5g(str { u16 word; diff --git a/package/kernel/mac80211/patches/600-17-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch b/package/kernel/mac80211/patches/600-17-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch index abc6eb4414..9d12c76255 100644 --- a/package/kernel/mac80211/patches/600-17-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch +++ b/package/kernel/mac80211/patches/600-17-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch @@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -520,6 +520,7 @@ void rt2800_get_txwi_rxwi_size(struct rt +@@ -587,6 +587,7 @@ void rt2800_get_txwi_rxwi_size(struct rt { switch (rt2x00dev->chip.rt) { case RT3593: diff --git a/package/kernel/mac80211/patches/600-18-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch b/package/kernel/mac80211/patches/600-18-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch index c1e41bb84e..cd212f9d8d 100644 --- a/package/kernel/mac80211/patches/600-18-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch +++ b/package/kernel/mac80211/patches/600-18-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch @@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -1888,7 +1888,8 @@ void rt2800_config_ant(struct rt2x00_dev +@@ -2013,7 +2013,8 @@ void rt2800_config_ant(struct rt2x00_dev rt2800_bbp_write(rt2x00dev, 3, r3); rt2800_bbp_write(rt2x00dev, 1, r1); diff --git a/package/kernel/mac80211/patches/600-19-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch b/package/kernel/mac80211/patches/600-19-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch index 645b3c54e9..30ea12a5cd 100644 --- a/package/kernel/mac80211/patches/600-19-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch +++ b/package/kernel/mac80211/patches/600-19-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch @@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -1911,7 +1911,8 @@ static void rt2800_config_lna_gain(struc +@@ -2036,7 +2036,8 @@ static void rt2800_config_lna_gain(struc rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom); lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0); } else if (libconf->rf.channel <= 128) { @@ -20,7 +20,7 @@ Signed-off-by: Gabor Juhos rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom); lna_gain = rt2x00_get_field16(eeprom, EEPROM_EXT_LNA2_A1); -@@ -1921,7 +1922,8 @@ static void rt2800_config_lna_gain(struc +@@ -2046,7 +2047,8 @@ static void rt2800_config_lna_gain(struc EEPROM_RSSI_BG2_LNA_A1); } } else { diff --git a/package/kernel/mac80211/patches/600-20-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch b/package/kernel/mac80211/patches/600-20-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch index 57ea80ea0f..70c33a1d20 100644 --- a/package/kernel/mac80211/patches/600-20-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch +++ b/package/kernel/mac80211/patches/600-20-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch @@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -4799,7 +4799,8 @@ static u8 rt2800_get_default_vgc(struct +@@ -5338,7 +5338,8 @@ static u8 rt2800_get_default_vgc(struct else vgc = 0x2e + rt2x00dev->lna_gain; } else { /* 5GHZ band */ @@ -20,7 +20,7 @@ Signed-off-by: Gabor Juhos vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3; else if (rt2x00_rt(rt2x00dev, RT5592)) vgc = 0x24 + (2 * rt2x00dev->lna_gain); -@@ -4819,7 +4820,8 @@ static inline void rt2800_set_vgc(struct +@@ -5358,7 +5359,8 @@ static inline void rt2800_set_vgc(struct { if (qual->vgc_level != vgc_level) { if (rt2x00_rt(rt2x00dev, RT3572) || @@ -30,7 +30,7 @@ Signed-off-by: Gabor Juhos rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, vgc_level); } else if (rt2x00_rt(rt2x00dev, RT5592)) { -@@ -4866,6 +4868,11 @@ void rt2800_link_tuner(struct rt2x00_dev +@@ -5405,6 +5407,11 @@ void rt2800_link_tuner(struct rt2x00_dev } break; diff --git a/package/kernel/mac80211/patches/600-21-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch b/package/kernel/mac80211/patches/600-21-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch index bb6f4fd684..a2cfd896eb 100644 --- a/package/kernel/mac80211/patches/600-21-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch +++ b/package/kernel/mac80211/patches/600-21-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch @@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -7676,7 +7676,8 @@ static int rt2800_validate_eeprom(struct +@@ -9074,7 +9074,8 @@ static int rt2800_validate_eeprom(struct rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word); if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10) rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0); @@ -20,7 +20,7 @@ Signed-off-by: Gabor Juhos if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 || rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff) rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1, -@@ -7696,7 +7697,8 @@ static int rt2800_validate_eeprom(struct +@@ -9094,7 +9095,8 @@ static int rt2800_validate_eeprom(struct rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word); if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10) rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0); @@ -30,7 +30,7 @@ Signed-off-by: Gabor Juhos if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 || rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff) rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2, -@@ -7704,7 +7706,8 @@ static int rt2800_validate_eeprom(struct +@@ -9102,7 +9104,8 @@ static int rt2800_validate_eeprom(struct } rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); diff --git a/package/kernel/mac80211/patches/600-22-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch b/package/kernel/mac80211/patches/600-22-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch index b4872b5108..ac8b219efd 100644 --- a/package/kernel/mac80211/patches/600-22-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch +++ b/package/kernel/mac80211/patches/600-22-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch @@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -3965,6 +3965,9 @@ static u8 rt2800_compensate_txpower(stru +@@ -4332,6 +4332,9 @@ static u8 rt2800_compensate_txpower(stru if (rt2x00_rt(rt2x00dev, RT3593)) return min_t(u8, txpower, 0xc); diff --git a/package/kernel/mac80211/patches/600-23-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch b/package/kernel/mac80211/patches/600-23-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch index a6dc6a6afb..7d8d2f5e13 100644 --- a/package/kernel/mac80211/patches/600-23-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch +++ b/package/kernel/mac80211/patches/600-23-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch @@ -122,7 +122,7 @@ Signed-off-by: Gabor Juhos */ --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -999,6 +999,11 @@ struct rt2x00_dev { +@@ -1000,6 +1000,11 @@ struct rt2x00_dev { int rf_channel; /* diff --git a/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00eeprom.patch b/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00eeprom.patch index 65711ae330..435cc96fc5 100644 --- a/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00eeprom.patch +++ b/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00eeprom.patch @@ -48,16 +48,16 @@ obj-$(CPTCFG_RT2X00_LIB_MMIO) += rt2x00mmio.o --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -@@ -20,6 +20,8 @@ - #ifndef RT2800LIB_H - #define RT2800LIB_H +@@ -48,6 +48,8 @@ struct rt2800_drv_data { + struct ieee80211_sta *wcid_to_sta[STA_IDS_SIZE]; + }; +#include "rt2800.h" + struct rt2800_ops { void (*register_read)(struct rt2x00_dev *rt2x00dev, const unsigned int offset, u32 *value); -@@ -119,6 +121,15 @@ static inline int rt2800_read_eeprom(str +@@ -147,6 +149,15 @@ static inline int rt2800_read_eeprom(str { const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; @@ -105,7 +105,7 @@ .drv_init_registers = rt2800mmio_init_registers, --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -701,6 +701,7 @@ enum rt2x00_capability_flags { +@@ -702,6 +702,7 @@ enum rt2x00_capability_flags { REQUIRE_HT_TX_DESC, REQUIRE_PS_AUTOWAKE, REQUIRE_DELAYED_RFKILL, @@ -113,7 +113,7 @@ /* * Capabilities -@@ -976,6 +977,11 @@ struct rt2x00_dev { +@@ -977,6 +978,11 @@ struct rt2x00_dev { const struct firmware *fw; /* @@ -127,7 +127,7 @@ DECLARE_KFIFO_PTR(txstatus_fifo, u32); --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -1346,6 +1346,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de +@@ -1418,6 +1418,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep); @@ -138,7 +138,7 @@ /* * Let the driver probe the device to detect the capabilities. */ -@@ -1484,6 +1488,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ +@@ -1556,6 +1560,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ * Free the driver data. */ kfree(rt2x00dev->drv_data); diff --git a/package/kernel/mac80211/patches/606-rt2x00-allow_disabling_bands_through_platform_data.patch b/package/kernel/mac80211/patches/606-rt2x00-allow_disabling_bands_through_platform_data.patch index 522670ece7..c3cd2f4341 100644 --- a/package/kernel/mac80211/patches/606-rt2x00-allow_disabling_bands_through_platform_data.patch +++ b/package/kernel/mac80211/patches/606-rt2x00-allow_disabling_bands_through_platform_data.patch @@ -12,7 +12,7 @@ #endif /* _RT2X00_PLATFORM_H */ --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -951,6 +951,22 @@ static int rt2x00lib_probe_hw_modes(stru +@@ -1023,6 +1023,22 @@ static int rt2x00lib_probe_hw_modes(stru unsigned int num_rates; unsigned int i; @@ -37,7 +37,7 @@ num_rates += 4; --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -408,6 +408,7 @@ struct hw_mode_spec { +@@ -409,6 +409,7 @@ struct hw_mode_spec { unsigned int supported_bands; #define SUPPORT_BAND_2GHZ 0x00000001 #define SUPPORT_BAND_5GHZ 0x00000002 diff --git a/package/kernel/mac80211/patches/607-rt2x00-add_platform_data_mac_addr.patch b/package/kernel/mac80211/patches/607-rt2x00-add_platform_data_mac_addr.patch index 5a3f858090..bca7be8533 100644 --- a/package/kernel/mac80211/patches/607-rt2x00-add_platform_data_mac_addr.patch +++ b/package/kernel/mac80211/patches/607-rt2x00-add_platform_data_mac_addr.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -929,8 +929,13 @@ static void rt2x00lib_rate(struct ieee80 +@@ -1001,8 +1001,13 @@ static void rt2x00lib_rate(struct ieee80 void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr) { diff --git a/package/kernel/mac80211/patches/608-rt2x00-allow_disabling_bands_through_dts.patch b/package/kernel/mac80211/patches/608-rt2x00-allow_disabling_bands_through_dts.patch index e312c1dc8a..724e626ca9 100644 --- a/package/kernel/mac80211/patches/608-rt2x00-allow_disabling_bands_through_dts.patch +++ b/package/kernel/mac80211/patches/608-rt2x00-allow_disabling_bands_through_dts.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -955,6 +955,16 @@ static int rt2x00lib_probe_hw_modes(stru +@@ -1027,6 +1027,16 @@ static int rt2x00lib_probe_hw_modes(stru struct ieee80211_rate *rates; unsigned int num_rates; unsigned int i; diff --git a/package/kernel/mac80211/patches/610-rt2x00-change-led-polarity-from-OF.patch b/package/kernel/mac80211/patches/610-rt2x00-change-led-polarity-from-OF.patch index 89fc706100..0236683d5f 100644 --- a/package/kernel/mac80211/patches/610-rt2x00-change-led-polarity-from-OF.patch +++ b/package/kernel/mac80211/patches/610-rt2x00-change-led-polarity-from-OF.patch @@ -8,7 +8,7 @@ #include "rt2x00.h" #include "rt2800lib.h" -@@ -7861,6 +7862,17 @@ static int rt2800_init_eeprom(struct rt2 +@@ -9261,6 +9262,17 @@ static int rt2800_init_eeprom(struct rt2 rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); diff --git a/package/kernel/mac80211/patches/611-rt2x00-add-AP+STA-support.patch b/package/kernel/mac80211/patches/611-rt2x00-add-AP+STA-support.patch index 2dac89566a..5ef5fc8def 100644 --- a/package/kernel/mac80211/patches/611-rt2x00-add-AP+STA-support.patch +++ b/package/kernel/mac80211/patches/611-rt2x00-add-AP+STA-support.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -1286,7 +1286,7 @@ static inline void rt2x00lib_set_if_comb +@@ -1358,7 +1358,7 @@ static inline void rt2x00lib_set_if_comb */ if_limit = &rt2x00dev->if_limits_ap; if_limit->max = rt2x00dev->ops->max_ap_intf; diff --git a/package/kernel/mac80211/patches/620-rt2x00-enable-rt2800soc-for-mt7620.patch b/package/kernel/mac80211/patches/620-rt2x00-enable-rt2800soc-for-mt7620.patch deleted file mode 100644 index bc9f799520..0000000000 --- a/package/kernel/mac80211/patches/620-rt2x00-enable-rt2800soc-for-mt7620.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/drivers/net/wireless/ralink/rt2x00/Kconfig -+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig -@@ -211,7 +211,7 @@ endif - config RT2800SOC - tristate "Ralink WiSoC support" - depends on m -- depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 -+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620 - select RT2X00_LIB_SOC - select RT2X00_LIB_MMIO - select RT2X00_LIB_CRYPTO -@@ -248,7 +248,7 @@ config RT2X00_LIB_PCI - - config RT2X00_LIB_SOC - tristate "RT2x00 SoC support" -- depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 -+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620 - depends on m - select RT2X00_LIB - diff --git a/package/kernel/mac80211/patches/621-rt2x00-add-support-for-mt7620.patch b/package/kernel/mac80211/patches/621-rt2x00-add-support-for-mt7620.patch deleted file mode 100644 index b7a0ad1327..0000000000 --- a/package/kernel/mac80211/patches/621-rt2x00-add-support-for-mt7620.patch +++ /dev/null @@ -1,2057 +0,0 @@ -From 5a53fd87e4691343fdb60be147ee859975071df6 Mon Sep 17 00:00:00 2001 -In-Reply-To: <20170311103750.GA17556@redhat.com> -References: <20170311103750.GA17556@redhat.com> -From: Daniel Golle -Date: Tue, 1 Jul 2014 10:26:18 +0000 -Subject: [PATCH] mac80211: rt2x00: add support for MT7620 -To: Stanislaw Gruszka -Cc: Helmut Schaa , - linux-wireless@vger.kernel.org, - Kalle Valo - -From: Roman Yeryomin - -Basic support for MT7620 built-in wireless radio was added to -OpenWrt in r41441. It has seen some heavy cleaning and refactoring -since in order to match the Kernel's code quality standards. - -Signed-off-by: Roman Yeryomin -Signed-off-by: Daniel Golle ---- - drivers/net/wireless/ralink/rt2x00/rt2800.h | 177 +++ - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 1421 +++++++++++++++++++++++- - drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 4 + - drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 + - 4 files changed, 1577 insertions(+), 26 deletions(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h -@@ -81,6 +81,7 @@ - #define RF5372 0x5372 - #define RF5390 0x5390 - #define RF5392 0x5392 -+#define RF7620 0x7620 - - /* - * Chipset revisions. -@@ -641,6 +642,24 @@ - #define RF_CSR_CFG_BUSY FIELD32(0x00020000) - - /* -+ * MT7620 RF registers (reversed order) -+ */ -+#define RF_CSR_CFG_DATA_MT7620 FIELD32(0x0000ff00) -+#define RF_CSR_CFG_REGNUM_MT7620 FIELD32(0x03ff0000) -+#define RF_CSR_CFG_WRITE_MT7620 FIELD32(0x00000010) -+#define RF_CSR_CFG_BUSY_MT7620 FIELD32(0x00000001) -+ -+/* undocumented registers for calibration of new MAC */ -+#define RF_CONTROL0 0x0518 -+#define RF_BYPASS0 0x051c -+#define RF_CONTROL1 0x0520 -+#define RF_BYPASS1 0x0524 -+#define RF_CONTROL2 0x0528 -+#define RF_BYPASS2 0x052c -+#define RF_CONTROL3 0x0530 -+#define RF_BYPASS3 0x0534 -+ -+/* - * EFUSE_CSR: RT30x0 EEPROM - */ - #define EFUSE_CTRL 0x0580 -@@ -1024,6 +1043,16 @@ - #define AUTOWAKEUP_CFG_AUTOWAKE FIELD32(0x00008000) - - /* -+ * MIMO_PS_CFG: MIMO Power-save Configuration -+ */ -+#define MIMO_PS_CFG 0x1210 -+#define MIMO_PS_CFG_MMPS_BB_EN FIELD32(0x00000001) -+#define MIMO_PS_CFG_MMPS_RX_ANT_NUM FIELD32(0x00000006) -+#define MIMO_PS_CFG_MMPS_RF_EN FIELD32(0x00000008) -+#define MIMO_PS_CFG_RX_STBY_POL FIELD32(0x00000010) -+#define MIMO_PS_CFG_RX_RX_STBY0 FIELD32(0x00000020) -+ -+/* - * EDCA_AC0_CFG: - */ - #define EDCA_AC0_CFG 0x1300 -@@ -1097,6 +1126,12 @@ - #define TX_PWR_CFG_0_OFDM6_CH1 FIELD32(0x00f00000) - #define TX_PWR_CFG_0_OFDM12_CH0 FIELD32(0x0f000000) - #define TX_PWR_CFG_0_OFDM12_CH1 FIELD32(0xf0000000) -+/* bits for new 2T devices */ -+#define TX_PWR_CFG_0B_1MBS_2MBS FIELD32(0x000000ff) -+#define TX_PWR_CFG_0B_5MBS_11MBS FIELD32(0x0000ff00) -+#define TX_PWR_CFG_0B_6MBS_9MBS FIELD32(0x00ff0000) -+#define TX_PWR_CFG_0B_12MBS_18MBS FIELD32(0xff000000) -+ - - /* - * TX_PWR_CFG_1: -@@ -1119,6 +1154,11 @@ - #define TX_PWR_CFG_1_MCS0_CH1 FIELD32(0x00f00000) - #define TX_PWR_CFG_1_MCS2_CH0 FIELD32(0x0f000000) - #define TX_PWR_CFG_1_MCS2_CH1 FIELD32(0xf0000000) -+/* bits for new 2T devices */ -+#define TX_PWR_CFG_1B_24MBS_36MBS FIELD32(0x000000ff) -+#define TX_PWR_CFG_1B_48MBS FIELD32(0x0000ff00) -+#define TX_PWR_CFG_1B_MCS0_MCS1 FIELD32(0x00ff0000) -+#define TX_PWR_CFG_1B_MCS2_MCS3 FIELD32(0xff000000) - - /* - * TX_PWR_CFG_2: -@@ -1141,6 +1181,11 @@ - #define TX_PWR_CFG_2_MCS8_CH1 FIELD32(0x00f00000) - #define TX_PWR_CFG_2_MCS10_CH0 FIELD32(0x0f000000) - #define TX_PWR_CFG_2_MCS10_CH1 FIELD32(0xf0000000) -+/* bits for new 2T devices */ -+#define TX_PWR_CFG_2B_MCS4_MCS5 FIELD32(0x000000ff) -+#define TX_PWR_CFG_2B_MCS6_MCS7 FIELD32(0x0000ff00) -+#define TX_PWR_CFG_2B_MCS8_MCS9 FIELD32(0x00ff0000) -+#define TX_PWR_CFG_2B_MCS10_MCS11 FIELD32(0xff000000) - - /* - * TX_PWR_CFG_3: -@@ -1163,6 +1208,11 @@ - #define TX_PWR_CFG_3_STBC0_CH1 FIELD32(0x00f00000) - #define TX_PWR_CFG_3_STBC2_CH0 FIELD32(0x0f000000) - #define TX_PWR_CFG_3_STBC2_CH1 FIELD32(0xf0000000) -+/* bits for new 2T devices */ -+#define TX_PWR_CFG_3B_MCS12_MCS13 FIELD32(0x000000ff) -+#define TX_PWR_CFG_3B_MCS14 FIELD32(0x0000ff00) -+#define TX_PWR_CFG_3B_STBC_MCS0_MCS1 FIELD32(0x00ff0000) -+#define TX_PWR_CFG_3B_STBC_MCS2_MSC3 FIELD32(0xff000000) - - /* - * TX_PWR_CFG_4: -@@ -1177,6 +1227,9 @@ - #define TX_PWR_CFG_3_STBC4_CH1 FIELD32(0x000000f0) - #define TX_PWR_CFG_3_STBC6_CH0 FIELD32(0x00000f00) - #define TX_PWR_CFG_3_STBC6_CH1 FIELD32(0x0000f000) -+/* bits for new 2T devices */ -+#define TX_PWR_CFG_4B_STBC_MCS4_MCS5 FIELD32(0x000000ff) -+#define TX_PWR_CFG_4B_STBC_MCS6 FIELD32(0x0000ff00) - - /* - * TX_PIN_CFG: -@@ -1203,6 +1256,8 @@ - #define TX_PIN_CFG_RFTR_POL FIELD32(0x00020000) - #define TX_PIN_CFG_TRSW_EN FIELD32(0x00040000) - #define TX_PIN_CFG_TRSW_POL FIELD32(0x00080000) -+#define TX_PIN_CFG_RFRX_EN FIELD32(0x00100000) -+#define TX_PIN_CFG_RFRX_POL FIELD32(0x00200000) - #define TX_PIN_CFG_PA_PE_A2_EN FIELD32(0x01000000) - #define TX_PIN_CFG_PA_PE_G2_EN FIELD32(0x02000000) - #define TX_PIN_CFG_PA_PE_A2_POL FIELD32(0x04000000) -@@ -1549,6 +1604,95 @@ - #define TX_PWR_CFG_4_EXT_STBC4_CH2 FIELD32(0x0000000f) - #define TX_PWR_CFG_4_EXT_STBC6_CH2 FIELD32(0x00000f00) - -+/* TXn_RF_GAIN_CORRECT: RF Gain Correction for each RF_ALC[3:2] -+ * Unit: 0.1 dB, Range: -3.2 dB to 3.1 dB -+ */ -+#define TX0_RF_GAIN_CORRECT 0x13a0 -+#define TX0_RF_GAIN_CORRECT_GAIN_CORR_0 FIELD32(0x0000003f) -+#define TX0_RF_GAIN_CORRECT_GAIN_CORR_1 FIELD32(0x00003f00) -+#define TX0_RF_GAIN_CORRECT_GAIN_CORR_2 FIELD32(0x003f0000) -+#define TX0_RF_GAIN_CORRECT_GAIN_CORR_3 FIELD32(0x3f000000) -+ -+#define TX1_RF_GAIN_CORRECT 0x13a4 -+#define TX1_RF_GAIN_CORRECT_GAIN_CORR_0 FIELD32(0x0000003f) -+#define TX1_RF_GAIN_CORRECT_GAIN_CORR_1 FIELD32(0x00003f00) -+#define TX1_RF_GAIN_CORRECT_GAIN_CORR_2 FIELD32(0x003f0000) -+#define TX1_RF_GAIN_CORRECT_GAIN_CORR_3 FIELD32(0x3f000000) -+ -+/* TXn_RF_GAIN_ATTEN: TXn RF Gain Attenuation Level -+ * Format: 7-bit, signed value -+ * Unit: 0.5 dB, Range: -20 dB to -5 dB -+ */ -+#define TX0_RF_GAIN_ATTEN 0x13a8 -+#define TX0_RF_GAIN_ATTEN_LEVEL_0 FIELD32(0x0000007f) -+#define TX0_RF_GAIN_ATTEN_LEVEL_1 FIELD32(0x00007f00) -+#define TX0_RF_GAIN_ATTEN_LEVEL_2 FIELD32(0x007f0000) -+#define TX0_RF_GAIN_ATTEN_LEVEL_3 FIELD32(0x7f000000) -+#define TX1_RF_GAIN_ATTEN 0x13ac -+#define TX1_RF_GAIN_ATTEN_LEVEL_0 FIELD32(0x0000007f) -+#define TX1_RF_GAIN_ATTEN_LEVEL_1 FIELD32(0x00007f00) -+#define TX1_RF_GAIN_ATTEN_LEVEL_2 FIELD32(0x007f0000) -+#define TX1_RF_GAIN_ATTEN_LEVEL_3 FIELD32(0x7f000000) -+ -+/* TX_ALC_CFG_0: TX Automatic Level Control Configuration 0 -+ * TX_ALC_LIMIT_n: TXn upper limit -+ * TX_ALC_CH_INIT_n: TXn channel initial transmission gain -+ * Unit: 0.5 dB, Range: 0 to 23.5 dB -+ */ -+#define TX_ALC_CFG_0 0x13b0 -+#define TX_ALC_CFG_0_CH_INIT_0 FIELD32(0x0000003f) -+#define TX_ALC_CFG_0_CH_INIT_1 FIELD32(0x00003f00) -+#define TX_ALC_CFG_0_LIMIT_0 FIELD32(0x003f0000) -+#define TX_ALC_CFG_0_LIMIT_1 FIELD32(0x3f000000) -+ -+/* TX_ALC_CFG_1: TX Automatic Level Control Configuration 1 -+ * TX_TEMP_COMP: TX Power Temperature Compensation -+ * Unit: 0.5 dB, Range: -10 dB to 10 dB -+ * TXn_GAIN_FINE: TXn Gain Fine Adjustment -+ * Unit: 0.1 dB, Range: -0.8 dB to 0.7 dB -+ * RF_TOS_DLY: Sets the RF_TOS_EN assertion delay after -+ * deassertion of PA_PE. -+ * Unit: 0.25 usec -+ * TXn_RF_GAIN_ATTEN: TXn RF gain attentuation selector -+ * RF_TOS_TIMEOUT: time-out value for RF_TOS_ENABLE -+ * deassertion if RF_TOS_DONE is missing. -+ * Unit: 0.25 usec -+ * RF_TOS_ENABLE: TX offset calibration enable -+ * ROS_BUSY_EN: RX offset calibration busy enable -+ */ -+#define TX_ALC_CFG_1 0x13b4 -+#define TX_ALC_CFG_1_TX_TEMP_COMP FIELD32(0x0000003f) -+#define TX_ALC_CFG_1_TX0_GAIN_FINE FIELD32(0x00000f00) -+#define TX_ALC_CFG_1_TX1_GAIN_FINE FIELD32(0x0000f000) -+#define TX_ALC_CFG_1_RF_TOS_DLY FIELD32(0x00070000) -+#define TX_ALC_CFG_1_TX0_RF_GAIN_ATTEN FIELD32(0x00300000) -+#define TX_ALC_CFG_1_TX1_RF_GAIN_ATTEN FIELD32(0x00c00000) -+#define TX_ALC_CFG_1_RF_TOS_TIMEOUT FIELD32(0x3f000000) -+#define TX_ALC_CFG_1_RF_TOS_ENABLE FIELD32(0x40000000) -+#define TX_ALC_CFG_1_ROS_BUSY_EN FIELD32(0x80000000) -+ -+/* TXn_BB_GAIN_ATTEN: TXn RF Gain Attenuation Level -+ * Format: 5-bit signed values -+ * Unit: 0.5 dB, Range: -8 dB to 7 dB -+ */ -+#define TX0_BB_GAIN_ATTEN 0x13c0 -+#define TX0_BB_GAIN_ATTEN_LEVEL_0 FIELD32(0x0000001f) -+#define TX0_BB_GAIN_ATTEN_LEVEL_1 FIELD32(0x00001f00) -+#define TX0_BB_GAIN_ATTEN_LEVEL_2 FIELD32(0x001f0000) -+#define TX0_BB_GAIN_ATTEN_LEVEL_3 FIELD32(0x1f000000) -+#define TX1_BB_GAIN_ATTEN 0x13c4 -+#define TX1_BB_GAIN_ATTEN_LEVEL_0 FIELD32(0x0000001f) -+#define TX1_BB_GAIN_ATTEN_LEVEL_1 FIELD32(0x00001f00) -+#define TX1_BB_GAIN_ATTEN_LEVEL_2 FIELD32(0x001f0000) -+#define TX1_BB_GAIN_ATTEN_LEVEL_3 FIELD32(0x1f000000) -+ -+/* TX_ALC_VGA3: TX Automatic Level Correction Variable Gain Amplifier 3 */ -+#define TX_ALC_VGA3 0x13c8 -+#define TX_ALC_VGA3_TX0_ALC_VGA3 FIELD32(0x0000001f) -+#define TX_ALC_VGA3_TX1_ALC_VGA3 FIELD32(0x00001f00) -+#define TX_ALC_VGA3_TX0_ALC_VGA2 FIELD32(0x001f0000) -+#define TX_ALC_VGA3_TX1_ALC_VGA2 FIELD32(0x1f000000) -+ - /* TX_PWR_CFG_7 */ - #define TX_PWR_CFG_7 0x13d4 - #define TX_PWR_CFG_7_OFDM54_CH0 FIELD32(0x0000000f) -@@ -1557,6 +1701,10 @@ - #define TX_PWR_CFG_7_MCS7_CH0 FIELD32(0x000f0000) - #define TX_PWR_CFG_7_MCS7_CH1 FIELD32(0x00f00000) - #define TX_PWR_CFG_7_MCS7_CH2 FIELD32(0x0f000000) -+/* bits for new 2T devices */ -+#define TX_PWR_CFG_7B_54MBS FIELD32(0x000000ff) -+#define TX_PWR_CFG_7B_MCS7 FIELD32(0x00ff0000) -+ - - /* TX_PWR_CFG_8 */ - #define TX_PWR_CFG_8 0x13d8 -@@ -1566,12 +1714,17 @@ - #define TX_PWR_CFG_8_MCS23_CH0 FIELD32(0x000f0000) - #define TX_PWR_CFG_8_MCS23_CH1 FIELD32(0x00f00000) - #define TX_PWR_CFG_8_MCS23_CH2 FIELD32(0x0f000000) -+/* bits for new 2T devices */ -+#define TX_PWR_CFG_8B_MCS15 FIELD32(0x000000ff) -+ - - /* TX_PWR_CFG_9 */ - #define TX_PWR_CFG_9 0x13dc - #define TX_PWR_CFG_9_STBC7_CH0 FIELD32(0x0000000f) - #define TX_PWR_CFG_9_STBC7_CH1 FIELD32(0x000000f0) - #define TX_PWR_CFG_9_STBC7_CH2 FIELD32(0x00000f00) -+/* bits for new 2T devices */ -+#define TX_PWR_CFG_9B_STBC_MCS7 FIELD32(0x000000ff) - - /* - * TX_TXBF_CFG: -@@ -2151,12 +2304,15 @@ struct mac_iveiv_entry { - #define RFCSR1_TX1_PD FIELD8(0x20) - #define RFCSR1_RX2_PD FIELD8(0x40) - #define RFCSR1_TX2_PD FIELD8(0x80) -+#define RFCSR1_TX2_EN_MT7620 FIELD8(0x02) - - /* - * RFCSR 2: - */ - #define RFCSR2_RESCAL_BP FIELD8(0x40) - #define RFCSR2_RESCAL_EN FIELD8(0x80) -+#define RFCSR2_RX2_EN_MT7620 FIELD8(0x02) -+#define RFCSR2_TX2_EN_MT7620 FIELD8(0x20) - - /* - * RFCSR 3: -@@ -2175,6 +2331,12 @@ struct mac_iveiv_entry { - #define RFCSR3_BIT5 FIELD8(0x20) - - /* -+ * RFCSR 4: -+ * VCOCAL_EN used by MT7620 -+ */ -+#define RFCSR4_VCOCAL_EN FIELD8(0x80) -+ -+/* - * FRCSR 5: - */ - #define RFCSR5_R1 FIELD8(0x0c) -@@ -2229,6 +2391,7 @@ struct mac_iveiv_entry { - */ - #define RFCSR13_TX_POWER FIELD8(0x1f) - #define RFCSR13_DR0 FIELD8(0xe0) -+#define RFCSR13_RDIV_MT7620 FIELD8(0x03) - - /* - * RFCSR 15: -@@ -2239,6 +2402,8 @@ struct mac_iveiv_entry { - * RFCSR 16: - */ - #define RFCSR16_TXMIXER_GAIN FIELD8(0x07) -+#define RFCSR16_RF_PLL_FREQ_SEL_MT7620 FIELD8(0x0F) -+#define RFCSR16_SDM_MODE_MT7620 FIELD8(0xE0) - - /* - * RFCSR 17: -@@ -2251,6 +2416,8 @@ struct mac_iveiv_entry { - /* RFCSR 18 */ - #define RFCSR18_XO_TUNE_BYPASS FIELD8(0x40) - -+/* RFCSR 19 */ -+#define RFCSR19_K FIELD8(0x03) - - /* - * RFCSR 20: -@@ -2261,11 +2428,14 @@ struct mac_iveiv_entry { - * RFCSR 21: - */ - #define RFCSR21_RX_LO2_EN FIELD8(0x08) -+#define RFCSR21_BIT1 FIELD8(0x01) -+#define RFCSR21_BIT8 FIELD8(0x80) - - /* - * RFCSR 22: - */ - #define RFCSR22_BASEBAND_LOOPBACK FIELD8(0x01) -+#define RFCSR22_FREQPLAN_D_MT7620 FIELD8(0x07) - - /* - * RFCSR 23: -@@ -2288,6 +2458,11 @@ struct mac_iveiv_entry { - #define RFCSR27_R4 FIELD8(0x40) - - /* -+ * RFCSR 28: -+ */ -+#define RFCSR28_CH11_HT40 FIELD8(0x04) -+ -+/* - * RFCSR 29: - */ - #define RFCSR29_ADC6_TEST FIELD8(0x01) -@@ -2348,6 +2523,7 @@ struct mac_iveiv_entry { - */ - #define RFCSR42_BIT1 FIELD8(0x01) - #define RFCSR42_BIT4 FIELD8(0x08) -+#define RFCSR42_TX2_EN_MT7620 FIELD8(0x40) - - /* - * RFCSR 49: -@@ -2450,6 +2626,7 @@ enum rt2800_eeprom_word { - EEPROM_TSSI_BOUND_BG5, - EEPROM_TXPOWER_A1, - EEPROM_TXPOWER_A2, -+ EEPROM_TXPOWER_INIT, - EEPROM_TSSI_BOUND_A1, - EEPROM_TSSI_BOUND_A2, - EEPROM_TSSI_BOUND_A3, -@@ -3019,6 +3196,10 @@ enum rt2800_eeprom_word { - struct rt2800_drv_data { - u8 calibration_bw20; - u8 calibration_bw40; -+ char rx_calibration_bw20; -+ char rx_calibration_bw40; -+ char tx_calibration_bw20; -+ char tx_calibration_bw40; - u8 bbp25; - u8 bbp26; - u8 txmixer_gain_24g; ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -60,6 +60,9 @@ - rt2800_regbusy_read((__dev), BBP_CSR_CFG, BBP_CSR_CFG_BUSY, (__reg)) - #define WAIT_FOR_RFCSR(__dev, __reg) \ - rt2800_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY, (__reg)) -+#define WAIT_FOR_RFCSR_MT7620(__dev, __reg) \ -+ rt2800_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY_MT7620, \ -+ (__reg)) - #define WAIT_FOR_RF(__dev, __reg) \ - rt2800_regbusy_read((__dev), RF_CSR_CFG0, RF_CSR_CFG0_BUSY, (__reg)) - #define WAIT_FOR_MCU(__dev, __reg) \ -@@ -151,19 +154,56 @@ static void rt2800_rfcsr_write(struct rt - * Wait until the RFCSR becomes available, afterwards we - * can safely write the new data into the register. - */ -- if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { -- reg = 0; -- rt2x00_set_field32(®, RF_CSR_CFG_DATA, value); -- rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); -- rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 1); -- rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); -+ switch (rt2x00dev->chip.rt) { -+ case RT6352: -+ if (WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®)) { -+ reg = 0; -+ rt2x00_set_field32(®, RF_CSR_CFG_DATA_MT7620, value); -+ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM_MT7620, -+ word); -+ rt2x00_set_field32(®, RF_CSR_CFG_WRITE_MT7620, 1); -+ rt2x00_set_field32(®, RF_CSR_CFG_BUSY_MT7620, 1); -+ -+ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); -+ } -+ break; -+ -+ default: -+ if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { -+ reg = 0; -+ rt2x00_set_field32(®, RF_CSR_CFG_DATA, value); -+ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); -+ rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 1); -+ rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); - -- rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); -+ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); -+ } -+ break; - } - - mutex_unlock(&rt2x00dev->csr_mutex); - } - -+static void rt2800_rfcsr_write_bank(struct rt2x00_dev *rt2x00dev, const u8 bank, -+ const unsigned int reg, const u8 value) -+{ -+ rt2800_rfcsr_write(rt2x00dev, (reg | (bank << 6)), value); -+} -+ -+static void rt2800_rfcsr_write_chanreg(struct rt2x00_dev *rt2x00dev, -+ const unsigned int reg, const u8 value) -+{ -+ rt2800_rfcsr_write_bank(rt2x00dev, 4, reg, value); -+ rt2800_rfcsr_write_bank(rt2x00dev, 6, reg, value); -+} -+ -+static void rt2800_rfcsr_write_dccal(struct rt2x00_dev *rt2x00dev, -+ const unsigned int reg, const u8 value) -+{ -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, reg, value); -+ rt2800_rfcsr_write_bank(rt2x00dev, 7, reg, value); -+} -+ - static void rt2800_rfcsr_read(struct rt2x00_dev *rt2x00dev, - const unsigned int word, u8 *value) - { -@@ -179,22 +219,48 @@ static void rt2800_rfcsr_read(struct rt2 - * doesn't become available in time, reg will be 0xffffffff - * which means we return 0xff to the caller. - */ -- if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { -- reg = 0; -- rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); -- rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 0); -- rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); -+ switch (rt2x00dev->chip.rt) { -+ case RT6352: -+ if (WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®)) { -+ reg = 0; -+ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM_MT7620, -+ word); -+ rt2x00_set_field32(®, RF_CSR_CFG_WRITE_MT7620, 0); -+ rt2x00_set_field32(®, RF_CSR_CFG_BUSY_MT7620, 1); - -- rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); -+ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); - -- WAIT_FOR_RFCSR(rt2x00dev, ®); -- } -+ WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®); -+ } -+ -+ *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA_MT7620); -+ break; - -- *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA); -+ default: -+ if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { -+ reg = 0; -+ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); -+ rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 0); -+ rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); -+ -+ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); -+ -+ WAIT_FOR_RFCSR(rt2x00dev, ®); -+ } -+ -+ *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA); -+ break; -+ } - - mutex_unlock(&rt2x00dev->csr_mutex); - } - -+static void rt2800_rfcsr_read_bank(struct rt2x00_dev *rt2x00dev, const u8 bank, -+ const unsigned int reg, u8 *value) -+{ -+ rt2800_rfcsr_read(rt2x00dev, (reg | (bank << 6)), value); -+} -+ - static void rt2800_rf_write(struct rt2x00_dev *rt2x00dev, - const unsigned int word, const u32 value) - { -@@ -251,6 +317,7 @@ static const unsigned int rt2800_eeprom_ - [EEPROM_TSSI_BOUND_BG5] = 0x003b, - [EEPROM_TXPOWER_A1] = 0x003c, - [EEPROM_TXPOWER_A2] = 0x0053, -+ [EEPROM_TXPOWER_INIT] = 0x0068, - [EEPROM_TSSI_BOUND_A1] = 0x006a, - [EEPROM_TSSI_BOUND_A2] = 0x006b, - [EEPROM_TSSI_BOUND_A3] = 0x006c, -@@ -527,6 +594,7 @@ void rt2800_get_txwi_rxwi_size(struct rt - break; - - case RT5592: -+ case RT6352: - *txwi_size = TXWI_DESC_SIZE_5WORDS; - *rxwi_size = RXWI_DESC_SIZE_6WORDS; - break; -@@ -2964,7 +3032,8 @@ static void rt2800_config_channel_rf53xx - rt2800_rfcsr_write(rt2x00dev, 59, - r59_nonbt_rev[idx]); - } else if (rt2x00_rt(rt2x00dev, RT5390) || -- rt2x00_rt(rt2x00dev, RT5392)) { -+ rt2x00_rt(rt2x00dev, RT5392) || -+ rt2x00_rt(rt2x00dev, RT6352)) { - static const char r59_non_bt[] = {0x8f, 0x8f, - 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, - 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86}; -@@ -3258,6 +3327,242 @@ static void rt2800_config_channel_rf55xx - rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x19 : 0x7F); - } - -+static void rt2800_config_channel_rf7620(struct rt2x00_dev *rt2x00dev, -+ struct ieee80211_conf *conf, -+ struct rf_channel *rf, -+ struct channel_info *info) -+{ -+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -+ u8 rx_agc_fc, tx_agc_fc; -+ u8 rfcsr; -+ -+ /* Frequeny plan setting */ -+ /* Rdiv setting (set 0x03 if Xtal==20) -+ * R13[1:0] -+ */ -+ rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); -+ rt2x00_set_field8(&rfcsr, RFCSR13_RDIV_MT7620, -+ rt2800_clk_is_20mhz(rt2x00dev) ? 3 : 0); -+ rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); -+ -+ /* N setting -+ * R20[7:0] in rf->rf1 -+ * R21[0] always 0 -+ */ -+ rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr); -+ rfcsr = (rf->rf1 & 0x00ff); -+ rt2800_rfcsr_write(rt2x00dev, 20, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr); -+ rt2x00_set_field8(&rfcsr, RFCSR21_BIT1, 0); -+ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); -+ -+ /* K setting (always 0) -+ * R16[3:0] (RF PLL freq selection) -+ */ -+ rt2800_rfcsr_read(rt2x00dev, 16, &rfcsr); -+ rt2x00_set_field8(&rfcsr, RFCSR16_RF_PLL_FREQ_SEL_MT7620, 0); -+ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); -+ -+ /* D setting (always 0) -+ * R22[2:0] (D=15, R22[2:0]=<111>) -+ */ -+ rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); -+ rt2x00_set_field8(&rfcsr, RFCSR22_FREQPLAN_D_MT7620, 0); -+ rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); -+ -+ /* Ksd setting -+ * Ksd: R17<7:0> in rf->rf2 -+ * R18<7:0> in rf->rf3 -+ * R19<1:0> in rf->rf4 -+ */ -+ rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); -+ rfcsr = rf->rf2; -+ rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 18, &rfcsr); -+ rfcsr = rf->rf3; -+ rt2800_rfcsr_write(rt2x00dev, 18, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 19, &rfcsr); -+ rt2x00_set_field8(&rfcsr, RFCSR19_K, rf->rf4); -+ rt2800_rfcsr_write(rt2x00dev, 19, rfcsr); -+ -+ /* Default: XO=20MHz , SDM mode */ -+ rt2800_rfcsr_read(rt2x00dev, 16, &rfcsr); -+ rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 0x80); -+ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr); -+ rt2x00_set_field8(&rfcsr, RFCSR21_BIT8, 1); -+ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); -+ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_EN_MT7620, -+ rt2x00dev->default_ant.tx_chain_num != 1); -+ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); -+ rt2x00_set_field8(&rfcsr, RFCSR2_TX2_EN_MT7620, -+ rt2x00dev->default_ant.tx_chain_num != 1); -+ rt2x00_set_field8(&rfcsr, RFCSR2_RX2_EN_MT7620, -+ rt2x00dev->default_ant.rx_chain_num != 1); -+ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 42, &rfcsr); -+ rt2x00_set_field8(&rfcsr, RFCSR42_TX2_EN_MT7620, -+ rt2x00dev->default_ant.tx_chain_num != 1); -+ rt2800_rfcsr_write(rt2x00dev, 42, rfcsr); -+ -+ /* RF for DC Cal BW */ -+ if (conf_is_ht40(conf)) { -+ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x10); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x10); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x04); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x10); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x10); -+ } else { -+ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x20); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x20); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x20); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x20); -+ } -+ -+ if (conf_is_ht40(conf)) { -+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x08); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x08); -+ } else { -+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x28); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x28); -+ } -+ -+ rt2800_rfcsr_read(rt2x00dev, 28, &rfcsr); -+ rt2x00_set_field8(&rfcsr, RFCSR28_CH11_HT40, -+ conf_is_ht40(conf) && (rf->channel == 11)); -+ rt2800_rfcsr_write(rt2x00dev, 28, rfcsr); -+ -+ if (!test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) { -+ if (conf_is_ht40(conf)) { -+ rx_agc_fc = drv_data->rx_calibration_bw40; -+ tx_agc_fc = drv_data->tx_calibration_bw40; -+ } else { -+ rx_agc_fc = drv_data->rx_calibration_bw20; -+ tx_agc_fc = drv_data->tx_calibration_bw20; -+ } -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 6, &rfcsr); -+ rfcsr &= (~0x3F); -+ rfcsr |= rx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 6, rfcsr); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 7, &rfcsr); -+ rfcsr &= (~0x3F); -+ rfcsr |= rx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 7, rfcsr); -+ rt2800_rfcsr_read_bank(rt2x00dev, 7, 6, &rfcsr); -+ rfcsr &= (~0x3F); -+ rfcsr |= rx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 6, rfcsr); -+ rt2800_rfcsr_read_bank(rt2x00dev, 7, 7, &rfcsr); -+ rfcsr &= (~0x3F); -+ rfcsr |= rx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 7, rfcsr); -+ -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 58, &rfcsr); -+ rfcsr &= (~0x3F); -+ rfcsr |= tx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 58, rfcsr); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 59, &rfcsr); -+ rfcsr &= (~0x3F); -+ rfcsr |= tx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 59, rfcsr); -+ rt2800_rfcsr_read_bank(rt2x00dev, 7, 58, &rfcsr); -+ rfcsr &= (~0x3F); -+ rfcsr |= tx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 58, rfcsr); -+ rt2800_rfcsr_read_bank(rt2x00dev, 7, 59, &rfcsr); -+ rfcsr &= (~0x3F); -+ rfcsr |= tx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 59, rfcsr); -+ } -+} -+ -+static void rt2800_config_alc(struct rt2x00_dev *rt2x00dev, -+ struct ieee80211_channel *chan, -+ int power_level) { -+ u16 eeprom, target_power, max_power; -+ u32 mac_sys_ctrl, mac_status; -+ u32 reg; -+ u8 bbp; -+ int i; -+ -+ /* hardware unit is 0.5dBm, limited to 23.5dBm */ -+ power_level *= 2; -+ if (power_level > 0x2f) -+ power_level = 0x2f; -+ -+ max_power = chan->max_power * 2; -+ if (max_power > 0x2f) -+ max_power = 0x2f; -+ -+ rt2800_register_read(rt2x00dev, TX_ALC_CFG_0, ®); -+ rt2x00_set_field32(®, TX_ALC_CFG_0_CH_INIT_0, power_level); -+ rt2x00_set_field32(®, TX_ALC_CFG_0_CH_INIT_1, power_level); -+ rt2x00_set_field32(®, TX_ALC_CFG_0_LIMIT_0, max_power); -+ rt2x00_set_field32(®, TX_ALC_CFG_0_LIMIT_1, max_power); -+ -+ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); -+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_INTERNAL_TX_ALC)) { -+ /* init base power by eeprom target power */ -+ rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_INIT, -+ &target_power); -+ rt2x00_set_field32(®, TX_ALC_CFG_0_CH_INIT_0, target_power); -+ rt2x00_set_field32(®, TX_ALC_CFG_0_CH_INIT_1, target_power); -+ } -+ rt2800_register_write(rt2x00dev, TX_ALC_CFG_0, reg); -+ -+ rt2800_register_read(rt2x00dev, TX_ALC_CFG_1, ®); -+ rt2x00_set_field32(®, TX_ALC_CFG_1_TX_TEMP_COMP, 0); -+ rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg); -+ -+ /* Save MAC SYS CTRL registers */ -+ rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &mac_sys_ctrl); -+ /* Disable Tx/Rx */ -+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0); -+ /* Check MAC Tx/Rx idle */ -+ for (i = 0; i < 10000; i++) { -+ rt2800_register_read(rt2x00dev, MAC_STATUS_CFG, -+ &mac_status); -+ if (mac_status & 0x3) -+ usleep_range(50, 200); -+ else -+ break; -+ } -+ -+ if (i == 10000) -+ rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n"); -+ -+ if (chan->center_freq > 2457) { -+ rt2800_bbp_read(rt2x00dev, 30, &bbp); -+ bbp = 0x40; -+ rt2800_bbp_write(rt2x00dev, 30, bbp); -+ rt2800_rfcsr_write(rt2x00dev, 39, 0); -+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) -+ rt2800_rfcsr_write(rt2x00dev, 42, 0xfb); -+ else -+ rt2800_rfcsr_write(rt2x00dev, 42, 0x7b); -+ } else { -+ rt2800_bbp_read(rt2x00dev, 30, &bbp); -+ bbp = 0x1f; -+ rt2800_bbp_write(rt2x00dev, 30, bbp); -+ rt2800_rfcsr_write(rt2x00dev, 39, 0x80); -+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) -+ rt2800_rfcsr_write(rt2x00dev, 42, 0xdb); -+ else -+ rt2800_rfcsr_write(rt2x00dev, 42, 0x5b); -+ } -+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl); -+} -+ - static void rt2800_bbp_write_with_rx_chain(struct rt2x00_dev *rt2x00dev, - const unsigned int word, - const u8 value) -@@ -3414,7 +3719,7 @@ static void rt2800_config_channel(struct - struct channel_info *info) - { - u32 reg; -- unsigned int tx_pin; -+ u32 tx_pin; - u8 bbp, rfcsr; - - info->default_power1 = rt2800_txpower_to_dev(rt2x00dev, rf->channel, -@@ -3468,6 +3773,9 @@ static void rt2800_config_channel(struct - case RF5592: - rt2800_config_channel_rf55xx(rt2x00dev, conf, rf, info); - break; -+ case RF7620: -+ rt2800_config_channel_rf7620(rt2x00dev, conf, rf, info); -+ break; - default: - rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); - } -@@ -3551,7 +3859,8 @@ static void rt2800_config_channel(struct - - if (rf->channel <= 14) { - if (!rt2x00_rt(rt2x00dev, RT5390) && -- !rt2x00_rt(rt2x00dev, RT5392)) { -+ !rt2x00_rt(rt2x00dev, RT5392) && -+ !rt2x00_rt(rt2x00dev, RT6352)) { - if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { - rt2800_bbp_write(rt2x00dev, 82, 0x62); - rt2800_bbp_write(rt2x00dev, 82, 0x62); -@@ -3574,7 +3883,7 @@ static void rt2800_config_channel(struct - else if (rt2x00_rt(rt2x00dev, RT3593) || - rt2x00_rt(rt2x00dev, RT3883)) - rt2800_bbp_write(rt2x00dev, 82, 0x82); -- else -+ else if (!rt2x00_rt(rt2x00dev, RT6352)) - rt2800_bbp_write(rt2x00dev, 82, 0xf2); - - if (rt2x00_rt(rt2x00dev, RT3593) || -@@ -3596,7 +3905,7 @@ static void rt2800_config_channel(struct - if (rt2x00_rt(rt2x00dev, RT3572)) - rt2800_rfcsr_write(rt2x00dev, 8, 0); - -- tx_pin = 0; -+ rt2800_register_read(rt2x00dev, TX_PIN_CFG, &tx_pin); - - switch (rt2x00dev->default_ant.tx_chain_num) { - case 3: -@@ -3645,6 +3954,7 @@ static void rt2800_config_channel(struct - - rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1); - rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1); -+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFRX_EN, 1); /* mt7620 */ - - rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); - -@@ -3720,7 +4030,7 @@ static void rt2800_config_channel(struct - usleep_range(1000, 1500); - } - -- if (rt2x00_rt(rt2x00dev, RT5592)) { -+ if (rt2x00_rt(rt2x00dev, RT5592) || rt2x00_rt(rt2x00dev, RT6352)) { - rt2800_bbp_write(rt2x00dev, 195, 141); - rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a); - -@@ -4410,6 +4720,128 @@ static void rt2800_config_txpower_rt3593 - (unsigned long) regs[i]); - } - -+static void rt2800_config_txpower_rt6352(struct rt2x00_dev *rt2x00dev, -+ struct ieee80211_channel *chan, -+ int power_level) -+{ -+ u32 reg, pwreg; -+ u16 eeprom; -+ u32 data, gdata; -+ u8 t, i; -+ enum nl80211_band band = chan->band; -+ int delta; -+ -+ /* Warn user if bw_comp is set in EEPROM */ -+ delta = rt2800_get_txpower_bw_comp(rt2x00dev, band); -+ -+ if (delta) -+ rt2x00_warn(rt2x00dev, "ignoring EEPROM HT40 power delta: %d\n", -+ delta); -+ -+ /* populate TX_PWR_CFG_0 up to TX_PWR_CFG_4 from EEPROM for HT20, limit -+ * value to 0x3f and replace 0x20 by 0x21 as this is what the vendor -+ * driver does as well, though it looks kinda wrong. -+ * Maybe some misunderstanding of what a signed 8-bit value is? Maybe -+ * the hardware has a problem handling 0x20, and as the code initially -+ * used a fixed offset between HT20 and HT40 rates they had to work- -+ * around that issue and most likely just forgot about it later on. -+ * Maybe we should use rt2800_get_txpower_bw_comp() here as well, -+ * however, the corresponding EEPROM value is not respected by the -+ * vendor driver, so maybe this is rather being taken care of the -+ * TXALC and the driver doesn't need to handle it...? -+ * Though this is all very awkward, just do as they did, as that's what -+ * board vendors expected when they populated the EEPROM... -+ */ -+ for (i = 0; i < 5; i++) { -+ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE, -+ i * 2, &eeprom); -+ -+ data = eeprom; -+ -+ t = eeprom & 0x3f; -+ if (t == 32) -+ t++; -+ -+ gdata = t; -+ -+ t = (eeprom & 0x3f00) >> 8; -+ if (t == 32) -+ t++; -+ -+ gdata |= (t << 8); -+ -+ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE, -+ (i * 2) + 1, &eeprom); -+ -+ t = eeprom & 0x3f; -+ if (t == 32) -+ t++; -+ -+ gdata |= (t << 16); -+ -+ t = (eeprom & 0x3f00) >> 8; -+ if (t == 32) -+ t++; -+ -+ gdata |= (t << 24); -+ data |= (eeprom << 16); -+ -+ if (!test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)) { -+ /* HT20 */ -+ if (data != 0xffffffff) -+ rt2800_register_write(rt2x00dev, -+ TX_PWR_CFG_0 + (i * 4), -+ data); -+ } else { -+ /* HT40 */ -+ if (gdata != 0xffffffff) -+ rt2800_register_write(rt2x00dev, -+ TX_PWR_CFG_0 + (i * 4), -+ gdata); -+ } -+ } -+ -+ /* Aparently Ralink ran out of space in the BYRATE calibration section -+ * of the EERPOM which is copied to the corresponding TX_PWR_CFG_x -+ * registers. As recent 2T chips use 8-bit instead of 4-bit values for -+ * power-offsets more space would be needed. Ralink decided to keep the -+ * EEPROM layout untouched and rather have some shared values covering -+ * multiple bitrates. -+ * Populate the registers not covered by the EEPROM in the same way the -+ * vendor driver does. -+ */ -+ -+ /* For OFDM 54MBS use value from OFDM 48MBS */ -+ pwreg = 0; -+ rt2800_register_read(rt2x00dev, TX_PWR_CFG_1, ®); -+ t = rt2x00_get_field32(reg, TX_PWR_CFG_1B_48MBS); -+ rt2x00_set_field32(&pwreg, TX_PWR_CFG_7B_54MBS, t); -+ -+ /* For MCS 7 use value from MCS 6 */ -+ rt2800_register_read(rt2x00dev, TX_PWR_CFG_2, ®); -+ t = rt2x00_get_field32(reg, TX_PWR_CFG_2B_MCS6_MCS7); -+ rt2x00_set_field32(&pwreg, TX_PWR_CFG_7B_MCS7, t); -+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_7, pwreg); -+ -+ /* For MCS 15 use value from MCS 14 */ -+ pwreg = 0; -+ rt2800_register_read(rt2x00dev, TX_PWR_CFG_3, ®); -+ t = rt2x00_get_field32(reg, TX_PWR_CFG_3B_MCS14); -+ rt2x00_set_field32(&pwreg, TX_PWR_CFG_8B_MCS15, t); -+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_8, pwreg); -+ -+ /* For STBC MCS 7 use value from STBC MCS 6 */ -+ pwreg = 0; -+ rt2800_register_read(rt2x00dev, TX_PWR_CFG_4, ®); -+ t = rt2x00_get_field32(reg, TX_PWR_CFG_4B_STBC_MCS6); -+ rt2x00_set_field32(&pwreg, TX_PWR_CFG_9B_STBC_MCS7, t); -+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_9, pwreg); -+ -+ rt2800_config_alc(rt2x00dev, chan, power_level); -+ -+ /* TODO: temperature compensation code! */ -+} -+ - /* - * We configure transmit power using MAC TX_PWR_CFG_{0,...,N} registers and - * BBP R1 register. TX_PWR_CFG_X allow to configure per rate TX power values, -@@ -4607,6 +5039,8 @@ static void rt2800_config_txpower(struct - if (rt2x00_rt(rt2x00dev, RT3593) || - rt2x00_rt(rt2x00dev, RT3883)) - rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level); -+ else if (rt2x00_rt(rt2x00dev, RT6352)) -+ rt2800_config_txpower_rt6352(rt2x00dev, chan, power_level); - else - rt2800_config_txpower_rt28xx(rt2x00dev, chan, power_level); - } -@@ -4622,6 +5056,7 @@ void rt2800_vco_calibration(struct rt2x0 - { - u32 tx_pin; - u8 rfcsr; -+ unsigned long min_sleep = 0; - - /* - * A voltage-controlled oscillator(VCO) is an electronic oscillator -@@ -4661,6 +5096,15 @@ void rt2800_vco_calibration(struct rt2x0 - rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1); - rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); -+ min_sleep = 1000; -+ break; -+ case RF7620: -+ rt2800_rfcsr_write(rt2x00dev, 5, 0x40); -+ rt2800_rfcsr_write(rt2x00dev, 4, 0x0C); -+ rt2800_rfcsr_read(rt2x00dev, 4, &rfcsr); -+ rt2x00_set_field8(&rfcsr, RFCSR4_VCOCAL_EN, 1); -+ rt2800_rfcsr_write(rt2x00dev, 4, rfcsr); -+ min_sleep = 2000; - break; - default: - WARN_ONCE(1, "Not supported RF chipet %x for VCO recalibration", -@@ -4668,7 +5112,8 @@ void rt2800_vco_calibration(struct rt2x0 - return; - } - -- usleep_range(1000, 1500); -+ if (min_sleep > 0) -+ usleep_range(min_sleep, min_sleep * 2); - - rt2800_register_read(rt2x00dev, TX_PIN_CFG, &tx_pin); - if (rt2x00dev->rf_channel <= 14) { -@@ -4700,6 +5145,42 @@ void rt2800_vco_calibration(struct rt2x0 - } - rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); - -+ if (rt2x00_rt(rt2x00dev, RT6352)) { -+ if (rt2x00dev->default_ant.tx_chain_num == 1) { -+ rt2800_bbp_write(rt2x00dev, 91, 0x07); -+ rt2800_bbp_write(rt2x00dev, 95, 0x1A); -+ rt2800_bbp_write(rt2x00dev, 195, 128); -+ rt2800_bbp_write(rt2x00dev, 196, 0xA0); -+ rt2800_bbp_write(rt2x00dev, 195, 170); -+ rt2800_bbp_write(rt2x00dev, 196, 0x12); -+ rt2800_bbp_write(rt2x00dev, 195, 171); -+ rt2800_bbp_write(rt2x00dev, 196, 0x10); -+ } else { -+ rt2800_bbp_write(rt2x00dev, 91, 0x06); -+ rt2800_bbp_write(rt2x00dev, 95, 0x9A); -+ rt2800_bbp_write(rt2x00dev, 195, 128); -+ rt2800_bbp_write(rt2x00dev, 196, 0xE0); -+ rt2800_bbp_write(rt2x00dev, 195, 170); -+ rt2800_bbp_write(rt2x00dev, 196, 0x30); -+ rt2800_bbp_write(rt2x00dev, 195, 171); -+ rt2800_bbp_write(rt2x00dev, 196, 0x30); -+ } -+ -+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -+ rt2800_bbp_write(rt2x00dev, 75, 0x60); -+ rt2800_bbp_write(rt2x00dev, 76, 0x44); -+ rt2800_bbp_write(rt2x00dev, 79, 0x1C); -+ rt2800_bbp_write(rt2x00dev, 80, 0x0C); -+ rt2800_bbp_write(rt2x00dev, 82, 0xB6); -+ } -+ -+ /* On 11A, We should delay and wait RF/BBP to be stable -+ * and the appropriate time should be 1000 micro seconds -+ * 2005/06/05 - On 11G, we also need this delay time. -+ * Otherwise it's difficult to pass the WHQL. -+ */ -+ usleep_range(1000, 1500); -+ } - } - EXPORT_SYMBOL_GPL(rt2800_vco_calibration); - -@@ -4798,7 +5279,8 @@ static u8 rt2800_get_default_vgc(struct - rt2x00_rt(rt2x00dev, RT3593) || - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392) || -- rt2x00_rt(rt2x00dev, RT5592)) -+ rt2x00_rt(rt2x00dev, RT5592) || -+ rt2x00_rt(rt2x00dev, RT6352)) - vgc = 0x1c + (2 * rt2x00dev->lna_gain); - else - vgc = 0x2e + rt2x00dev->lna_gain; -@@ -5038,7 +5520,8 @@ static int rt2800_init_registers(struct - rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21); - rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40); - } else if (rt2x00_rt(rt2x00dev, RT5390) || -- rt2x00_rt(rt2x00dev, RT5392)) { -+ rt2x00_rt(rt2x00dev, RT5392) || -+ rt2x00_rt(rt2x00dev, RT6352)) { - rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); - rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); - rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); -@@ -5048,6 +5531,24 @@ static int rt2800_init_registers(struct - rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); - } else if (rt2x00_rt(rt2x00dev, RT5350)) { - rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); -+ } else if (rt2x00_rt(rt2x00dev, RT6352)) { -+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401); -+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000); -+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); -+ rt2800_register_write(rt2x00dev, MIMO_PS_CFG, 0x00000002); -+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x00150F0F); -+ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x06060606); -+ rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0); -+ rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0); -+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C666C); -+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, 0x6C6C666C); -+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, -+ 0x3630363A); -+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_CORRECT, -+ 0x3630363A); -+ rt2800_register_read(rt2x00dev, TX_ALC_CFG_1, ®); -+ rt2x00_set_field32(®, TX_ALC_CFG_1_ROS_BUSY_EN, 0); -+ rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg); - } else { - rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); - rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); -@@ -6075,6 +6576,231 @@ static void rt2800_init_bbp_5592(struct - rt2800_bbp_write(rt2x00dev, 103, 0xc0); - } - -+static void rt2800_bbp_glrt_write(struct rt2x00_dev *rt2x00dev, -+ const u8 reg, const u8 value) -+{ -+ rt2800_bbp_write(rt2x00dev, 195, reg); -+ rt2800_bbp_write(rt2x00dev, 196, value); -+} -+ -+static void rt2800_bbp_dcoc_write(struct rt2x00_dev *rt2x00dev, -+ const u8 reg, const u8 value) -+{ -+ rt2800_bbp_write(rt2x00dev, 158, reg); -+ rt2800_bbp_write(rt2x00dev, 159, value); -+} -+ -+static void rt2800_bbp_dcoc_read(struct rt2x00_dev *rt2x00dev, -+ const u8 reg, u8 *value) -+{ -+ rt2800_bbp_write(rt2x00dev, 158, reg); -+ rt2800_bbp_read(rt2x00dev, 159, value); -+} -+ -+static void rt2800_init_bbp_6352(struct rt2x00_dev *rt2x00dev) -+{ -+ u8 bbp; -+ -+ /* Apply Maximum Likelihood Detection (MLD) for 2 stream case */ -+ rt2800_bbp_read(rt2x00dev, 105, &bbp); -+ rt2x00_set_field8(&bbp, BBP105_MLD, -+ rt2x00dev->default_ant.rx_chain_num == 2); -+ rt2800_bbp_write(rt2x00dev, 105, bbp); -+ -+ /* Avoid data loss and CRC errors */ -+ rt2800_bbp4_mac_if_ctrl(rt2x00dev); -+ -+ /* Fix I/Q swap issue */ -+ rt2800_bbp_read(rt2x00dev, 1, &bbp); -+ bbp |= 0x04; -+ rt2800_bbp_write(rt2x00dev, 1, bbp); -+ -+ /* BBP for G band */ -+ rt2800_bbp_write(rt2x00dev, 3, 0x08); -+ rt2800_bbp_write(rt2x00dev, 4, 0x00); /* rt2800_bbp4_mac_if_ctrl? */ -+ rt2800_bbp_write(rt2x00dev, 6, 0x08); -+ rt2800_bbp_write(rt2x00dev, 14, 0x09); -+ rt2800_bbp_write(rt2x00dev, 15, 0xFF); -+ rt2800_bbp_write(rt2x00dev, 16, 0x01); -+ rt2800_bbp_write(rt2x00dev, 20, 0x06); -+ rt2800_bbp_write(rt2x00dev, 21, 0x00); -+ rt2800_bbp_write(rt2x00dev, 22, 0x00); -+ rt2800_bbp_write(rt2x00dev, 27, 0x00); -+ rt2800_bbp_write(rt2x00dev, 28, 0x00); -+ rt2800_bbp_write(rt2x00dev, 30, 0x00); -+ rt2800_bbp_write(rt2x00dev, 31, 0x48); -+ rt2800_bbp_write(rt2x00dev, 47, 0x40); -+ rt2800_bbp_write(rt2x00dev, 62, 0x00); -+ rt2800_bbp_write(rt2x00dev, 63, 0x00); -+ rt2800_bbp_write(rt2x00dev, 64, 0x00); -+ rt2800_bbp_write(rt2x00dev, 65, 0x2C); -+ rt2800_bbp_write(rt2x00dev, 66, 0x1C); -+ rt2800_bbp_write(rt2x00dev, 67, 0x20); -+ rt2800_bbp_write(rt2x00dev, 68, 0xDD); -+ rt2800_bbp_write(rt2x00dev, 69, 0x10); -+ rt2800_bbp_write(rt2x00dev, 70, 0x05); -+ rt2800_bbp_write(rt2x00dev, 73, 0x18); -+ rt2800_bbp_write(rt2x00dev, 74, 0x0F); -+ rt2800_bbp_write(rt2x00dev, 75, 0x60); -+ rt2800_bbp_write(rt2x00dev, 76, 0x44); -+ rt2800_bbp_write(rt2x00dev, 77, 0x59); -+ rt2800_bbp_write(rt2x00dev, 78, 0x1E); -+ rt2800_bbp_write(rt2x00dev, 79, 0x1C); -+ rt2800_bbp_write(rt2x00dev, 80, 0x0C); -+ rt2800_bbp_write(rt2x00dev, 81, 0x3A); -+ rt2800_bbp_write(rt2x00dev, 82, 0xB6); -+ rt2800_bbp_write(rt2x00dev, 83, 0x9A); -+ rt2800_bbp_write(rt2x00dev, 84, 0x9A); -+ rt2800_bbp_write(rt2x00dev, 86, 0x38); -+ rt2800_bbp_write(rt2x00dev, 88, 0x90); -+ rt2800_bbp_write(rt2x00dev, 91, 0x04); -+ rt2800_bbp_write(rt2x00dev, 92, 0x02); -+ rt2800_bbp_write(rt2x00dev, 95, 0x9A); -+ rt2800_bbp_write(rt2x00dev, 96, 0x00); -+ rt2800_bbp_write(rt2x00dev, 103, 0xC0); -+ rt2800_bbp_write(rt2x00dev, 104, 0x92); -+ /* FIXME BBP105 owerwrite */ -+ rt2800_bbp_write(rt2x00dev, 105, 0x3C); -+ rt2800_bbp_write(rt2x00dev, 106, 0x12); -+ rt2800_bbp_write(rt2x00dev, 109, 0x00); -+ rt2800_bbp_write(rt2x00dev, 134, 0x10); -+ rt2800_bbp_write(rt2x00dev, 135, 0xA6); -+ rt2800_bbp_write(rt2x00dev, 137, 0x04); -+ rt2800_bbp_write(rt2x00dev, 142, 0x30); -+ rt2800_bbp_write(rt2x00dev, 143, 0xF7); -+ rt2800_bbp_write(rt2x00dev, 160, 0xEC); -+ rt2800_bbp_write(rt2x00dev, 161, 0xC4); -+ rt2800_bbp_write(rt2x00dev, 162, 0x77); -+ rt2800_bbp_write(rt2x00dev, 163, 0xF9); -+ rt2800_bbp_write(rt2x00dev, 164, 0x00); -+ rt2800_bbp_write(rt2x00dev, 165, 0x00); -+ rt2800_bbp_write(rt2x00dev, 186, 0x00); -+ rt2800_bbp_write(rt2x00dev, 187, 0x00); -+ rt2800_bbp_write(rt2x00dev, 188, 0x00); -+ rt2800_bbp_write(rt2x00dev, 186, 0x00); -+ rt2800_bbp_write(rt2x00dev, 187, 0x01); -+ rt2800_bbp_write(rt2x00dev, 188, 0x00); -+ rt2800_bbp_write(rt2x00dev, 189, 0x00); -+ -+ rt2800_bbp_write(rt2x00dev, 91, 0x06); -+ rt2800_bbp_write(rt2x00dev, 92, 0x04); -+ rt2800_bbp_write(rt2x00dev, 93, 0x54); -+ rt2800_bbp_write(rt2x00dev, 99, 0x50); -+ rt2800_bbp_write(rt2x00dev, 148, 0x84); -+ rt2800_bbp_write(rt2x00dev, 167, 0x80); -+ rt2800_bbp_write(rt2x00dev, 178, 0xFF); -+ rt2800_bbp_write(rt2x00dev, 106, 0x13); -+ -+ /* BBP for G band GLRT function (BBP_128 ~ BBP_221) */ -+ rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00); -+ rt2800_bbp_glrt_write(rt2x00dev, 1, 0x14); -+ rt2800_bbp_glrt_write(rt2x00dev, 2, 0x20); -+ rt2800_bbp_glrt_write(rt2x00dev, 3, 0x0A); -+ rt2800_bbp_glrt_write(rt2x00dev, 10, 0x16); -+ rt2800_bbp_glrt_write(rt2x00dev, 11, 0x06); -+ rt2800_bbp_glrt_write(rt2x00dev, 12, 0x02); -+ rt2800_bbp_glrt_write(rt2x00dev, 13, 0x07); -+ rt2800_bbp_glrt_write(rt2x00dev, 14, 0x05); -+ rt2800_bbp_glrt_write(rt2x00dev, 15, 0x09); -+ rt2800_bbp_glrt_write(rt2x00dev, 16, 0x20); -+ rt2800_bbp_glrt_write(rt2x00dev, 17, 0x08); -+ rt2800_bbp_glrt_write(rt2x00dev, 18, 0x4A); -+ rt2800_bbp_glrt_write(rt2x00dev, 19, 0x00); -+ rt2800_bbp_glrt_write(rt2x00dev, 20, 0x00); -+ rt2800_bbp_glrt_write(rt2x00dev, 128, 0xE0); -+ rt2800_bbp_glrt_write(rt2x00dev, 129, 0x1F); -+ rt2800_bbp_glrt_write(rt2x00dev, 130, 0x4F); -+ rt2800_bbp_glrt_write(rt2x00dev, 131, 0x32); -+ rt2800_bbp_glrt_write(rt2x00dev, 132, 0x08); -+ rt2800_bbp_glrt_write(rt2x00dev, 133, 0x28); -+ rt2800_bbp_glrt_write(rt2x00dev, 134, 0x19); -+ rt2800_bbp_glrt_write(rt2x00dev, 135, 0x0A); -+ rt2800_bbp_glrt_write(rt2x00dev, 138, 0x16); -+ rt2800_bbp_glrt_write(rt2x00dev, 139, 0x10); -+ rt2800_bbp_glrt_write(rt2x00dev, 140, 0x10); -+ rt2800_bbp_glrt_write(rt2x00dev, 141, 0x1A); -+ rt2800_bbp_glrt_write(rt2x00dev, 142, 0x36); -+ rt2800_bbp_glrt_write(rt2x00dev, 143, 0x2C); -+ rt2800_bbp_glrt_write(rt2x00dev, 144, 0x26); -+ rt2800_bbp_glrt_write(rt2x00dev, 145, 0x24); -+ rt2800_bbp_glrt_write(rt2x00dev, 146, 0x42); -+ rt2800_bbp_glrt_write(rt2x00dev, 147, 0x40); -+ rt2800_bbp_glrt_write(rt2x00dev, 148, 0x30); -+ rt2800_bbp_glrt_write(rt2x00dev, 149, 0x29); -+ rt2800_bbp_glrt_write(rt2x00dev, 150, 0x4C); -+ rt2800_bbp_glrt_write(rt2x00dev, 151, 0x46); -+ rt2800_bbp_glrt_write(rt2x00dev, 152, 0x3D); -+ rt2800_bbp_glrt_write(rt2x00dev, 153, 0x40); -+ rt2800_bbp_glrt_write(rt2x00dev, 154, 0x3E); -+ rt2800_bbp_glrt_write(rt2x00dev, 155, 0x38); -+ rt2800_bbp_glrt_write(rt2x00dev, 156, 0x3D); -+ rt2800_bbp_glrt_write(rt2x00dev, 157, 0x2F); -+ rt2800_bbp_glrt_write(rt2x00dev, 158, 0x3C); -+ rt2800_bbp_glrt_write(rt2x00dev, 159, 0x34); -+ rt2800_bbp_glrt_write(rt2x00dev, 160, 0x2C); -+ rt2800_bbp_glrt_write(rt2x00dev, 161, 0x2F); -+ rt2800_bbp_glrt_write(rt2x00dev, 162, 0x3C); -+ rt2800_bbp_glrt_write(rt2x00dev, 163, 0x35); -+ rt2800_bbp_glrt_write(rt2x00dev, 164, 0x2E); -+ rt2800_bbp_glrt_write(rt2x00dev, 165, 0x2F); -+ rt2800_bbp_glrt_write(rt2x00dev, 166, 0x49); -+ rt2800_bbp_glrt_write(rt2x00dev, 167, 0x41); -+ rt2800_bbp_glrt_write(rt2x00dev, 168, 0x36); -+ rt2800_bbp_glrt_write(rt2x00dev, 169, 0x39); -+ rt2800_bbp_glrt_write(rt2x00dev, 170, 0x30); -+ rt2800_bbp_glrt_write(rt2x00dev, 171, 0x30); -+ rt2800_bbp_glrt_write(rt2x00dev, 172, 0x0E); -+ rt2800_bbp_glrt_write(rt2x00dev, 173, 0x0D); -+ rt2800_bbp_glrt_write(rt2x00dev, 174, 0x28); -+ rt2800_bbp_glrt_write(rt2x00dev, 175, 0x21); -+ rt2800_bbp_glrt_write(rt2x00dev, 176, 0x1C); -+ rt2800_bbp_glrt_write(rt2x00dev, 177, 0x16); -+ rt2800_bbp_glrt_write(rt2x00dev, 178, 0x50); -+ rt2800_bbp_glrt_write(rt2x00dev, 179, 0x4A); -+ rt2800_bbp_glrt_write(rt2x00dev, 180, 0x43); -+ rt2800_bbp_glrt_write(rt2x00dev, 181, 0x50); -+ rt2800_bbp_glrt_write(rt2x00dev, 182, 0x10); -+ rt2800_bbp_glrt_write(rt2x00dev, 183, 0x10); -+ rt2800_bbp_glrt_write(rt2x00dev, 184, 0x10); -+ rt2800_bbp_glrt_write(rt2x00dev, 185, 0x10); -+ rt2800_bbp_glrt_write(rt2x00dev, 200, 0x7D); -+ rt2800_bbp_glrt_write(rt2x00dev, 201, 0x14); -+ rt2800_bbp_glrt_write(rt2x00dev, 202, 0x32); -+ rt2800_bbp_glrt_write(rt2x00dev, 203, 0x2C); -+ rt2800_bbp_glrt_write(rt2x00dev, 204, 0x36); -+ rt2800_bbp_glrt_write(rt2x00dev, 205, 0x4C); -+ rt2800_bbp_glrt_write(rt2x00dev, 206, 0x43); -+ rt2800_bbp_glrt_write(rt2x00dev, 207, 0x2C); -+ rt2800_bbp_glrt_write(rt2x00dev, 208, 0x2E); -+ rt2800_bbp_glrt_write(rt2x00dev, 209, 0x36); -+ rt2800_bbp_glrt_write(rt2x00dev, 210, 0x30); -+ rt2800_bbp_glrt_write(rt2x00dev, 211, 0x6E); -+ -+ /* BBP for G band DCOC function */ -+ rt2800_bbp_dcoc_write(rt2x00dev, 140, 0x0C); -+ rt2800_bbp_dcoc_write(rt2x00dev, 141, 0x00); -+ rt2800_bbp_dcoc_write(rt2x00dev, 142, 0x10); -+ rt2800_bbp_dcoc_write(rt2x00dev, 143, 0x10); -+ rt2800_bbp_dcoc_write(rt2x00dev, 144, 0x10); -+ rt2800_bbp_dcoc_write(rt2x00dev, 145, 0x10); -+ rt2800_bbp_dcoc_write(rt2x00dev, 146, 0x08); -+ rt2800_bbp_dcoc_write(rt2x00dev, 147, 0x40); -+ rt2800_bbp_dcoc_write(rt2x00dev, 148, 0x04); -+ rt2800_bbp_dcoc_write(rt2x00dev, 149, 0x04); -+ rt2800_bbp_dcoc_write(rt2x00dev, 150, 0x08); -+ rt2800_bbp_dcoc_write(rt2x00dev, 151, 0x08); -+ rt2800_bbp_dcoc_write(rt2x00dev, 152, 0x03); -+ rt2800_bbp_dcoc_write(rt2x00dev, 153, 0x03); -+ rt2800_bbp_dcoc_write(rt2x00dev, 154, 0x03); -+ rt2800_bbp_dcoc_write(rt2x00dev, 155, 0x02); -+ rt2800_bbp_dcoc_write(rt2x00dev, 156, 0x40); -+ rt2800_bbp_dcoc_write(rt2x00dev, 157, 0x40); -+ rt2800_bbp_dcoc_write(rt2x00dev, 158, 0x64); -+ rt2800_bbp_dcoc_write(rt2x00dev, 159, 0x64); -+ -+ rt2800_bbp4_mac_if_ctrl(rt2x00dev); -+} -+ - static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) - { - unsigned int i; -@@ -6122,6 +6848,9 @@ static void rt2800_init_bbp(struct rt2x0 - case RT5592: - rt2800_init_bbp_5592(rt2x00dev); - return; -+ case RT6352: -+ rt2800_init_bbp_6352(rt2x00dev); -+ break; - } - - for (i = 0; i < EEPROM_BBP_SIZE; i++) { -@@ -7331,6 +8060,615 @@ static void rt2800_init_rfcsr_5592(struc - rt2800_led_open_drain_enable(rt2x00dev); - } - -+static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, -+ bool set_bw, bool is_ht40) -+{ -+ u8 bbp_val; -+ -+ rt2800_bbp_read(rt2x00dev, 21, &bbp_val); -+ bbp_val |= 0x1; -+ rt2800_bbp_write(rt2x00dev, 21, bbp_val); -+ usleep_range(100, 200); -+ -+ if (set_bw) { -+ rt2800_bbp_read(rt2x00dev, 4, &bbp_val); -+ rt2x00_set_field8(&bbp_val, BBP4_BANDWIDTH, 2 * is_ht40); -+ rt2800_bbp_write(rt2x00dev, 4, bbp_val); -+ usleep_range(100, 200); -+ } -+ -+ rt2800_bbp_read(rt2x00dev, 21, &bbp_val); -+ bbp_val &= (~0x1); -+ rt2800_bbp_write(rt2x00dev, 21, bbp_val); -+ usleep_range(100, 200); -+} -+ -+static int rt2800_rf_lp_config(struct rt2x00_dev *rt2x00dev, bool btxcal) -+{ -+ u8 rf_val; -+ -+ if (btxcal) -+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x04); -+ else -+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x02); -+ -+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x06); -+ -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 17, &rf_val); -+ rf_val |= 0x80; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, rf_val); -+ -+ if (btxcal) { -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, 0xC1); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, 0x20); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, 0x02); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 3, &rf_val); -+ rf_val &= (~0x3F); -+ rf_val |= 0x3F; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 3, rf_val); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 4, &rf_val); -+ rf_val &= (~0x3F); -+ rf_val |= 0x3F; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, rf_val); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 5, 0x31); -+ } else { -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, 0xF1); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, 0x18); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, 0x02); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 3, &rf_val); -+ rf_val &= (~0x3F); -+ rf_val |= 0x34; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 3, rf_val); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 4, &rf_val); -+ rf_val &= (~0x3F); -+ rf_val |= 0x34; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, rf_val); -+ } -+ -+ return 0; -+} -+ -+static char rt2800_lp_tx_filter_bw_cal(struct rt2x00_dev *rt2x00dev) -+{ -+ unsigned int cnt; -+ u8 bbp_val; -+ char cal_val; -+ -+ rt2800_bbp_dcoc_write(rt2x00dev, 0, 0x82); -+ -+ cnt = 0; -+ do { -+ usleep_range(500, 2000); -+ rt2800_bbp_read(rt2x00dev, 159, &bbp_val); -+ if (bbp_val == 0x02 || cnt == 20) -+ break; -+ -+ cnt++; -+ } while (cnt < 20); -+ -+ rt2800_bbp_dcoc_read(rt2x00dev, 0x39, &bbp_val); -+ cal_val = bbp_val & 0x7F; -+ if (cal_val >= 0x40) -+ cal_val -= 128; -+ -+ return cal_val; -+} -+ -+static void rt2800_bw_filter_calibration(struct rt2x00_dev *rt2x00dev, -+ bool btxcal) -+{ -+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -+ u8 tx_agc_fc = 0, rx_agc_fc = 0, cmm_agc_fc; -+ u8 filter_target; -+ u8 tx_filter_target_20m = 0x09, tx_filter_target_40m = 0x02; -+ u8 rx_filter_target_20m = 0x27, rx_filter_target_40m = 0x31; -+ int loop = 0, is_ht40, cnt; -+ u8 bbp_val, rf_val; -+ char cal_r32_init, cal_r32_val, cal_diff; -+ u8 saverfb5r00, saverfb5r01, saverfb5r03, saverfb5r04, saverfb5r05; -+ u8 saverfb5r06, saverfb5r07; -+ u8 saverfb5r08, saverfb5r17, saverfb5r18, saverfb5r19, saverfb5r20; -+ u8 saverfb5r37, saverfb5r38, saverfb5r39, saverfb5r40, saverfb5r41; -+ u8 saverfb5r42, saverfb5r43, saverfb5r44, saverfb5r45, saverfb5r46; -+ u8 saverfb5r58, saverfb5r59; -+ u8 savebbp159r0, savebbp159r2, savebbpr23; -+ u32 MAC_RF_CONTROL0, MAC_RF_BYPASS0; -+ -+ /* Save MAC registers */ -+ rt2800_register_read(rt2x00dev, RF_CONTROL0, &MAC_RF_CONTROL0); -+ rt2800_register_read(rt2x00dev, RF_BYPASS0, &MAC_RF_BYPASS0); -+ -+ /* save BBP registers */ -+ rt2800_bbp_read(rt2x00dev, 23, &savebbpr23); -+ -+ rt2800_bbp_dcoc_read(rt2x00dev, 0, &savebbp159r0); -+ rt2800_bbp_dcoc_read(rt2x00dev, 2, &savebbp159r2); -+ -+ /* Save RF registers */ -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 0, &saverfb5r00); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 1, &saverfb5r01); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 3, &saverfb5r03); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 4, &saverfb5r04); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 5, &saverfb5r05); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 6, &saverfb5r06); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 7, &saverfb5r07); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 8, &saverfb5r08); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 17, &saverfb5r17); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 18, &saverfb5r18); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 19, &saverfb5r19); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 20, &saverfb5r20); -+ -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 37, &saverfb5r37); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 38, &saverfb5r38); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 39, &saverfb5r39); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 40, &saverfb5r40); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 41, &saverfb5r41); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 42, &saverfb5r42); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 43, &saverfb5r43); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 44, &saverfb5r44); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 45, &saverfb5r45); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 46, &saverfb5r46); -+ -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 58, &saverfb5r58); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 59, &saverfb5r59); -+ -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 0, &rf_val); -+ rf_val |= 0x3; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 0, rf_val); -+ -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 1, &rf_val); -+ rf_val |= 0x1; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 1, rf_val); -+ -+ cnt = 0; -+ do { -+ usleep_range(500, 2000); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 1, &rf_val); -+ if (((rf_val & 0x1) == 0x00) || (cnt == 40)) -+ break; -+ cnt++; -+ } while (cnt < 40); -+ -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 0, &rf_val); -+ rf_val &= (~0x3); -+ rf_val |= 0x1; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 0, rf_val); -+ -+ /* I-3 */ -+ rt2800_bbp_read(rt2x00dev, 23, &bbp_val); -+ bbp_val &= (~0x1F); -+ bbp_val |= 0x10; -+ rt2800_bbp_write(rt2x00dev, 23, bbp_val); -+ -+ do { -+ /* I-4,5,6,7,8,9 */ -+ if (loop == 0) { -+ is_ht40 = false; -+ -+ if (btxcal) -+ filter_target = tx_filter_target_20m; -+ else -+ filter_target = rx_filter_target_20m; -+ } else { -+ is_ht40 = true; -+ -+ if (btxcal) -+ filter_target = tx_filter_target_40m; -+ else -+ filter_target = rx_filter_target_40m; -+ } -+ -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 8, &rf_val); -+ rf_val &= (~0x04); -+ if (loop == 1) -+ rf_val |= 0x4; -+ -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 8, rf_val); -+ -+ rt2800_bbp_core_soft_reset(rt2x00dev, true, is_ht40); -+ -+ rt2800_rf_lp_config(rt2x00dev, btxcal); -+ if (btxcal) { -+ tx_agc_fc = 0; -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 58, &rf_val); -+ rf_val &= (~0x7F); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 58, rf_val); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 59, &rf_val); -+ rf_val &= (~0x7F); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 59, rf_val); -+ } else { -+ rx_agc_fc = 0; -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 6, &rf_val); -+ rf_val &= (~0x7F); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 6, rf_val); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 7, &rf_val); -+ rf_val &= (~0x7F); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 7, rf_val); -+ } -+ -+ usleep_range(1000, 2000); -+ -+ rt2800_bbp_dcoc_read(rt2x00dev, 2, &bbp_val); -+ bbp_val &= (~0x6); -+ rt2800_bbp_dcoc_write(rt2x00dev, 2, bbp_val); -+ -+ rt2800_bbp_core_soft_reset(rt2x00dev, false, is_ht40); -+ -+ cal_r32_init = rt2800_lp_tx_filter_bw_cal(rt2x00dev); -+ -+ rt2800_bbp_dcoc_read(rt2x00dev, 2, &bbp_val); -+ bbp_val |= 0x6; -+ rt2800_bbp_dcoc_write(rt2x00dev, 2, bbp_val); -+do_cal: -+ if (btxcal) { -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 58, &rf_val); -+ rf_val &= (~0x7F); -+ rf_val |= tx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 58, rf_val); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 59, &rf_val); -+ rf_val &= (~0x7F); -+ rf_val |= tx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 59, rf_val); -+ } else { -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 6, &rf_val); -+ rf_val &= (~0x7F); -+ rf_val |= rx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 6, rf_val); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 7, &rf_val); -+ rf_val &= (~0x7F); -+ rf_val |= rx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 7, rf_val); -+ } -+ -+ usleep_range(500, 1000); -+ -+ rt2800_bbp_core_soft_reset(rt2x00dev, false, is_ht40); -+ -+ cal_r32_val = rt2800_lp_tx_filter_bw_cal(rt2x00dev); -+ -+ cal_diff = cal_r32_init - cal_r32_val; -+ -+ if (btxcal) -+ cmm_agc_fc = tx_agc_fc; -+ else -+ cmm_agc_fc = rx_agc_fc; -+ -+ if (((cal_diff > filter_target) && (cmm_agc_fc == 0)) || -+ ((cal_diff < filter_target) && (cmm_agc_fc == 0x3f))) { -+ if (btxcal) -+ tx_agc_fc = 0; -+ else -+ rx_agc_fc = 0; -+ } else if ((cal_diff <= filter_target) && (cmm_agc_fc < 0x3f)) { -+ if (btxcal) -+ tx_agc_fc++; -+ else -+ rx_agc_fc++; -+ goto do_cal; -+ } -+ -+ if (btxcal) { -+ if (loop == 0) -+ drv_data->tx_calibration_bw20 = tx_agc_fc; -+ else -+ drv_data->tx_calibration_bw40 = tx_agc_fc; -+ } else { -+ if (loop == 0) -+ drv_data->rx_calibration_bw20 = rx_agc_fc; -+ else -+ drv_data->rx_calibration_bw40 = rx_agc_fc; -+ } -+ -+ loop++; -+ } while (loop <= 1); -+ -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 0, saverfb5r00); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 1, saverfb5r01); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 3, saverfb5r03); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, saverfb5r04); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 5, saverfb5r05); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 6, saverfb5r06); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 7, saverfb5r07); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 8, saverfb5r08); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, saverfb5r17); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, saverfb5r18); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, saverfb5r19); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, saverfb5r20); -+ -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 37, saverfb5r37); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 38, saverfb5r38); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 39, saverfb5r39); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 40, saverfb5r40); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 41, saverfb5r41); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 42, saverfb5r42); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 43, saverfb5r43); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 44, saverfb5r44); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 45, saverfb5r45); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 46, saverfb5r46); -+ -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 58, saverfb5r58); -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 59, saverfb5r59); -+ -+ rt2800_bbp_write(rt2x00dev, 23, savebbpr23); -+ -+ rt2800_bbp_dcoc_write(rt2x00dev, 0, savebbp159r0); -+ rt2800_bbp_dcoc_write(rt2x00dev, 2, savebbp159r2); -+ -+ rt2800_bbp_read(rt2x00dev, 4, &bbp_val); -+ rt2x00_set_field8(&bbp_val, BBP4_BANDWIDTH, -+ 2 * test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)); -+ rt2800_bbp_write(rt2x00dev, 4, bbp_val); -+ -+ rt2800_register_write(rt2x00dev, RF_CONTROL0, MAC_RF_CONTROL0); -+ rt2800_register_write(rt2x00dev, RF_BYPASS0, MAC_RF_BYPASS0); -+} -+ -+static void rt2800_init_rfcsr_6352(struct rt2x00_dev *rt2x00dev) -+{ -+ /* Initialize RF central register to default value */ -+ rt2800_rfcsr_write(rt2x00dev, 0, 0x02); -+ rt2800_rfcsr_write(rt2x00dev, 1, 0x03); -+ rt2800_rfcsr_write(rt2x00dev, 2, 0x33); -+ rt2800_rfcsr_write(rt2x00dev, 3, 0xFF); -+ rt2800_rfcsr_write(rt2x00dev, 4, 0x0C); -+ rt2800_rfcsr_write(rt2x00dev, 5, 0x40); -+ rt2800_rfcsr_write(rt2x00dev, 6, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 7, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 8, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 9, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 10, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 11, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 12, rt2x00dev->freq_offset); -+ rt2800_rfcsr_write(rt2x00dev, 13, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 14, 0x40); -+ rt2800_rfcsr_write(rt2x00dev, 15, 0x22); -+ rt2800_rfcsr_write(rt2x00dev, 16, 0x4C); -+ rt2800_rfcsr_write(rt2x00dev, 17, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 18, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 19, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 20, 0xA0); -+ rt2800_rfcsr_write(rt2x00dev, 21, 0x12); -+ rt2800_rfcsr_write(rt2x00dev, 22, 0x07); -+ rt2800_rfcsr_write(rt2x00dev, 23, 0x13); -+ rt2800_rfcsr_write(rt2x00dev, 24, 0xFE); -+ rt2800_rfcsr_write(rt2x00dev, 25, 0x24); -+ rt2800_rfcsr_write(rt2x00dev, 26, 0x7A); -+ rt2800_rfcsr_write(rt2x00dev, 27, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 28, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 29, 0x05); -+ rt2800_rfcsr_write(rt2x00dev, 30, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 31, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 32, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 33, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 34, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 35, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 36, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 37, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 38, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 39, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 40, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 41, 0xD0); -+ rt2800_rfcsr_write(rt2x00dev, 42, 0x5B); -+ rt2800_rfcsr_write(rt2x00dev, 43, 0x00); -+ -+ rt2800_rfcsr_write(rt2x00dev, 11, 0x21); -+ if (rt2800_clk_is_20mhz(rt2x00dev)) -+ rt2800_rfcsr_write(rt2x00dev, 13, 0x03); -+ else -+ rt2800_rfcsr_write(rt2x00dev, 13, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 14, 0x7C); -+ rt2800_rfcsr_write(rt2x00dev, 16, 0x80); -+ rt2800_rfcsr_write(rt2x00dev, 17, 0x99); -+ rt2800_rfcsr_write(rt2x00dev, 18, 0x99); -+ rt2800_rfcsr_write(rt2x00dev, 19, 0x09); -+ rt2800_rfcsr_write(rt2x00dev, 20, 0x50); -+ rt2800_rfcsr_write(rt2x00dev, 21, 0xB0); -+ rt2800_rfcsr_write(rt2x00dev, 22, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 23, 0x06); -+ rt2800_rfcsr_write(rt2x00dev, 24, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 25, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 26, 0x5D); -+ rt2800_rfcsr_write(rt2x00dev, 27, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 28, 0x61); -+ rt2800_rfcsr_write(rt2x00dev, 29, 0xB5); -+ rt2800_rfcsr_write(rt2x00dev, 43, 0x02); -+ -+ rt2800_rfcsr_write(rt2x00dev, 28, 0x62); -+ rt2800_rfcsr_write(rt2x00dev, 29, 0xAD); -+ rt2800_rfcsr_write(rt2x00dev, 39, 0x80); -+ -+ /* Initialize RF channel register to default value */ -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 1, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 2, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 3, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 4, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 5, 0x08); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 6, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 7, 0x51); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x53); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x16); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x61); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 12, 0x22); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 13, 0x3D); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 15, 0x13); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 16, 0x22); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x27); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x02); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x01); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x52); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 22, 0x80); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 23, 0xB3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 24, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 25, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 26, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 27, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x5C); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0x6B); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 30, 0x6B); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 31, 0x31); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x5D); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 33, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xE6); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 35, 0x55); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 37, 0xBB); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 39, 0xB3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 40, 0x03); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 41, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 42, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xB3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xD3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x07); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x68); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xEF); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1C); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x07); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xA8); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0x85); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x10); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x07); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6A); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0x85); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x10); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 62, 0x1C); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 63, 0x00); -+ -+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5); -+ -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x33); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x0E); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA4); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x02); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x12); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x1C); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0xEB); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x7D); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xD6); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x08); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB4); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x69); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFF); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x20); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09); -+ -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16); -+ -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); -+ -+ /* Initialize RF channel register for DRQFN */ -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7); -+ -+ /* Initialize RF DC calibration register to default value */ -+ rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 1, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 2, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x10); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x10); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x04); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 9, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 10, 0x07); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 11, 0x01); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 12, 0x07); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 13, 0x07); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 14, 0x07); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 15, 0x20); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 16, 0x22); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 18, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 19, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 20, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 21, 0xF1); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 22, 0x11); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 23, 0x02); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 24, 0x41); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 25, 0x20); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 26, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 27, 0xD7); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 28, 0xA2); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 29, 0x20); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 30, 0x49); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 31, 0x20); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 32, 0x04); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 33, 0xF1); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 34, 0xA1); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 35, 0x01); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 41, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 42, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 43, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 44, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 45, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 46, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 47, 0x3E); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 48, 0x3D); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 49, 0x3E); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 50, 0x3D); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 51, 0x3E); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 52, 0x3D); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 53, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 54, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 55, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 56, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 57, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x10); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x10); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 60, 0x0A); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 61, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00); -+ -+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x08); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x04); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x20); -+ -+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); -+ -+ rt2800_bw_filter_calibration(rt2x00dev, true); -+ rt2800_bw_filter_calibration(rt2x00dev, false); -+} -+ - static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) - { - if (rt2800_is_305x_soc(rt2x00dev)) { -@@ -7374,6 +8712,9 @@ static void rt2800_init_rfcsr(struct rt2 - case RT5592: - rt2800_init_rfcsr_5592(rt2x00dev); - break; -+ case RT6352: -+ rt2800_init_rfcsr_6352(rt2x00dev); -+ break; - } - } - -@@ -7745,7 +9086,8 @@ static int rt2800_init_eeprom(struct rt2 - */ - if (rt2x00_rt(rt2x00dev, RT3290) || - rt2x00_rt(rt2x00dev, RT5390) || -- rt2x00_rt(rt2x00dev, RT5392)) -+ rt2x00_rt(rt2x00dev, RT5392) || -+ rt2x00_rt(rt2x00dev, RT6352)) - rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); - else if (rt2x00_rt(rt2x00dev, RT3352)) - rf = RF3322; -@@ -7780,6 +9122,7 @@ static int rt2800_init_eeprom(struct rt2 - case RF5390: - case RF5392: - case RF5592: -+ case RF7620: - break; - default: - rt2x00_err(rt2x00dev, "Invalid RF chipset 0x%04x detected\n", -@@ -8258,6 +9601,23 @@ static const struct rf_channel rf_vals_5 - {196, 83, 0, 12, 1}, - }; - -+static const struct rf_channel rf_vals_7620[] = { -+ {1, 0x50, 0x99, 0x99, 1}, -+ {2, 0x50, 0x44, 0x44, 2}, -+ {3, 0x50, 0xEE, 0xEE, 2}, -+ {4, 0x50, 0x99, 0x99, 3}, -+ {5, 0x51, 0x44, 0x44, 0}, -+ {6, 0x51, 0xEE, 0xEE, 0}, -+ {7, 0x51, 0x99, 0x99, 1}, -+ {8, 0x51, 0x44, 0x44, 2}, -+ {9, 0x51, 0xEE, 0xEE, 2}, -+ {10, 0x51, 0x99, 0x99, 3}, -+ {11, 0x52, 0x44, 0x44, 0}, -+ {12, 0x52, 0xEE, 0xEE, 0}, -+ {13, 0x52, 0x99, 0x99, 1}, -+ {14, 0x52, 0x33, 0x33, 3}, -+}; -+ - static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) - { - struct hw_mode_spec *spec = &rt2x00dev->spec; -@@ -8361,6 +9721,11 @@ static int rt2800_probe_hw_mode(struct r - spec->channels = rf_vals_3x; - break; - -+ case RF7620: -+ spec->num_channels = ARRAY_SIZE(rf_vals_7620); -+ spec->channels = rf_vals_7620; -+ break; -+ - case RF3052: - case RF3053: - spec->num_channels = ARRAY_SIZE(rf_vals_3x); -@@ -8498,6 +9863,7 @@ static int rt2800_probe_hw_mode(struct r - case RF5390: - case RF5392: - case RF5592: -+ case RF7620: - __set_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags); - break; - } -@@ -8543,6 +9909,9 @@ static int rt2800_probe_rt(struct rt2x00 - return -ENODEV; - } - -+ if (rt == RT5390 && rt2x00_is_soc(rt2x00dev)) -+ rt = RT6352; -+ - rt2x00_set_rt(rt2x00dev, rt, rev); - - return 0; ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -175,6 +175,7 @@ struct rt2x00_chip { - #define RT5390 0x5390 /* 2.4GHz */ - #define RT5392 0x5392 /* 2.4GHz */ - #define RT5592 0x5592 -+#define RT6352 0x6352 /* WSOC 2.4GHz */ - - u16 rf; - u16 rev;