History

Merge remote-tracking branch 'wireless-next/master' into HEAD

Johannes Berg committed 13 years ago

Commit 448cd552 parents 3b4797b 9ebea38195 files · +12015 −3487Browse files

Unified · Split

195 files
  1. Documentation/nfc/nfc-hci.txt +103 −26
  2. Documentation/nfc/nfc-pn544.txt +1 −83
  3. MAINTAINERS +8 −0
  4. arch/mips/bcm47xx/serial.c +1 −1
  5. drivers/bcma/Kconfig +1 −2
  6. drivers/bcma/bcma_private.h +2 −0
  7. drivers/bcma/driver_chipcommon.c +1 −1
  8. drivers/bcma/driver_chipcommon_sflash.c +1 −1
  9. drivers/bcma/driver_mips.c +112 −45
  10. drivers/bcma/driver_pci_host.c +38 −24
  11. drivers/bcma/main.c +2 −2
  12. drivers/bluetooth/ath3k.c +10 −0
  13. drivers/bluetooth/btusb.c +5 −0
  14. drivers/net/wireless/ath/Kconfig +1 −0
  15. drivers/net/wireless/ath/Makefile +1 −0
  16. drivers/net/wireless/ath/ath9k/Kconfig +3 −2
  17. drivers/net/wireless/ath/ath9k/ahb.c +6 −16
  18. drivers/net/wireless/ath/ath9k/ani.c +6 −27
  19. drivers/net/wireless/ath/ath9k/ani.h +0 −8
  20. drivers/net/wireless/ath/ath9k/ar5008_initvals.h +4 −4
  21. drivers/net/wireless/ath/ath9k/ar5008_phy.c +15 −35
  22. drivers/net/wireless/ath/ath9k/ar9001_initvals.h +2 −2
  23. drivers/net/wireless/ath/ath9k/ar9002_hw.c +16 −7
  24. drivers/net/wireless/ath/ath9k/ar9002_phy.c +64 −2
  25. drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +180 −0
  26. drivers/net/wireless/ath/ath9k/ar9003_calib.c +78 −67
  27. drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +99 −29
  28. drivers/net/wireless/ath/ath9k/ar9003_hw.c +51 −20
  29. drivers/net/wireless/ath/ath9k/ar9003_phy.c +88 −34
  30. drivers/net/wireless/ath/ath9k/ar9003_phy.h +1 −1
  31. drivers/net/wireless/ath/ath9k/ar9340_initvals.h +100 −0
  32. drivers/net/wireless/ath/ath9k/ar9485_initvals.h +146 −0
  33. drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h +66 −66
  34. drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h +76 −0
  35. drivers/net/wireless/ath/ath9k/ath9k.h +154 −11
  36. drivers/net/wireless/ath/ath9k/beacon.c +2 −2
  37. drivers/net/wireless/ath/ath9k/debug.c +115 −1
  38. drivers/net/wireless/ath/ath9k/debug.h +5 −2
  39. drivers/net/wireless/ath/ath9k/htc_hst.c +2 −0
  40. drivers/net/wireless/ath/ath9k/hw-ops.h +0 −16
  41. drivers/net/wireless/ath/ath9k/hw.c +12 −36
  42. drivers/net/wireless/ath/ath9k/hw.h +45 −14
  43. drivers/net/wireless/ath/ath9k/init.c +37 −70
  44. drivers/net/wireless/ath/ath9k/mac.h +2 −1
  45. drivers/net/wireless/ath/ath9k/main.c +126 −33
  46. drivers/net/wireless/ath/ath9k/mci.c +1 −6
  47. drivers/net/wireless/ath/ath9k/pci.c +8 −31
  48. drivers/net/wireless/ath/ath9k/recv.c +122 −49
  49. drivers/net/wireless/ath/ath9k/reg.h +4 −3
  50. drivers/net/wireless/ath/ath9k/xmit.c +45 −100
  51. drivers/net/wireless/ath/carl9170/carl9170.h +7 −12
  52. drivers/net/wireless/ath/carl9170/fw.c +30 −13
  53. drivers/net/wireless/ath/carl9170/fwcmd.h +8 −0
  54. drivers/net/wireless/ath/carl9170/hw.h +1 −1
  55. drivers/net/wireless/ath/carl9170/main.c +83 −20
  56. drivers/net/wireless/ath/carl9170/tx.c +80 −53
  57. drivers/net/wireless/ath/carl9170/version.h +3 −3
  58. drivers/net/wireless/ath/wil6210/Kconfig +29 −0
  59. drivers/net/wireless/ath/wil6210/Makefile +13 −0
  60. drivers/net/wireless/ath/wil6210/cfg80211.c +573 −0
  61. drivers/net/wireless/ath/wil6210/dbg_hexdump.h +30 −0
  62. drivers/net/wireless/ath/wil6210/debugfs.c +603 −0
  63. drivers/net/wireless/ath/wil6210/interrupt.c +471 −0
  64. drivers/net/wireless/ath/wil6210/main.c +407 −0
  65. drivers/net/wireless/ath/wil6210/netdev.c +157 −0
  66. drivers/net/wireless/ath/wil6210/pcie_bus.c +223 −0
  67. drivers/net/wireless/ath/wil6210/txrx.c +871 −0
  68. drivers/net/wireless/ath/wil6210/txrx.h +362 −0
  69. drivers/net/wireless/ath/wil6210/wil6210.h +363 −0
  70. drivers/net/wireless/ath/wil6210/wmi.c +975 −0
  71. drivers/net/wireless/ath/wil6210/wmi.h +1116 −0
  72. drivers/net/wireless/b43/b43.h +5 −0
  73. drivers/net/wireless/b43/main.c +41 −13
  74. drivers/net/wireless/b43/main.h +2 −3
  75. drivers/net/wireless/b43/tables_nphy.c +8 −22
  76. drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +0 −2
  77. drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +0 −2
  78. drivers/net/wireless/brcm80211/brcmfmac/dhd.h +5 −34
  79. drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +3 −16
  80. drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +12 −36
  81. drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +0 −2
  82. drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +20 −15
  83. drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +55 −35
  84. drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +5 −19
  85. drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +0 −2
  86. drivers/net/wireless/brcm80211/brcmfmac/usb.c +19 −8
  87. drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +16 −83
  88. drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +2 −5
  89. drivers/net/wireless/brcm80211/brcmsmac/debug.h +1 −0
  90. drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +7 −3
  91. drivers/net/wireless/brcm80211/brcmsmac/main.c +4 −5
  92. drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c +2 −2
  93. drivers/net/wireless/brcm80211/brcmsmac/scb.h +0 −1
  94. drivers/net/wireless/iwlegacy/3945-mac.c +6 −2
  95. drivers/net/wireless/iwlegacy/4965-mac.c +4 −2
  96. drivers/net/wireless/iwlegacy/common.c +50 −21
  97. drivers/net/wireless/iwlegacy/common.h +1 −0
  98. drivers/net/wireless/iwlwifi/dvm/commands.h +4 −4
  99. drivers/net/wireless/iwlwifi/dvm/debugfs.c +2 −2
  100. drivers/net/wireless/iwlwifi/dvm/led.c +1 −1
  101. drivers/net/wireless/iwlwifi/dvm/mac80211.c +7 −9
  102. drivers/net/wireless/iwlwifi/dvm/main.c +11 −10
  103. drivers/net/wireless/iwlwifi/dvm/tt.c +2 −2
  104. drivers/net/wireless/iwlwifi/dvm/tx.c +45 −30
  105. drivers/net/wireless/iwlwifi/dvm/ucode.c +1 −95
  106. drivers/net/wireless/iwlwifi/iwl-csr.h +2 −2
  107. drivers/net/wireless/iwlwifi/iwl-fh.h +4 −0
  108. drivers/net/wireless/iwlwifi/iwl-io.c +22 −146
  109. drivers/net/wireless/iwlwifi/iwl-io.h +2 −19
  110. drivers/net/wireless/iwlwifi/iwl-test.c +29 −24
  111. drivers/net/wireless/iwlwifi/iwl-trans.h +91 −8
  112. drivers/net/wireless/iwlwifi/pcie/internal.h +4 −4
  113. drivers/net/wireless/iwlwifi/pcie/rx.c +11 −4
  114. drivers/net/wireless/iwlwifi/pcie/trans.c +248 −61
  115. drivers/net/wireless/iwlwifi/pcie/tx.c +48 −31
  116. drivers/net/wireless/mac80211_hwsim.c +39 −18
  117. drivers/net/wireless/mwifiex/11n.c +3 −1
  118. drivers/net/wireless/mwifiex/11n_aggr.c +4 −2
  119. drivers/net/wireless/mwifiex/cfg80211.c +5 −16
  120. drivers/net/wireless/mwifiex/decl.h +18 −0
  121. drivers/net/wireless/mwifiex/fw.h +8 −6
  122. drivers/net/wireless/mwifiex/init.c +6 −0
  123. drivers/net/wireless/mwifiex/ioctl.h +2 −1
  124. drivers/net/wireless/mwifiex/join.c +25 −5
  125. drivers/net/wireless/mwifiex/main.h +6 −0
  126. drivers/net/wireless/mwifiex/pcie.c +452 −204
  127. drivers/net/wireless/mwifiex/pcie.h +29 −4
  128. drivers/net/wireless/mwifiex/sta_cmd.c +5 −5
  129. drivers/net/wireless/mwifiex/sta_ioctl.c +24 −11
  130. drivers/net/wireless/mwifiex/txrx.c +4 −2
  131. drivers/net/wireless/mwifiex/uap_cmd.c +44 −0
  132. drivers/net/wireless/mwifiex/usb.c +3 −27
  133. drivers/net/wireless/mwifiex/util.h +4 −4
  134. drivers/net/wireless/mwifiex/wmm.c +6 −2
  135. drivers/net/wireless/mwl8k.c +124 −27
  136. drivers/net/wireless/p54/p54pci.c +5 −2
  137. drivers/net/wireless/p54/p54usb.c +4 −0
  138. drivers/net/wireless/prism54/isl_ioctl.c +1 −0
  139. drivers/net/wireless/ray_cs.c +14 −5
  140. drivers/net/wireless/rt2x00/rt2800lib.c +432 −378
  141. drivers/net/wireless/rt2x00/rt2800lib.h +4 −4
  142. drivers/net/wireless/rt2x00/rt2800pci.c +24 −11
  143. drivers/net/wireless/rt2x00/rt2800usb.c +8 −4
  144. drivers/net/wireless/rt2x00/rt2x00.h +20 −0
  145. drivers/net/wireless/rt2x00/rt2x00dev.c +100 −1
  146. drivers/net/wireless/rt2x00/rt2x00queue.c +47 −0
  147. drivers/net/wireless/rtlwifi/Kconfig +2 −2
  148. drivers/net/wireless/rtlwifi/pci.c +6 −0
  149. drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +1 −1
  150. drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +11 −0
  151. drivers/net/wireless/rtlwifi/rtl8192de/trx.c +11 −1
  152. drivers/net/wireless/rtlwifi/rtl8192se/trx.c +13 −2
  153. drivers/net/wireless/rtlwifi/rtl8723ae/phy.c +1 −1
  154. drivers/net/wireless/rtlwifi/rtl8723ae/trx.c +11 −1
  155. drivers/net/wireless/rtlwifi/usb.c +4 −4
  156. drivers/nfc/Kconfig +2 −13
  157. drivers/nfc/Makefile +1 −1
  158. drivers/nfc/nfcwilink.c +3 −7
  159. drivers/nfc/pn533.c +836 −757
  160. drivers/nfc/pn544/Kconfig +23 −0
  161. drivers/nfc/pn544/Makefile +3 −2
  162. drivers/nfc/pn544/i2c.c +7 −37
  163. drivers/nfc/pn544/pn544.c +42 −23
  164. drivers/ssb/Kconfig +6 −2
  165. drivers/ssb/Makefile +1 −0
  166. drivers/ssb/driver_chipcommon_sflash.c +140 −0
  167. drivers/ssb/driver_mipscore.c +2 −1
  168. drivers/ssb/ssb_private.h +11 −0
  169. include/linux/bcma/bcma_driver_mips.h +2 −2
  170. include/linux/bcma/bcma_driver_pci.h +2 −0
  171. include/net/nfc/hci.h +20 −2
  172. include/net/nfc/nci_core.h +1 −0
  173. include/net/nfc/nfc.h +8 −0
  174. include/uapi/linux/nfc.h +24 −13
  175. net/bluetooth/hci_core.c +0 −8
  176. net/bluetooth/hci_event.c +1 −1
  177. net/bluetooth/hidp/core.c +1 −1
  178. net/bluetooth/l2cap_core.c +11 −0
  179. net/bluetooth/sco.c +1 −1
  180. net/mac80211/cfg.c +11 −1
  181. net/mac80211/ieee80211_i.h +2 −4
  182. net/mac80211/mesh_hwmp.c +4 −1
  183. net/mac80211/offchannel.c +7 −12
  184. net/mac80211/scan.c +5 −10
  185. net/mac80211/tx.c +6 −3
  186. net/nfc/core.c +25 −25
  187. net/nfc/hci/command.c +6 −1
  188. net/nfc/hci/core.c +42 −15
  189. net/nfc/hci/hcp.c +7 −0
  190. net/nfc/llcp/commands.c +2 −0
  191. net/nfc/llcp/llcp.c +31 −13
  192. net/nfc/llcp/llcp.h +0 −1
  193. net/nfc/llcp/sock.c +11 −11
  194. net/nfc/nci/core.c +2 −0
  195. net/nfc/netlink.c +1 −0
Documentation/nfc/nfc-hci.txt+103−26
@@ -17,10 +17,12 @@ HCI · 16 unmodified lines
1717 HCI registers as an nfc device with NFC Core. Requests coming from userspace are
1818 routed through netlink sockets to NFC Core and then to HCI. From this point,
1919 they are translated in a sequence of HCI commands sent to the HCI layer in the
20−host controller (the chip). The sending context blocks while waiting for the
21−response to arrive.
20+host controller (the chip). Commands can be executed synchronously (the sending
21+context blocks waiting for response) or asynchronously (the response is returned
22+from HCI Rx context).
2223 HCI events can also be received from the host controller. They will be handled
23−and a translation will be forwarded to NFC Core as needed.
24+and a translation will be forwarded to NFC Core as needed. There are hooks to
25+let the HCI driver handle proprietary events or override standard behavior.
2426 HCI uses 2 execution contexts:
2527 - one for executing commands : nfc_hci_msg_tx_work(). Only one command
2628 can be executing at any given moment.
@@ -33,6 +35,8 @@ The Session initialization is an HCI standard which must unfortunately · 6 unmodified lines
3335 support proprietary gates. This is the reason why the driver will pass a list
3436 of proprietary gates that must be part of the session. HCI will ensure all
3537 those gates have pipes connected when the hci device is set up.
38+In case the chip supports pre-opened gates and pseudo-static pipes, the driver
39+can pass that information to HCI core.
3640
3741 HCI Gates and Pipes
3842 -------------------
@@ -46,6 +50,13 @@ without knowing the pipe connected to it. · 7 unmodified lines
4650 Driver interface
4751 ----------------
4852
53+A driver is generally written in two parts : the physical link management and
54+the HCI management. This makes it easier to maintain a driver for a chip that
55+can be connected using various phy (i2c, spi, ...)
56+
57+HCI Management
58+--------------
59+
4960 A driver would normally register itself with HCI and provide the following
5061 entry points:
5162
@@ -53,58 +64,113 @@ struct nfc_hci_ops { · 1 unmodified line
5364 int (*open)(struct nfc_hci_dev *hdev);
5465 void (*close)(struct nfc_hci_dev *hdev);
5566 int (*hci_ready) (struct nfc_hci_dev *hdev);
56− int (*xmit)(struct nfc_hci_dev *hdev, struct sk_buff *skb);
57− int (*start_poll)(struct nfc_hci_dev *hdev, u32 protocols);
58− int (*target_from_gate)(struct nfc_hci_dev *hdev, u8 gate,
59− struct nfc_target *target);
67+ int (*xmit) (struct nfc_hci_dev *hdev, struct sk_buff *skb);
68+ int (*start_poll) (struct nfc_hci_dev *hdev,
69+ u32 im_protocols, u32 tm_protocols);
70+ int (*dep_link_up)(struct nfc_hci_dev *hdev, struct nfc_target *target,
71+ u8 comm_mode, u8 *gb, size_t gb_len);
72+ int (*dep_link_down)(struct nfc_hci_dev *hdev);
73+ int (*target_from_gate) (struct nfc_hci_dev *hdev, u8 gate,
74+ struct nfc_target *target);
6075 int (*complete_target_discovered) (struct nfc_hci_dev *hdev, u8 gate,
6176 struct nfc_target *target);
62− int (*data_exchange) (struct nfc_hci_dev *hdev,
63− struct nfc_target *target,
64− struct sk_buff *skb, struct sk_buff **res_skb);
77+ int (*im_transceive) (struct nfc_hci_dev *hdev,
78+ struct nfc_target *target, struct sk_buff *skb,
79+ data_exchange_cb_t cb, void *cb_context);
80+ int (*tm_send)(struct nfc_hci_dev *hdev, struct sk_buff *skb);
6581 int (*check_presence)(struct nfc_hci_dev *hdev,
6682 struct nfc_target *target);
83+ int (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event,
84+ struct sk_buff *skb);
6785 };
6886
6987 - open() and close() shall turn the hardware on and off.
7088 - hci_ready() is an optional entry point that is called right after the hci
7189 session has been set up. The driver can use it to do additional initialization
7290 that must be performed using HCI commands.
73−- xmit() shall simply write a frame to the chip.
91+- xmit() shall simply write a frame to the physical link.
7492 - start_poll() is an optional entrypoint that shall set the hardware in polling
7593 mode. This must be implemented only if the hardware uses proprietary gates or a
7694 mechanism slightly different from the HCI standard.
95+- dep_link_up() is called after a p2p target has been detected, to finish
96+the p2p connection setup with hardware parameters that need to be passed back
97+to nfc core.
98+- dep_link_down() is called to bring the p2p link down.
7799 - target_from_gate() is an optional entrypoint to return the nfc protocols
78100 corresponding to a proprietary gate.
79101 - complete_target_discovered() is an optional entry point to let the driver
80102 perform additional proprietary processing necessary to auto activate the
81103 discovered target.
82−- data_exchange() must be implemented by the driver if proprietary HCI commands
104+- im_transceive() must be implemented by the driver if proprietary HCI commands
83105 are required to send data to the tag. Some tag types will require custom
84106 commands, others can be written to using the standard HCI commands. The driver
85107 can check the tag type and either do proprietary processing, or return 1 to ask
86−for standard processing.
108+for standard processing. The data exchange command itself must be sent
109+asynchronously.
110+- tm_send() is called to send data in the case of a p2p connection
87111 - check_presence() is an optional entry point that will be called regularly
88112 by the core to check that an activated tag is still in the field. If this is
89113 not implemented, the core will not be able to push tag_lost events to the user
90114 space
115+- event_received() is called to handle an event coming from the chip. Driver
116+can handle the event or return 1 to let HCI attempt standard processing.
91117
92118 On the rx path, the driver is responsible to push incoming HCP frames to HCI
93119 using nfc_hci_recv_frame(). HCI will take care of re-aggregation and handling
94120 This must be done from a context that can sleep.
95121
96−SHDLC
97−-----
122+PHY Management
123+--------------
124+
125+The physical link (i2c, ...) management is defined by the following struture:
126+
127+struct nfc_phy_ops {
128+ int (*write)(void *dev_id, struct sk_buff *skb);
129+ int (*enable)(void *dev_id);
130+ void (*disable)(void *dev_id);
131+};
132+
133+enable(): turn the phy on (power on), make it ready to transfer data
134+disable(): turn the phy off
135+write(): Send a data frame to the chip. Note that to enable higher
136+layers such as an llc to store the frame for re-emission, this function must
137+not alter the skb. It must also not return a positive result (return 0 for
138+success, negative for failure).
139+
140+Data coming from the chip shall be sent directly to nfc_hci_recv_frame().
141+
142+LLC
143+---
144+
145+Communication between the CPU and the chip often requires some link layer
146+protocol. Those are isolated as modules managed by the HCI layer. There are
147+currently two modules : nop (raw transfert) and shdlc.
148+A new llc must implement the following functions:
149+
150+struct nfc_llc_ops {
151+ void *(*init) (struct nfc_hci_dev *hdev, xmit_to_drv_t xmit_to_drv,
152+ rcv_to_hci_t rcv_to_hci, int tx_headroom,
153+ int tx_tailroom, int *rx_headroom, int *rx_tailroom,
154+ llc_failure_t llc_failure);
155+ void (*deinit) (struct nfc_llc *llc);
156+ int (*start) (struct nfc_llc *llc);
157+ int (*stop) (struct nfc_llc *llc);
158+ void (*rcv_from_drv) (struct nfc_llc *llc, struct sk_buff *skb);
159+ int (*xmit_from_hci) (struct nfc_llc *llc, struct sk_buff *skb);
160+};
161+
162+- init() : allocate and init your private storage
163+- deinit() : cleanup
164+- start() : establish the logical connection
165+- stop () : terminate the logical connection
166+- rcv_from_drv() : handle data coming from the chip, going to HCI
167+- xmit_from_hci() : handle data sent by HCI, going to the chip
98168
99−Most chips use shdlc to ensure integrity and delivery ordering of the HCP
100−frames between the host controller (the chip) and hosts (entities connected
101−to the chip, like the cpu). In order to simplify writing the driver, an shdlc
102−layer is available for use by the driver.
103−When used, the driver actually registers with shdlc, and shdlc will register
104−with HCI. HCI sees shdlc as the driver and thus send its HCP frames
105−through shdlc->xmit.
106−SHDLC adds a new execution context (nfc_shdlc_sm_work()) to run its state
107−machine and handle both its rx and tx path.
169+The llc must be registered with nfc before it can be used. Do that by
170+calling nfc_llc_register(const char *name, struct nfc_llc_ops *ops);
171+
172+Again, note that the llc does not handle the physical link. It is thus very
173+easy to mix any physical link with any llc for a given chip driver.
108174
109175 Included Drivers
110176 ----------------
@@ -117,10 +183,12 @@ Execution Contexts · 6 unmodified lines
117183
118184 The execution contexts are the following:
119185 - IRQ handler (IRQH):
120−fast, cannot sleep. stores incoming frames into an shdlc rx queue
186+fast, cannot sleep. sends incoming frames to HCI where they are passed to
187+the current llc. In case of shdlc, the frame is queued in shdlc rx queue.
121188
122189 - SHDLC State Machine worker (SMW)
123−handles shdlc rx & tx queues. Dispatches HCI cmd responses.
190+Only when llc_shdlc is used: handles shdlc rx & tx queues.
191+Dispatches HCI cmd responses.
124192
125193 - HCI Tx Cmd worker (MSGTXWQ)
126194 Serializes execution of HCI commands. Completes execution in case of response
@@ -166,6 +234,15 @@ waiting command execution. Response processing involves invoking the completion · 39 unmodified lines
166234 callback that was provided by nfc_hci_msg_tx_work() when it sent the command.
167235 The completion callback will then wake the syscall context.
168236
237+It is also possible to execute the command asynchronously using this API:
238+
239+static int nfc_hci_execute_cmd_async(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
240+ const u8 *param, size_t param_len,
241+ data_exchange_cb_t cb, void *cb_context)
242+
243+The workflow is the same, except that the API call returns immediately, and
244+the callback will be called with the result from the SMW context.
245+
169246 Workflow receiving an HCI event or command
170247 ------------------------------------------
171248
Documentation/nfc/nfc-pn544.txt+1−83
@@ -1,32 +1,15 @@
11 Kernel driver for the NXP Semiconductors PN544 Near Field
22 Communication chip
33
4−Author: Jari Vanhala
5−Contact: Matti Aaltonen (matti.j.aaltonen at nokia.com)
6−
74 General
85 -------
96
107 The PN544 is an integrated transmission module for contactless
118 communication. The driver goes under drives/nfc/ and is compiled as a
12−module named "pn544". It registers a misc device and creates a device
13−file named "/dev/pn544".
9+module named "pn544".
1410
1511 Host Interfaces: I2C, SPI and HSU, this driver supports currently only I2C.
1612
17−The Interface
18−-------------
19−
20−The driver offers a sysfs interface for a hardware test and an IOCTL
21−interface for selecting between two operating modes. There are read,
22−write and poll functions for transferring messages. The two operating
23−modes are the normal (HCI) mode and the firmware update mode.
24−
25−PN544 is controlled by sending messages from the userspace to the
26−chip. The main function of the driver is just to pass those messages
27−without caring about the message content.
28−
29−
3013 Protocols
3114 ---------
3215
@@ -47,68 +30,3 @@ and third (LSB) bytes of the message. The maximum FW message length is · 14 unmodified lines
4730
4831 For the ETSI HCI specification see
4932 http://www.etsi.org/WebSite/Technologies/ProtocolSpecification.aspx
50−
51−The Hardware Test
52−-----------------
53−
54−The idea of the test is that it can performed by reading from the
55−corresponding sysfs file. The test is implemented in the board file
56−and it should test that PN544 can be put into the firmware update
57−mode. If the test is not implemented the sysfs file does not get
58−created.
59−
60−Example:
61−> cat /sys/module/pn544/drivers/i2c\:pn544/3-002b/nfc_test
62−1
63−
64−Normal Operation
65−----------------
66−
67−PN544 is powered up when the device file is opened, otherwise it's
68−turned off. Only one instance can use the device at a time.
69−
70−Userspace applications control PN544 with HCI messages. The hardware
71−sends an interrupt when data is available for reading. Data is
72−physically read when the read function is called by a userspace
73−application. Poll() checks the read interrupt state. Configuration and
74−self testing are also done from the userspace using read and write.
75−
76−Example platform data:
77−
78−static int rx71_pn544_nfc_request_resources(struct i2c_client *client)
79−{
80− /* Get and setup the HW resources for the device */
81−}
82−
83−static void rx71_pn544_nfc_free_resources(void)
84−{
85− /* Release the HW resources */
86−}
87−
88−static void rx71_pn544_nfc_enable(int fw)
89−{
90− /* Turn the device on */
91−}
92−
93−static int rx71_pn544_nfc_test(void)
94−{
95− /*
96− * Put the device into the FW update mode
97− * and then back to the normal mode.
98− * Check the behavior and return one on success,
99− * zero on failure.
100− */
101−}
102−
103−static void rx71_pn544_nfc_disable(void)
104−{
105− /* turn the power off */
106−}
107−
108−static struct pn544_nfc_platform_data rx71_nfc_data = {
109− .request_resources = rx71_pn544_nfc_request_resources,
110− .free_resources = rx71_pn544_nfc_free_resources,
111− .enable = rx71_pn544_nfc_enable,
112− .test = rx71_pn544_nfc_test,
113− .disable = rx71_pn544_nfc_disable,
114−};
MAINTAINERS+8−0
@@ -1353,6 +1353,14 @@ W: http://wireless.kernel.org/en/users/Drivers/ath9k · 1352 unmodified lines
13531353 S: Supported
13541354 F: drivers/net/wireless/ath/ath9k/
13551355
1356+WILOCITY WIL6210 WIRELESS DRIVER
1357+M: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
1358+L: linux-wireless@vger.kernel.org
1359+L: wil6210@qca.qualcomm.com
1360+S: Supported
1361+W: http://wireless.kernel.org/en/users/Drivers/wil6210
1362+F: drivers/net/wireless/ath/wil6210/
1363+
13561364 CARL9170 LINUX COMMUNITY WIRELESS DRIVER
13571365 M: Christian Lamparter <chunkeey@googlemail.com>
13581366 L: linux-wireless@vger.kernel.org
arch/mips/bcm47xx/serial.c+1−1
@@ -62,7 +62,7 @@ static int __init uart8250_init_bcma(void) · 61 unmodified lines
6262
6363 p->mapbase = (unsigned int) bcma_port->regs;
6464 p->membase = (void *) bcma_port->regs;
65− p->irq = bcma_port->irq + 2;
65+ p->irq = bcma_port->irq;
6666 p->uartclk = bcma_port->baud_base;
6767 p->regshift = bcma_port->reg_shift;
6868 p->iotype = UPIO_MEM;
drivers/bcma/Kconfig+1−2
@@ -67,8 +67,7 @@ config BCMA_DRIVER_GMAC_CMN · 66 unmodified lines
6767
6868 config BCMA_DRIVER_GPIO
6969 bool "BCMA GPIO driver"
70− depends on BCMA
71− select GPIOLIB
70+ depends on BCMA && GPIOLIB
7271 help
7372 Driver to provide access to the GPIO pins of the bcma bus.
7473
drivers/bcma/bcma_private.h+2−0
@@ -31,6 +31,8 @@ int __init bcma_bus_early_register(struct bcma_bus *bus, · 30 unmodified lines
3131 int bcma_bus_suspend(struct bcma_bus *bus);
3232 int bcma_bus_resume(struct bcma_bus *bus);
3333 #endif
34+struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
35+ u8 unit);
3436
3537 /* scan.c */
3638 int bcma_bus_scan(struct bcma_bus *bus);
drivers/bcma/driver_chipcommon.c+1−1
@@ -329,7 +329,7 @@ void bcma_chipco_serial_init(struct bcma_drv_cc *cc) · 328 unmodified lines
329329 return;
330330 }
331331
332− irq = bcma_core_mips_irq(cc->core);
332+ irq = bcma_core_irq(cc->core);
333333
334334 /* Determine the registers of the UARTs */
335335 cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
drivers/bcma/driver_chipcommon_sflash.c+1−1
@@ -35,7 +35,7 @@ static struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = { · 34 unmodified lines
3535 { "M25P40", 0x12, 0x10000, 8, },
3636
3737 { "M25P16", 0x14, 0x10000, 32, },
38− { "M25P32", 0x14, 0x10000, 64, },
38+ { "M25P32", 0x15, 0x10000, 64, },
3939 { "M25P64", 0x16, 0x10000, 128, },
4040 { "M25FL128", 0x17, 0x10000, 256, },
4141 { 0 },
drivers/bcma/driver_mips.c+112−45
@@ -74,28 +74,41 @@ static u32 bcma_core_mips_irqflag(struct bcma_device *dev) · 73 unmodified lines
7474 return dev->core_index;
7575 flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
7676
77− return flag & 0x1F;
77+ if (flag)
78+ return flag & 0x1F;
79+ else
80+ return 0x3f;
7881 }
7982
8083 /* Get the MIPS IRQ assignment for a specified device.
8184 * If unassigned, 0 is returned.
85+ * If disabled, 5 is returned.
86+ * If not supported, 6 is returned.
8287 */
83−unsigned int bcma_core_mips_irq(struct bcma_device *dev)
88+static unsigned int bcma_core_mips_irq(struct bcma_device *dev)
8489 {
8590 struct bcma_device *mdev = dev->bus->drv_mips.core;
8691 u32 irqflag;
8792 unsigned int irq;
8893
8994 irqflag = bcma_core_mips_irqflag(dev);
95+ if (irqflag == 0x3f)
96+ return 6;
9097
91− for (irq = 1; irq <= 4; irq++)
98+ for (irq = 0; irq <= 4; irq++)
9299 if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
93100 (1 << irqflag))
94101 return irq;
95102
96− return 0;
103+ return 5;
104+}
105+
106+unsigned int bcma_core_irq(struct bcma_device *dev)
107+{
108+ unsigned int mips_irq = bcma_core_mips_irq(dev);
109+ return mips_irq <= 4 ? mips_irq + 2 : 0;
97110 }
98−EXPORT_SYMBOL(bcma_core_mips_irq);
111+EXPORT_SYMBOL(bcma_core_irq);
99112
100113 static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
101114 {
@@ -114,7 +127,7 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) · 12 unmodified lines
114127 bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
115128 bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
116129 ~(1 << irqflag));
117− else
130+ else if (oldirq != 5)
118131 bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(oldirq), 0);
119132
120133 /* assign the new one */
@@ -123,9 +136,9 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) · 2 unmodified lines
123136 bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
124137 (1 << irqflag));
125138 } else {
126− u32 oldirqflag = bcma_read32(mdev,
127− BCMA_MIPS_MIPS74K_INTMASK(irq));
128− if (oldirqflag) {
139+ u32 irqinitmask = bcma_read32(mdev,
140+ BCMA_MIPS_MIPS74K_INTMASK(irq));
141+ if (irqinitmask) {
129142 struct bcma_device *core;
130143
131144 /* backplane irq line is in use, find out who uses
@@ -133,7 +146,7 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) · 1 unmodified line
133146 */
134147 list_for_each_entry(core, &bus->cores, list) {
135148 if ((1 << bcma_core_mips_irqflag(core)) ==
136− oldirqflag) {
149+ irqinitmask) {
137150 bcma_core_mips_set_irq(core, 0);
138151 break;
139152 }
@@ -143,15 +156,31 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) · 3 unmodified lines
143156 1 << irqflag);
144157 }
145158
146− bcma_info(bus, "set_irq: core 0x%04x, irq %d => %d\n",
147− dev->id.id, oldirq + 2, irq + 2);
159+ bcma_debug(bus, "set_irq: core 0x%04x, irq %d => %d\n",
160+ dev->id.id, oldirq <= 4 ? oldirq + 2 : 0, irq + 2);
161+}
162+
163+static void bcma_core_mips_set_irq_name(struct bcma_bus *bus, unsigned int irq,
164+ u16 coreid, u8 unit)
165+{
166+ struct bcma_device *core;
167+
168+ core = bcma_find_core_unit(bus, coreid, unit);
169+ if (!core) {
170+ bcma_warn(bus,
171+ "Can not find core (id: 0x%x, unit %i) for IRQ configuration.\n",
172+ coreid, unit);
173+ return;
174+ }
175+
176+ bcma_core_mips_set_irq(core, irq);
148177 }
149178
150179 static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
151180 {
152181 int i;
153182 static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
154− printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
183+ printk(KERN_DEBUG KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
155184 for (i = 0; i <= 6; i++)
156185 printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
157186 printk("\n");
@@ -227,6 +256,32 @@ void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) · 69 unmodified lines
227256 mcore->early_setup_done = true;
228257 }
229258
259+static void bcma_fix_i2s_irqflag(struct bcma_bus *bus)
260+{
261+ struct bcma_device *cpu, *pcie, *i2s;
262+
263+ /* Fixup the interrupts in 4716/4748 for i2s core (2010 Broadcom SDK)
264+ * (IRQ flags > 7 are ignored when setting the interrupt masks)
265+ */
266+ if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4716 &&
267+ bus->chipinfo.id != BCMA_CHIP_ID_BCM4748)
268+ return;
269+
270+ cpu = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
271+ pcie = bcma_find_core(bus, BCMA_CORE_PCIE);
272+ i2s = bcma_find_core(bus, BCMA_CORE_I2S);
273+ if (cpu && pcie && i2s &&
274+ bcma_aread32(cpu, BCMA_MIPS_OOBSELINA74) == 0x08060504 &&
275+ bcma_aread32(pcie, BCMA_MIPS_OOBSELINA74) == 0x08060504 &&
276+ bcma_aread32(i2s, BCMA_MIPS_OOBSELOUTA30) == 0x88) {
277+ bcma_awrite32(cpu, BCMA_MIPS_OOBSELINA74, 0x07060504);
278+ bcma_awrite32(pcie, BCMA_MIPS_OOBSELINA74, 0x07060504);
279+ bcma_awrite32(i2s, BCMA_MIPS_OOBSELOUTA30, 0x87);
280+ bcma_debug(bus,
281+ "Moved i2s interrupt to oob line 7 instead of 8\n");
282+ }
283+}
284+
230285 void bcma_core_mips_init(struct bcma_drv_mips *mcore)
231286 {
232287 struct bcma_bus *bus;
@@ -236,43 +291,55 @@ void bcma_core_mips_init(struct bcma_drv_mips *mcore) · 3 unmodified lines
236291 if (mcore->setup_done)
237292 return;
238293
239− bcma_info(bus, "Initializing MIPS core...\n");
294+ bcma_debug(bus, "Initializing MIPS core...\n");
240295
241296 bcma_core_mips_early_init(mcore);
242297
243− mcore->assigned_irqs = 1;
244−
245− /* Assign IRQs to all cores on the bus */
246− list_for_each_entry(core, &bus->cores, list) {
247− int mips_irq;
248− if (core->irq)
249− continue;
250−
251− mips_irq = bcma_core_mips_irq(core);
252− if (mips_irq > 4)
253− core->irq = 0;
254− else
255− core->irq = mips_irq + 2;
256− if (core->irq > 5)
257− continue;
258− switch (core->id.id) {
259− case BCMA_CORE_PCI:
260− case BCMA_CORE_PCIE:
261− case BCMA_CORE_ETHERNET:
262− case BCMA_CORE_ETHERNET_GBIT:
263− case BCMA_CORE_MAC_GBIT:
264− case BCMA_CORE_80211:
265− case BCMA_CORE_USB20_HOST:
266− /* These devices get their own IRQ line if available,
267− * the rest goes on IRQ0
268− */
269− if (mcore->assigned_irqs <= 4)
270− bcma_core_mips_set_irq(core,
271− mcore->assigned_irqs++);
272− break;
298+ bcma_fix_i2s_irqflag(bus);
299+
300+ switch (bus->chipinfo.id) {
301+ case BCMA_CHIP_ID_BCM4716:
302+ case BCMA_CHIP_ID_BCM4748:
303+ bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
304+ bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
305+ bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0);
306+ bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_PCIE, 0);
307+ bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
308+ bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0);
309+ break;
310+ case BCMA_CHIP_ID_BCM5356:
311+ case BCMA_CHIP_ID_BCM47162:
312+ case BCMA_CHIP_ID_BCM53572:
313+ bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
314+ bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
315+ bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
316+ break;
317+ case BCMA_CHIP_ID_BCM5357:
318+ case BCMA_CHIP_ID_BCM4749:
319+ bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
320+ bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
321+ bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0);
322+ bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
323+ bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0);
324+ break;
325+ case BCMA_CHIP_ID_BCM4706:
326+ bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_PCIE, 0);
327+ bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_4706_MAC_GBIT,
328+ 0);
329+ bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_PCIE, 1);
330+ bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_USB20_HOST, 0);
331+ bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_4706_CHIPCOMMON,
332+ 0);
333+ break;
334+ default:
335+ list_for_each_entry(core, &bus->cores, list) {
336+ core->irq = bcma_core_irq(core);
273337 }
338+ bcma_err(bus,
339+ "Unknown device (0x%x) found, can not configure IRQs\n",
340+ bus->chipinfo.id);
274341 }
275− bcma_info(bus, "IRQ reconfiguration done\n");
342+ bcma_debug(bus, "IRQ reconfiguration done\n");
276343 bcma_core_mips_dump_irq(bus);
277344
278345 mcore->setup_done = true;
drivers/bcma/driver_pci_host.c+38−24
@@ -94,19 +94,19 @@ static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev, · 93 unmodified lines
9494 if (dev == 0) {
9595 /* we support only two functions on device 0 */
9696 if (func > 1)
97− return -EINVAL;
97+ goto out;
9898
9999 /* accesses to config registers with offsets >= 256
100100 * requires indirect access.
101101 */
102102 if (off >= PCI_CONFIG_SPACE_SIZE) {
103103 addr = (func << 12);
104− addr |= (off & 0x0FFF);
104+ addr |= (off & 0x0FFC);
105105 val = bcma_pcie_read_config(pc, addr);
106106 } else {
107107 addr = BCMA_CORE_PCI_PCICFG0;
108108 addr |= (func << 8);
109− addr |= (off & 0xfc);
109+ addr |= (off & 0xFC);
110110 val = pcicore_read32(pc, addr);
111111 }
112112 } else {
@@ -119,11 +119,9 @@ static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev, · 6 unmodified lines
119119 goto out;
120120
121121 if (mips_busprobe32(val, mmio)) {
122− val = 0xffffffff;
122+ val = 0xFFFFFFFF;
123123 goto unmap;
124124 }
125−
126− val = readl(mmio);
127125 }
128126 val >>= (8 * (off & 3));
129127
@@ -151,7 +149,7 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev, · 21 unmodified lines
151149 const void *buf, int len)
152150 {
153151 int err = -EINVAL;
154− u32 addr = 0, val = 0;
152+ u32 addr, val;
155153 void __iomem *mmio = 0;
156154 u16 chipid = pc->core->bus->chipinfo.id;
157155
@@ -159,16 +157,22 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev, · 1 unmodified line
159157 if (unlikely(len != 1 && len != 2 && len != 4))
160158 goto out;
161159 if (dev == 0) {
160+ /* we support only two functions on device 0 */
161+ if (func > 1)
162+ goto out;
163+
162164 /* accesses to config registers with offsets >= 256
163165 * requires indirect access.
164166 */
165− if (off < PCI_CONFIG_SPACE_SIZE) {
166− addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0;
167+ if (off >= PCI_CONFIG_SPACE_SIZE) {
168+ addr = (func << 12);
169+ addr |= (off & 0x0FFC);
170+ val = bcma_pcie_read_config(pc, addr);
171+ } else {
172+ addr = BCMA_CORE_PCI_PCICFG0;
167173 addr |= (func << 8);
168− addr |= (off & 0xfc);
169− mmio = ioremap_nocache(addr, sizeof(val));
170− if (!mmio)
171− goto out;
174+ addr |= (off & 0xFC);
175+ val = pcicore_read32(pc, addr);
172176 }
173177 } else {
174178 addr = bcma_get_cfgspace_addr(pc, dev, func, off);
@@ -180,19 +184,17 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev, · 5 unmodified lines
180184 goto out;
181185
182186 if (mips_busprobe32(val, mmio)) {
183− val = 0xffffffff;
187+ val = 0xFFFFFFFF;
184188 goto unmap;
185189 }
186190 }
187191
188192 switch (len) {
189193 case 1:
190− val = readl(mmio);
191194 val &= ~(0xFF << (8 * (off & 3)));
192195 val |= *((const u8 *)buf) << (8 * (off & 3));
193196 break;
194197 case 2:
195− val = readl(mmio);
196198 val &= ~(0xFFFF << (8 * (off & 3)));
197199 val |= *((const u16 *)buf) << (8 * (off & 3));
198200 break;
@@ -200,13 +202,14 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev, · 1 unmodified line
200202 val = *((const u32 *)buf);
201203 break;
202204 }
203− if (dev == 0 && !addr) {
205+ if (dev == 0) {
204206 /* accesses to config registers with offsets >= 256
205207 * requires indirect access.
206208 */
207− addr = (func << 12);
208− addr |= (off & 0x0FFF);
209− bcma_pcie_write_config(pc, addr, val);
209+ if (off >= PCI_CONFIG_SPACE_SIZE)
210+ bcma_pcie_write_config(pc, addr, val);
211+ else
212+ pcicore_write32(pc, addr, val);
210213 } else {
211214 writel(val, mmio);
212215
@@ -277,7 +280,7 @@ static u8 __devinit bcma_find_pci_capability(struct bcma_drv_pci *pc, · 64 unmodified lines
277280 /* check for Header type 0 */
278281 bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val,
279282 sizeof(u8));
280− if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
283+ if ((byte_val & 0x7F) != PCI_HEADER_TYPE_NORMAL)
281284 return cap_ptr;
282285
283286 /* check if the capability pointer field exists */
@@ -427,7 +430,7 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) · 143 unmodified lines
427430 /* Reset RC */
428431 usleep_range(3000, 5000);
429432 pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE);
430− usleep_range(1000, 2000);
433+ msleep(50);
431434 pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST |
432435 BCMA_CORE_PCI_CTL_RST_OE);
433436
@@ -489,6 +492,17 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) · 55 unmodified lines
489492
490493 bcma_core_pci_enable_crs(pc);
491494
495+ if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706 ||
496+ bus->chipinfo.id == BCMA_CHIP_ID_BCM4716) {
497+ u16 val16;
498+ bcma_extpci_read_config(pc, 0, 0, BCMA_CORE_PCI_CFG_DEVCTRL,
499+ &val16, sizeof(val16));
500+ val16 |= (2 << 5); /* Max payload size of 512 */
501+ val16 |= (2 << 12); /* MRRS 512 */
502+ bcma_extpci_write_config(pc, 0, 0, BCMA_CORE_PCI_CFG_DEVCTRL,
503+ &val16, sizeof(val16));
504+ }
505+
492506 /* Enable PCI bridge BAR0 memory & master access */
493507 tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
494508 bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp));
@@ -577,7 +591,7 @@ int bcma_core_pci_plat_dev_init(struct pci_dev *dev) · 82 unmodified lines
577591 pr_info("PCI: Fixing up device %s\n", pci_name(dev));
578592
579593 /* Fix up interrupt lines */
580− dev->irq = bcma_core_mips_irq(pc_host->pdev->core) + 2;
594+ dev->irq = bcma_core_irq(pc_host->pdev->core);
581595 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
582596
583597 return 0;
@@ -596,6 +610,6 @@ int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev) · 12 unmodified lines
596610
597611 pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
598612 pci_ops);
599− return bcma_core_mips_irq(pc_host->pdev->core) + 2;
613+ return bcma_core_irq(pc_host->pdev->core);
600614 }
601615 EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq);
drivers/bcma/main.c+2−2
@@ -81,8 +81,8 @@ struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) · 80 unmodified lines
8181 }
8282 EXPORT_SYMBOL_GPL(bcma_find_core);
8383
84−static struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
85− u8 unit)
84+struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
85+ u8 unit)
8686 {
8787 struct bcma_device *core;
8888
drivers/bluetooth/ath3k.c+10−0
@@ -77,10 +77,15 @@ static struct usb_device_id ath3k_table[] = { · 76 unmodified lines
7777 { USB_DEVICE(0x0CF3, 0x311D) },
7878 { USB_DEVICE(0x13d3, 0x3375) },
7979 { USB_DEVICE(0x04CA, 0x3005) },
80+ { USB_DEVICE(0x04CA, 0x3006) },
81+ { USB_DEVICE(0x04CA, 0x3008) },
8082 { USB_DEVICE(0x13d3, 0x3362) },
8183 { USB_DEVICE(0x0CF3, 0xE004) },
8284 { USB_DEVICE(0x0930, 0x0219) },
8385 { USB_DEVICE(0x0489, 0xe057) },
86+ { USB_DEVICE(0x13d3, 0x3393) },
87+ { USB_DEVICE(0x0489, 0xe04e) },
88+ { USB_DEVICE(0x0489, 0xe056) },
8489
8590 /* Atheros AR5BBU12 with sflash firmware */
8691 { USB_DEVICE(0x0489, 0xE02C) },
@@ -104,10 +109,15 @@ static struct usb_device_id ath3k_blist_tbl[] = { · 17 unmodified lines
104109 { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
105110 { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
106111 { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
112+ { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
113+ { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
107114 { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
108115 { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
109116 { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
110117 { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
118+ { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
119+ { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
120+ { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
111121
112122 /* Atheros AR5BBU22 with sflash firmware */
113123 { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
drivers/bluetooth/btusb.c+5−0
@@ -135,10 +135,15 @@ static struct usb_device_id blacklist_table[] = { · 134 unmodified lines
135135 { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
136136 { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
137137 { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
138+ { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
139+ { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
138140 { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
139141 { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
140142 { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
141143 { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
144+ { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
145+ { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
146+ { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
142147
143148 /* Atheros AR5BBU12 with sflash firmware */
144149 { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
drivers/net/wireless/ath/Kconfig+1−0
@@ -30,5 +30,6 @@ source "drivers/net/wireless/ath/ath9k/Kconfig" · 29 unmodified lines
3030 source "drivers/net/wireless/ath/carl9170/Kconfig"
3131 source "drivers/net/wireless/ath/ath6kl/Kconfig"
3232 source "drivers/net/wireless/ath/ar5523/Kconfig"
33+source "drivers/net/wireless/ath/wil6210/Kconfig"
3334
3435 endif
drivers/net/wireless/ath/Makefile+1−0
@@ -3,6 +3,7 @@ obj-$(CONFIG_ATH9K_HW) += ath9k/ · 2 unmodified lines
33 obj-$(CONFIG_CARL9170) += carl9170/
44 obj-$(CONFIG_ATH6KL) += ath6kl/
55 obj-$(CONFIG_AR5523) += ar5523/
6+obj-$(CONFIG_WIL6210) += wil6210/
67
78 obj-$(CONFIG_ATH_COMMON) += ath.o
89
drivers/net/wireless/ath/ath9k/Kconfig+3−2
@@ -2,6 +2,7 @@ config ATH9K_HW · 1 unmodified line
22 tristate
33 config ATH9K_COMMON
44 tristate
5+ select ATH_COMMON
56 config ATH9K_DFS_DEBUGFS
67 def_bool y
78 depends on ATH9K_DEBUGFS && ATH9K_DFS_CERTIFIED
@@ -17,7 +18,6 @@ config ATH9K_BTCOEX_SUPPORT · 9 unmodified lines
1718 config ATH9K
1819 tristate "Atheros 802.11n wireless cards support"
1920 depends on MAC80211
20− select ATH_COMMON
2121 select ATH9K_HW
2222 select MAC80211_LEDS
2323 select LEDS_CLASS
@@ -56,7 +56,8 @@ config ATH9K_AHB · 32 unmodified lines
5656
5757 config ATH9K_DEBUGFS
5858 bool "Atheros ath9k debugging"
59− depends on ATH9K && DEBUG_FS
59+ depends on ATH9K
60+ select MAC80211_DEBUGFS
6061 ---help---
6162 Say Y, if you need access to ath9k's statistics for
6263 interrupts, rate control, etc.
drivers/net/wireless/ath/ath9k/ahb.c+6−16
@@ -86,29 +86,25 @@ static int ath_ahb_probe(struct platform_device *pdev) · 85 unmodified lines
8686
8787 if (!pdev->dev.platform_data) {
8888 dev_err(&pdev->dev, "no platform data specified\n");
89− ret = -EINVAL;
90− goto err_out;
89+ return -EINVAL;
9190 }
9291
9392 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
9493 if (res == NULL) {
9594 dev_err(&pdev->dev, "no memory resource found\n");
96− ret = -ENXIO;
97− goto err_out;
95+ return -ENXIO;
9896 }
9997
100− mem = ioremap_nocache(res->start, resource_size(res));
98+ mem = devm_ioremap_nocache(&pdev->dev, res->start, resource_size(res));
10199 if (mem == NULL) {
102100 dev_err(&pdev->dev, "ioremap failed\n");
103− ret = -ENOMEM;
104− goto err_out;
101+ return -ENOMEM;
105102 }
106103
107104 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
108105 if (res == NULL) {
109106 dev_err(&pdev->dev, "no IRQ resource found\n");
110− ret = -ENXIO;
111− goto err_iounmap;
107+ return -ENXIO;
112108 }
113109
114110 irq = res->start;
@@ -116,8 +112,7 @@ static int ath_ahb_probe(struct platform_device *pdev) · 1 unmodified line
116112 hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
117113 if (hw == NULL) {
118114 dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
119− ret = -ENOMEM;
120− goto err_iounmap;
115+ return -ENOMEM;
121116 }
122117
123118 SET_IEEE80211_DEV(hw, &pdev->dev);
@@ -156,9 +151,6 @@ static int ath_ahb_probe(struct platform_device *pdev) · 32 unmodified lines
156151 err_free_hw:
157152 ieee80211_free_hw(hw);
158153 platform_set_drvdata(pdev, NULL);
159− err_iounmap:
160− iounmap(mem);
161− err_out:
162154 return ret;
163155 }
164156
@@ -168,12 +160,10 @@ static int ath_ahb_remove(struct platform_device *pdev) · 3 unmodified lines
168160
169161 if (hw) {
170162 struct ath_softc *sc = hw->priv;
171− void __iomem *mem = sc->mem;
172163
173164 ath9k_deinit_device(sc);
174165 free_irq(sc->irq, sc);
175166 ieee80211_free_hw(sc->hw);
176− iounmap(mem);
177167 platform_set_drvdata(pdev, NULL);
178168 }
179169
drivers/net/wireless/ath/ath9k/ani.c+6−27
@@ -152,7 +152,8 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel, · 151 unmodified lines
152152 ath_dbg(common, ANI, "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
153153 aniState->ofdmNoiseImmunityLevel,
154154 immunityLevel, BEACON_RSSI(ah),
155− aniState->rssiThrLow, aniState->rssiThrHigh);
155+ ATH9K_ANI_RSSI_THR_LOW,
156+ ATH9K_ANI_RSSI_THR_HIGH);
156157
157158 if (!scan)
158159 aniState->ofdmNoiseImmunityLevel = immunityLevel;
@@ -173,7 +174,7 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel, · 14 unmodified lines
173174
174175 weak_sig = entry_ofdm->ofdm_weak_signal_on;
175176 if (ah->opmode == NL80211_IFTYPE_STATION &&
176− BEACON_RSSI(ah) <= aniState->rssiThrHigh)
177+ BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_HIGH)
177178 weak_sig = true;
178179
179180 if (aniState->ofdmWeakSigDetect != weak_sig)
@@ -216,11 +217,11 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel, · 36 unmodified lines
216217
217218 ath_dbg(common, ANI, "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
218219 aniState->cckNoiseImmunityLevel, immunityLevel,
219− BEACON_RSSI(ah), aniState->rssiThrLow,
220− aniState->rssiThrHigh);
220+ BEACON_RSSI(ah), ATH9K_ANI_RSSI_THR_LOW,
221+ ATH9K_ANI_RSSI_THR_HIGH);
221222
222223 if (ah->opmode == NL80211_IFTYPE_STATION &&
223− BEACON_RSSI(ah) <= aniState->rssiThrLow &&
224+ BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_LOW &&
224225 immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI)
225226 immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI;
226227
@@ -418,9 +419,6 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan) · 191 unmodified lines
418419 return;
419420
420421 aniState = &ah->curchan->ani;
421− if (WARN_ON(!aniState))
422− return;
423−
424422 if (!ath9k_hw_ani_read_counters(ah))
425423 return;
426424
@@ -489,23 +487,6 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah) · 62 unmodified lines
489487 }
490488 EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
491489
492−void ath9k_hw_ani_setup(struct ath_hw *ah)
493−{
494− int i;
495−
496− static const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
497− static const int coarseHigh[] = { -14, -14, -14, -14, -12 };
498− static const int coarseLow[] = { -64, -64, -64, -64, -70 };
499− static const int firpwr[] = { -78, -78, -78, -78, -80 };
500−
501− for (i = 0; i < 5; i++) {
502− ah->totalSizeDesired[i] = totalSizeDesired[i];
503− ah->coarse_high[i] = coarseHigh[i];
504− ah->coarse_low[i] = coarseLow[i];
505− ah->firpwr[i] = firpwr[i];
506− }
507−}
508−
509490 void ath9k_hw_ani_init(struct ath_hw *ah)
510491 {
511492 struct ath_common *common = ath9k_hw_common(ah);
@@ -531,8 +512,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah) · 19 unmodified lines
531512
532513 ani->ofdmsTurn = true;
533514
534− ani->rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
535− ani->rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
536515 ani->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
537516 ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
538517 ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
drivers/net/wireless/ath/ath9k/ani.h+0−8
@@ -104,7 +104,6 @@ struct ath9k_ani_default { · 103 unmodified lines
104104 };
105105
106106 struct ar5416AniState {
107− struct ath9k_channel *c;
108107 u8 noiseImmunityLevel;
109108 u8 ofdmNoiseImmunityLevel;
110109 u8 cckNoiseImmunityLevel;
@@ -113,15 +112,9 @@ struct ar5416AniState { · 2 unmodified lines
113112 u8 spurImmunityLevel;
114113 u8 firstepLevel;
115114 u8 ofdmWeakSigDetect;
116− u8 cckWeakSigThreshold;
117115 u32 listenTime;
118− int32_t rssiThrLow;
119− int32_t rssiThrHigh;
120116 u32 ofdmPhyErrCount;
121117 u32 cckPhyErrCount;
122− int16_t pktRssi[2];
123− int16_t ofdmErrRssi[2];
124− int16_t cckErrRssi[2];
125118 struct ath9k_ani_default iniDef;
126119 };
127120
@@ -147,7 +140,6 @@ struct ar5416Stats { · 19 unmodified lines
147140
148141 void ath9k_enable_mib_counters(struct ath_hw *ah);
149142 void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
150−void ath9k_hw_ani_setup(struct ath_hw *ah);
151143 void ath9k_hw_ani_init(struct ath_hw *ah);
152144
153145 #endif /* ANI_H */
drivers/net/wireless/ath/ath9k/ar5008_initvals.h+4−4
@@ -466,7 +466,7 @@ static const u32 ar5416Bank0[][2] = { · 465 unmodified lines
466466 };
467467
468468 static const u32 ar5416BB_RfGain[][3] = {
469− /* Addr 5G_HT20 5G_HT40 */
469+ /* Addr 5G 2G */
470470 {0x00009a00, 0x00000000, 0x00000000},
471471 {0x00009a04, 0x00000040, 0x00000040},
472472 {0x00009a08, 0x00000080, 0x00000080},
@@ -546,12 +546,12 @@ static const u32 ar5416Bank2[][2] = { · 73 unmodified lines
546546 };
547547
548548 static const u32 ar5416Bank3[][3] = {
549− /* Addr 5G_HT20 5G_HT40 */
549+ /* Addr 5G 2G */
550550 {0x000098f0, 0x01400018, 0x01c00018},
551551 };
552552
553553 static const u32 ar5416Bank6[][3] = {
554− /* Addr 5G_HT20 5G_HT40 */
554+ /* Addr 5G 2G */
555555 {0x0000989c, 0x00000000, 0x00000000},
556556 {0x0000989c, 0x00000000, 0x00000000},
557557 {0x0000989c, 0x00000000, 0x00000000},
@@ -588,7 +588,7 @@ static const u32 ar5416Bank6[][3] = { · 30 unmodified lines
588588 };
589589
590590 static const u32 ar5416Bank6TPC[][3] = {
591− /* Addr 5G_HT20 5G_HT40 */
591+ /* Addr 5G 2G */
592592 {0x0000989c, 0x00000000, 0x00000000},
593593 {0x0000989c, 0x00000000, 0x00000000},
594594 {0x0000989c, 0x00000000, 0x00000000},
drivers/net/wireless/ath/ath9k/ar5008_phy.c+15−35
@@ -470,16 +470,15 @@ static void ar5008_hw_spur_mitigate(struct ath_hw *ah, · 469 unmodified lines
470470 static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah)
471471 {
472472 #define ATH_ALLOC_BANK(bank, size) do { \
473− bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \
474− if (!bank) { \
475− ath_err(common, "Cannot allocate RF banks\n"); \
476− return -ENOMEM; \
477− } \
473+ bank = devm_kzalloc(ah->dev, sizeof(u32) * size, GFP_KERNEL); \
474+ if (!bank) \
475+ goto error; \
478476 } while (0);
479477
480478 struct ath_common *common = ath9k_hw_common(ah);
481479
482− BUG_ON(AR_SREV_9280_20_OR_LATER(ah));
480+ if (AR_SREV_9280_20_OR_LATER(ah))
481+ return 0;
483482
484483 ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows);
485484 ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows);
@@ -492,35 +491,12 @@ static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah) · 6 unmodified lines
492491
493492 return 0;
494493 #undef ATH_ALLOC_BANK
494+error:
495+ ath_err(common, "Cannot allocate RF banks\n");
496+ return -ENOMEM;
495497 }
496498
497499
498−/**
499− * ar5008_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers
500− * @ah: atheros hardware struture
501− * For the external AR2133/AR5133 radios banks.
502− */
503−static void ar5008_hw_rf_free_ext_banks(struct ath_hw *ah)
504−{
505−#define ATH_FREE_BANK(bank) do { \
506− kfree(bank); \
507− bank = NULL; \
508− } while (0);
509−
510− BUG_ON(AR_SREV_9280_20_OR_LATER(ah));
511−
512− ATH_FREE_BANK(ah->analogBank0Data);
513− ATH_FREE_BANK(ah->analogBank1Data);
514− ATH_FREE_BANK(ah->analogBank2Data);
515− ATH_FREE_BANK(ah->analogBank3Data);
516− ATH_FREE_BANK(ah->analogBank6Data);
517− ATH_FREE_BANK(ah->analogBank6TPCData);
518− ATH_FREE_BANK(ah->analogBank7Data);
519− ATH_FREE_BANK(ah->bank6Temp);
520−
521−#undef ATH_FREE_BANK
522−}
523−
524500 /* *
525501 * ar5008_hw_set_rf_regs - programs rf registers based on EEPROM
526502 * @ah: atheros hardware structure
@@ -1380,7 +1356,7 @@ static void ar5008_hw_set_radar_conf(struct ath_hw *ah) · 853 unmodified lines
13801356 conf->radar_inband = 8;
13811357 }
13821358
1383−void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
1359+int ar5008_hw_attach_phy_ops(struct ath_hw *ah)
13841360 {
13851361 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
13861362 static const u32 ar5416_cca_regs[6] = {
@@ -1391,12 +1367,15 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah) · 4 unmodified lines
13911367 AR_PHY_CH1_EXT_CCA,
13921368 AR_PHY_CH2_EXT_CCA
13931369 };
1370+ int ret;
1371+
1372+ ret = ar5008_hw_rf_alloc_ext_banks(ah);
1373+ if (ret)
1374+ return ret;
13941375
13951376 priv_ops->rf_set_freq = ar5008_hw_set_channel;
13961377 priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate;
13971378
1398− priv_ops->rf_alloc_ext_banks = ar5008_hw_rf_alloc_ext_banks;
1399− priv_ops->rf_free_ext_banks = ar5008_hw_rf_free_ext_banks;
14001379 priv_ops->set_rf_regs = ar5008_hw_set_rf_regs;
14011380 priv_ops->set_channel_regs = ar5008_hw_set_channel_regs;
14021381 priv_ops->init_bb = ar5008_hw_init_bb;
@@ -1421,4 +1400,5 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah) · 18 unmodified lines
14211400 ar5008_hw_set_nf_limits(ah);
14221401 ar5008_hw_set_radar_conf(ah);
14231402 memcpy(ah->nf_regs, ar5416_cca_regs, sizeof(ah->nf_regs));
1403+ return 0;
14241404 }
drivers/net/wireless/ath/ath9k/ar9001_initvals.h+2−2
@@ -460,7 +460,7 @@ static const u32 ar5416Common_9100[][2] = { · 459 unmodified lines
460460 };
461461
462462 static const u32 ar5416Bank6_9100[][3] = {
463− /* Addr 5G_HT20 5G_HT40 */
463+ /* Addr 5G 2G */
464464 {0x0000989c, 0x00000000, 0x00000000},
465465 {0x0000989c, 0x00000000, 0x00000000},
466466 {0x0000989c, 0x00000000, 0x00000000},
@@ -497,7 +497,7 @@ static const u32 ar5416Bank6_9100[][3] = { · 30 unmodified lines
497497 };
498498
499499 static const u32 ar5416Bank6TPC_9100[][3] = {
500− /* Addr 5G_HT20 5G_HT40 */
500+ /* Addr 5G 2G */
501501 {0x0000989c, 0x00000000, 0x00000000},
502502 {0x0000989c, 0x00000000, 0x00000000},
503503 {0x0000989c, 0x00000000, 0x00000000},
drivers/net/wireless/ath/ath9k/ar9002_hw.c+16−7
@@ -23,13 +23,13 @@ · 22 unmodified lines
2323
2424 /* General hardware code for the A5008/AR9001/AR9002 hadware families */
2525
26−static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
26+static int ar9002_hw_init_mode_regs(struct ath_hw *ah)
2727 {
2828 if (AR_SREV_9271(ah)) {
2929 INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271);
3030 INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271);
3131 INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg);
32− return;
32+ return 0;
3333 }
3434
3535 if (ah->config.pcie_clock_req)
@@ -102,9 +102,9 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) · 66 unmodified lines
102102 u32 size = sizeof(u32) * addac->ia_rows * addac->ia_columns;
103103 u32 *data;
104104
105− data = kmalloc(size, GFP_KERNEL);
105+ data = devm_kzalloc(ah->dev, size, GFP_KERNEL);
106106 if (!data)
107− return;
107+ return -ENOMEM;
108108
109109 memcpy(data, addac->ia_array, size);
110110 addac->ia_array = data;
@@ -120,6 +120,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) · 9 unmodified lines
120120 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
121121 ar9287Common_japan_2484_cck_fir_coeff_9287_1_1);
122122 }
123+ return 0;
123124 }
124125
125126 static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah)
@@ -409,22 +410,30 @@ void ar9002_hw_enable_async_fifo(struct ath_hw *ah) · 283 unmodified lines
409410 }
410411
411412 /* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
412−void ar9002_hw_attach_ops(struct ath_hw *ah)
413+int ar9002_hw_attach_ops(struct ath_hw *ah)
413414 {
414415 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
415416 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
417+ int ret;
418+
419+ ret = ar9002_hw_init_mode_regs(ah);
420+ if (ret)
421+ return ret;
416422
417− priv_ops->init_mode_regs = ar9002_hw_init_mode_regs;
418423 priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs;
419424
420425 ops->config_pci_powersave = ar9002_hw_configpcipowersave;
421426
422− ar5008_hw_attach_phy_ops(ah);
427+ ret = ar5008_hw_attach_phy_ops(ah);
428+ if (ret)
429+ return ret;
430+
423431 if (AR_SREV_9280_20_OR_LATER(ah))
424432 ar9002_hw_attach_phy_ops(ah);
425433
426434 ar9002_hw_attach_calib_ops(ah);
427435 ar9002_hw_attach_mac_ops(ah);
436+ return 0;
428437 }
429438
430439 void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan)
drivers/net/wireless/ath/ath9k/ar9002_phy.c+64−2
@@ -555,14 +555,73 @@ static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw *ah, · 554 unmodified lines
555555 REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval);
556556 }
557557
558+static void ar9002_hw_spectral_scan_config(struct ath_hw *ah,
559+ struct ath_spec_scan *param)
560+{
561+ u8 count;
562+
563+ if (!param->enabled) {
564+ REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN,
565+ AR_PHY_SPECTRAL_SCAN_ENABLE);
566+ return;
567+ }
568+ REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_FFT_ENA);
569+ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE);
570+
571+ if (param->short_repeat)
572+ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
573+ AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);
574+ else
575+ REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN,
576+ AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);
577+
578+ /* on AR92xx, the highest bit of count will make the the chip send
579+ * spectral samples endlessly. Check if this really was intended,
580+ * and fix otherwise.
581+ */
582+ count = param->count;
583+ if (param->endless)
584+ count = 0x80;
585+ else if (count & 0x80)
586+ count = 0x7f;
587+
588+ REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
589+ AR_PHY_SPECTRAL_SCAN_COUNT, count);
590+ REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
591+ AR_PHY_SPECTRAL_SCAN_PERIOD, param->period);
592+ REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
593+ AR_PHY_SPECTRAL_SCAN_FFT_PERIOD, param->fft_period);
594+
595+ return;
596+}
597+
598+static void ar9002_hw_spectral_scan_trigger(struct ath_hw *ah)
599+{
600+ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE);
601+ /* Activate spectral scan */
602+ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
603+ AR_PHY_SPECTRAL_SCAN_ACTIVE);
604+}
605+
606+static void ar9002_hw_spectral_scan_wait(struct ath_hw *ah)
607+{
608+ struct ath_common *common = ath9k_hw_common(ah);
609+
610+ /* Poll for spectral scan complete */
611+ if (!ath9k_hw_wait(ah, AR_PHY_SPECTRAL_SCAN,
612+ AR_PHY_SPECTRAL_SCAN_ACTIVE,
613+ 0, AH_WAIT_TIMEOUT)) {
614+ ath_err(common, "spectral scan wait failed\n");
615+ return;
616+ }
617+}
618+
558619 void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
559620 {
560621 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
561622 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
562623
563624 priv_ops->set_rf_regs = NULL;
564− priv_ops->rf_alloc_ext_banks = NULL;
565− priv_ops->rf_free_ext_banks = NULL;
566625 priv_ops->rf_set_freq = ar9002_hw_set_channel;
567626 priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate;
568627 priv_ops->olc_init = ar9002_olc_init;
@@ -571,6 +630,9 @@ void ar9002_hw_attach_phy_ops(struct ath_hw *ah) · 2 unmodified lines
571630
572631 ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get;
573632 ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set;
633+ ops->spectral_scan_config = ar9002_hw_spectral_scan_config;
634+ ops->spectral_scan_trigger = ar9002_hw_spectral_scan_trigger;
635+ ops->spectral_scan_wait = ar9002_hw_spectral_scan_wait;
574636
575637 ar9002_hw_set_nf_limits(ah);
576638 }
drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h+180−0
@@ -744,6 +744,186 @@ static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { · 743 unmodified lines
744744 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
745745 };
746746
747+static const u32 ar9300Modes_mixed_ob_db_tx_gain_table_2p2[][5] = {
748+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
749+ {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
750+ {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
751+ {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
752+ {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
753+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
754+ {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
755+ {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
756+ {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
757+ {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
758+ {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
759+ {0x0000a514, 0x1c000223, 0x1c000223, 0x11000400, 0x11000400},
760+ {0x0000a518, 0x21002220, 0x21002220, 0x15000402, 0x15000402},
761+ {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
762+ {0x0000a520, 0x2b022220, 0x2b022220, 0x1b000603, 0x1b000603},
763+ {0x0000a524, 0x2f022222, 0x2f022222, 0x1f000a02, 0x1f000a02},
764+ {0x0000a528, 0x34022225, 0x34022225, 0x23000a04, 0x23000a04},
765+ {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x26000a20, 0x26000a20},
766+ {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2a000e20, 0x2a000e20},
767+ {0x0000a534, 0x4202242a, 0x4202242a, 0x2e000e22, 0x2e000e22},
768+ {0x0000a538, 0x4702244a, 0x4702244a, 0x31000e24, 0x31000e24},
769+ {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x34001640, 0x34001640},
770+ {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660},
771+ {0x0000a544, 0x52022470, 0x52022470, 0x3b001861, 0x3b001861},
772+ {0x0000a548, 0x55022490, 0x55022490, 0x3e001a81, 0x3e001a81},
773+ {0x0000a54c, 0x59022492, 0x59022492, 0x42001a83, 0x42001a83},
774+ {0x0000a550, 0x5d022692, 0x5d022692, 0x44001c84, 0x44001c84},
775+ {0x0000a554, 0x61022892, 0x61022892, 0x48001ce3, 0x48001ce3},
776+ {0x0000a558, 0x65024890, 0x65024890, 0x4c001ce5, 0x4c001ce5},
777+ {0x0000a55c, 0x69024892, 0x69024892, 0x50001ce9, 0x50001ce9},
778+ {0x0000a560, 0x6e024c92, 0x6e024c92, 0x54001ceb, 0x54001ceb},
779+ {0x0000a564, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
780+ {0x0000a568, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
781+ {0x0000a56c, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
782+ {0x0000a570, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
783+ {0x0000a574, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
784+ {0x0000a578, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
785+ {0x0000a57c, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
786+ {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
787+ {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
788+ {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
789+ {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
790+ {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
791+ {0x0000a594, 0x1c800223, 0x1c800223, 0x11800400, 0x11800400},
792+ {0x0000a598, 0x21802220, 0x21802220, 0x15800402, 0x15800402},
793+ {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404},
794+ {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800603, 0x1b800603},
795+ {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800a02, 0x1f800a02},
796+ {0x0000a5a8, 0x34822225, 0x34822225, 0x23800a04, 0x23800a04},
797+ {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x26800a20, 0x26800a20},
798+ {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2a800e20, 0x2a800e20},
799+ {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2e800e22, 0x2e800e22},
800+ {0x0000a5b8, 0x4782244a, 0x4782244a, 0x31800e24, 0x31800e24},
801+ {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x34801640, 0x34801640},
802+ {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38801660, 0x38801660},
803+ {0x0000a5c4, 0x52822470, 0x52822470, 0x3b801861, 0x3b801861},
804+ {0x0000a5c8, 0x55822490, 0x55822490, 0x3e801a81, 0x3e801a81},
805+ {0x0000a5cc, 0x59822492, 0x59822492, 0x42801a83, 0x42801a83},
806+ {0x0000a5d0, 0x5d822692, 0x5d822692, 0x44801c84, 0x44801c84},
807+ {0x0000a5d4, 0x61822892, 0x61822892, 0x48801ce3, 0x48801ce3},
808+ {0x0000a5d8, 0x65824890, 0x65824890, 0x4c801ce5, 0x4c801ce5},
809+ {0x0000a5dc, 0x69824892, 0x69824892, 0x50801ce9, 0x50801ce9},
810+ {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x54801ceb, 0x54801ceb},
811+ {0x0000a5e4, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
812+ {0x0000a5e8, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
813+ {0x0000a5ec, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
814+ {0x0000a5f0, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
815+ {0x0000a5f4, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
816+ {0x0000a5f8, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
817+ {0x0000a5fc, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
818+ {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
819+ {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
820+ {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
821+ {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
822+ {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
823+ {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
824+ {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
825+ {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
826+ {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
827+ {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
828+ {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
829+ {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
830+ {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
831+ {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
832+ {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
833+ {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
834+ {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
835+ {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
836+ {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
837+ {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
838+ {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
839+ {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
840+ {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
841+ {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
842+ {0x00016044, 0x012492d4, 0x012492d4, 0x056db2e4, 0x056db2e4},
843+ {0x00016048, 0x66480001, 0x66480001, 0x8e480001, 0x8e480001},
844+ {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
845+ {0x00016444, 0x012492d4, 0x012492d4, 0x056db2e4, 0x056db2e4},
846+ {0x00016448, 0x66480001, 0x66480001, 0x8e480001, 0x8e480001},
847+ {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
848+ {0x00016844, 0x012492d4, 0x012492d4, 0x056db2e4, 0x056db2e4},
849+ {0x00016848, 0x66480001, 0x66480001, 0x8e480001, 0x8e480001},
850+ {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
851+};
852+
853+static const u32 ar9300Modes_type5_tx_gain_table_2p2[][5] = {
854+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
855+ {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
856+ {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
857+ {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
858+ {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
859+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
860+ {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
861+ {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
862+ {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
863+ {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
864+ {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202},
865+ {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400},
866+ {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402},
867+ {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404},
868+ {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603},
869+ {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02},
870+ {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04},
871+ {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20},
872+ {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20},
873+ {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22},
874+ {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24},
875+ {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640},
876+ {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660},
877+ {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861},
878+ {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81},
879+ {0x0000a54c, 0x5e08442e, 0x5e08442e, 0x47001a83, 0x47001a83},
880+ {0x0000a550, 0x620a4431, 0x620a4431, 0x4a001c84, 0x4a001c84},
881+ {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3},
882+ {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5},
883+ {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9},
884+ {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb},
885+ {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
886+ {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
887+ {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
888+ {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
889+ {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
890+ {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
891+ {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
892+ {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
893+ {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
894+ {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
895+ {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
896+ {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
897+ {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000},
898+ {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501},
899+ {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501},
900+ {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03},
901+ {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
902+ {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04},
903+ {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
904+ {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
905+ {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
906+ {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
907+ {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
908+ {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
909+ {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
910+ {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
911+ {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
912+ {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
913+ {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
914+ {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
915+ {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
916+ {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
917+ {0x00016048, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
918+ {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
919+ {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
920+ {0x00016448, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
921+ {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
922+ {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
923+ {0x00016848, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
924+ {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
925+};
926+
747927 static const u32 ar9300Common_rx_gain_table_2p2[][2] = {
748928 /* Addr allmodes */
749929 {0x0000a000, 0x00010000},
drivers/net/wireless/ath/ath9k/ar9003_calib.c+78−67
@@ -32,7 +32,6 @@ struct coeff { · 31 unmodified lines
3232
3333 enum ar9003_cal_types {
3434 IQ_MISMATCH_CAL = BIT(0),
35− TEMP_COMP_CAL = BIT(1),
3635 };
3736
3837 static void ar9003_hw_setup_calibration(struct ath_hw *ah,
@@ -49,7 +48,7 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah, · 10 unmodified lines
4948 */
5049 REG_RMW_FIELD(ah, AR_PHY_TIMING4,
5150 AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX,
52− currCal->calData->calCountMax);
51+ currCal->calData->calCountMax);
5352 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
5453
5554 ath_dbg(common, CALIBRATE,
@@ -58,14 +57,8 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah, · 2 unmodified lines
5857 /* Kick-off cal */
5958 REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
6059 break;
61− case TEMP_COMP_CAL:
62− REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM,
63− AR_PHY_65NM_CH0_THERM_LOCAL, 1);
64− REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM,
65− AR_PHY_65NM_CH0_THERM_START, 1);
66−
67− ath_dbg(common, CALIBRATE,
68− "starting Temperature Compensation Calibration\n");
60+ default:
61+ ath_err(common, "Invalid calibration type\n");
6962 break;
7063 }
7164 }
@@ -323,6 +316,14 @@ static const struct ath9k_percal_data iq_cal_single_sample = { · 251 unmodified lines
323316 static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
324317 {
325318 ah->iq_caldata.calData = &iq_cal_single_sample;
319+
320+ if (AR_SREV_9300_20_OR_LATER(ah)) {
321+ ah->enabled_cals |= TX_IQ_CAL;
322+ if (AR_SREV_9485_OR_LATER(ah) && !AR_SREV_9340(ah))
323+ ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
324+ }
325+
326+ ah->supp_cals = IQ_MISMATCH_CAL;
326327 }
327328
328329 /*
@@ -959,22 +960,70 @@ static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g) · 630 unmodified lines
959960 AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0);
960961 }
961962
963+static void ar9003_hw_do_manual_peak_cal(struct ath_hw *ah,
964+ struct ath9k_channel *chan)
965+{
966+ int i;
967+
968+ if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah))
969+ return;
970+
971+ for (i = 0; i < AR9300_MAX_CHAINS; i++) {
972+ if (!(ah->rxchainmask & (1 << i)))
973+ continue;
974+ ar9003_hw_manual_peak_cal(ah, i, IS_CHAN_2GHZ(chan));
975+ }
976+}
977+
978+static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable)
979+{
980+ u32 cl_idx[AR9300_MAX_CHAINS] = { AR_PHY_CL_TAB_0,
981+ AR_PHY_CL_TAB_1,
982+ AR_PHY_CL_TAB_2 };
983+ struct ath9k_hw_cal_data *caldata = ah->caldata;
984+ bool txclcal_done = false;
985+ int i, j;
986+
987+ if (!caldata || !(ah->enabled_cals & TX_CL_CAL))
988+ return;
989+
990+ txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) &
991+ AR_PHY_AGC_CONTROL_CLC_SUCCESS);
992+
993+ if (caldata->done_txclcal_once) {
994+ for (i = 0; i < AR9300_MAX_CHAINS; i++) {
995+ if (!(ah->txchainmask & (1 << i)))
996+ continue;
997+ for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
998+ REG_WRITE(ah, CL_TAB_ENTRY(cl_idx[i]),
999+ caldata->tx_clcal[i][j]);
1000+ }
1001+ } else if (is_reusable && txclcal_done) {
1002+ for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1003+ if (!(ah->txchainmask & (1 << i)))
1004+ continue;
1005+ for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
1006+ caldata->tx_clcal[i][j] =
1007+ REG_READ(ah, CL_TAB_ENTRY(cl_idx[i]));
1008+ }
1009+ caldata->done_txclcal_once = true;
1010+ }
1011+}
1012+
9621013 static bool ar9003_hw_init_cal(struct ath_hw *ah,
9631014 struct ath9k_channel *chan)
9641015 {
9651016 struct ath_common *common = ath9k_hw_common(ah);
9661017 struct ath9k_hw_cal_data *caldata = ah->caldata;
967− bool txiqcal_done = false, txclcal_done = false;
1018+ bool txiqcal_done = false;
9681019 bool is_reusable = true, status = true;
969− bool run_rtt_cal = false, run_agc_cal;
1020+ bool run_rtt_cal = false, run_agc_cal, sep_iq_cal = false;
9701021 bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT);
9711022 u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL |
9721023 AR_PHY_AGC_CONTROL_FLTR_CAL |
9731024 AR_PHY_AGC_CONTROL_PKDET_CAL;
974− int i, j;
975− u32 cl_idx[AR9300_MAX_CHAINS] = { AR_PHY_CL_TAB_0,
976− AR_PHY_CL_TAB_1,
977− AR_PHY_CL_TAB_2 };
1025+
1026+ ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
9781027
9791028 if (rtt) {
9801029 if (!ar9003_hw_rtt_restore(ah, chan))
@@ -1012,7 +1061,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, · 31 unmodified lines
10121061 }
10131062 }
10141063
1015− if (!(ah->enabled_cals & TX_IQ_CAL))
1064+ if ((IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) ||
1065+ !(ah->enabled_cals & TX_IQ_CAL))
10161066 goto skip_tx_iqcal;
10171067
10181068 /* Do Tx IQ Calibration */
@@ -1032,21 +1082,22 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, · 13 unmodified lines
10321082 REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
10331083 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
10341084 txiqcal_done = run_agc_cal = true;
1035− goto skip_tx_iqcal;
1036− } else if (caldata && !caldata->done_txiqcal_once)
1085+ } else if (caldata && !caldata->done_txiqcal_once) {
10371086 run_agc_cal = true;
1087+ sep_iq_cal = true;
1088+ }
10381089
1090+skip_tx_iqcal:
10391091 if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
10401092 ar9003_mci_init_cal_req(ah, &is_reusable);
10411093
1042− if (!(IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))) {
1094+ if (sep_iq_cal) {
10431095 txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
10441096 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
10451097 udelay(5);
10461098 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
10471099 }
10481100
1049−skip_tx_iqcal:
10501101 if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
10511102 /* Calibrate the AGC */
10521103 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
@@ -1057,14 +1108,8 @@ skip_tx_iqcal: · 4 unmodified lines
10571108 status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
10581109 AR_PHY_AGC_CONTROL_CAL,
10591110 0, AH_WAIT_TIMEOUT);
1060− if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
1061− for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1062− if (!(ah->rxchainmask & (1 << i)))
1063− continue;
1064− ar9003_hw_manual_peak_cal(ah, i,
1065− IS_CHAN_2GHZ(chan));
1066− }
1067− }
1111+
1112+ ar9003_hw_do_manual_peak_cal(ah, chan);
10681113 }
10691114
10701115 if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
@@ -1089,31 +1134,7 @@ skip_tx_iqcal: · 18 unmodified lines
10891134 else if (caldata && caldata->done_txiqcal_once)
10901135 ar9003_hw_tx_iq_cal_reload(ah);
10911136
1092−#define CL_TAB_ENTRY(reg_base) (reg_base + (4 * j))
1093− if (caldata && (ah->enabled_cals & TX_CL_CAL)) {
1094− txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) &
1095− AR_PHY_AGC_CONTROL_CLC_SUCCESS);
1096− if (caldata->done_txclcal_once) {
1097− for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1098− if (!(ah->txchainmask & (1 << i)))
1099− continue;
1100− for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
1101− REG_WRITE(ah, CL_TAB_ENTRY(cl_idx[i]),
1102− caldata->tx_clcal[i][j]);
1103− }
1104− } else if (is_reusable && txclcal_done) {
1105− for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1106− if (!(ah->txchainmask & (1 << i)))
1107− continue;
1108− for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
1109− caldata->tx_clcal[i][j] =
1110− REG_READ(ah,
1111− CL_TAB_ENTRY(cl_idx[i]));
1112− }
1113− caldata->done_txclcal_once = true;
1114− }
1115− }
1116−#undef CL_TAB_ENTRY
1137+ ar9003_hw_cl_cal_post_proc(ah, is_reusable);
11171138
11181139 if (run_rtt_cal && caldata) {
11191140 if (is_reusable) {
@@ -1131,20 +1152,10 @@ skip_tx_iqcal: · 11 unmodified lines
11311152
11321153 /* Initialize list pointers */
11331154 ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
1134− ah->supp_cals = IQ_MISMATCH_CAL;
1135−
1136− if (ah->supp_cals & IQ_MISMATCH_CAL) {
1137− INIT_CAL(&ah->iq_caldata);
1138− INSERT_CAL(ah, &ah->iq_caldata);
1139− ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n");
1140− }
11411155
1142− if (ah->supp_cals & TEMP_COMP_CAL) {
1143− INIT_CAL(&ah->tempCompCalData);
1144− INSERT_CAL(ah, &ah->tempCompCalData);
1145− ath_dbg(common, CALIBRATE,
1146− "enabling Temperature Compensation Calibration\n");
1147− }
1156+ INIT_CAL(&ah->iq_caldata);
1157+ INSERT_CAL(ah, &ah->iq_caldata);
1158+ ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n");
11481159
11491160 /* Initialize current pointer to first element in list */
11501161 ah->cal_list_curr = ah->cal_list;
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c+99−29
@@ -4586,14 +4586,14 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah, · 4585 unmodified lines
45864586 return 0;
45874587 }
45884588
4589−static int ar9003_hw_power_control_override(struct ath_hw *ah,
4590− int frequency,
4591− int *correction,
4592− int *voltage, int *temperature)
4589+static void ar9003_hw_power_control_override(struct ath_hw *ah,
4590+ int frequency,
4591+ int *correction,
4592+ int *voltage, int *temperature)
45934593 {
4594− int tempSlope = 0;
4594+ int temp_slope = 0, temp_slope1 = 0, temp_slope2 = 0;
45954595 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4596− int f[8], t[8], i;
4596+ int f[8], t[8], t1[3], t2[3], i;
45974597
45984598 REG_RMW(ah, AR_PHY_TPC_11_B0,
45994599 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
@@ -4624,38 +4624,108 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah, · 24 unmodified lines
46244624 * enable temperature compensation
46254625 * Need to use register names
46264626 */
4627− if (frequency < 4000)
4628− tempSlope = eep->modalHeader2G.tempSlope;
4629− else if ((eep->baseEepHeader.miscConfiguration & 0x20) != 0) {
4630− for (i = 0; i < 8; i++) {
4631− t[i] = eep->base_ext1.tempslopextension[i];
4632− f[i] = FBIN2FREQ(eep->calFreqPier5G[i], 0);
4627+ if (frequency < 4000) {
4628+ temp_slope = eep->modalHeader2G.tempSlope;
4629+ } else {
4630+ if (AR_SREV_9550(ah)) {
4631+ t[0] = eep->base_ext1.tempslopextension[2];
4632+ t1[0] = eep->base_ext1.tempslopextension[3];
4633+ t2[0] = eep->base_ext1.tempslopextension[4];
4634+ f[0] = 5180;
4635+
4636+ t[1] = eep->modalHeader5G.tempSlope;
4637+ t1[1] = eep->base_ext1.tempslopextension[0];
4638+ t2[1] = eep->base_ext1.tempslopextension[1];
4639+ f[1] = 5500;
4640+
4641+ t[2] = eep->base_ext1.tempslopextension[5];
4642+ t1[2] = eep->base_ext1.tempslopextension[6];
4643+ t2[2] = eep->base_ext1.tempslopextension[7];
4644+ f[2] = 5785;
4645+
4646+ temp_slope = ar9003_hw_power_interpolate(frequency,
4647+ f, t, 3);
4648+ temp_slope1 = ar9003_hw_power_interpolate(frequency,
4649+ f, t1, 3);
4650+ temp_slope2 = ar9003_hw_power_interpolate(frequency,
4651+ f, t2, 3);
4652+
4653+ goto tempslope;
46334654 }
4634− tempSlope = ar9003_hw_power_interpolate((s32) frequency,
4635− f, t, 8);
4636− } else if (eep->base_ext2.tempSlopeLow != 0) {
4637− t[0] = eep->base_ext2.tempSlopeLow;
4638− f[0] = 5180;
4639− t[1] = eep->modalHeader5G.tempSlope;
4640− f[1] = 5500;
4641− t[2] = eep->base_ext2.tempSlopeHigh;
4642− f[2] = 5785;
4643− tempSlope = ar9003_hw_power_interpolate((s32) frequency,
4644− f, t, 3);
4645− } else
4646− tempSlope = eep->modalHeader5G.tempSlope;
46474655
4648− REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
4656+ if ((eep->baseEepHeader.miscConfiguration & 0x20) != 0) {
4657+ for (i = 0; i < 8; i++) {
4658+ t[i] = eep->base_ext1.tempslopextension[i];
4659+ f[i] = FBIN2FREQ(eep->calFreqPier5G[i], 0);
4660+ }
4661+ temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4662+ f, t, 8);
4663+ } else if (eep->base_ext2.tempSlopeLow != 0) {
4664+ t[0] = eep->base_ext2.tempSlopeLow;
4665+ f[0] = 5180;
4666+ t[1] = eep->modalHeader5G.tempSlope;
4667+ f[1] = 5500;
4668+ t[2] = eep->base_ext2.tempSlopeHigh;
4669+ f[2] = 5785;
4670+ temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4671+ f, t, 3);
4672+ } else {
4673+ temp_slope = eep->modalHeader5G.tempSlope;
4674+ }
4675+ }
4676+
4677+tempslope:
4678+ if (AR_SREV_9550(ah)) {
4679+ /*
4680+ * AR955x has tempSlope register for each chain.
4681+ * Check whether temp_compensation feature is enabled or not.
4682+ */
4683+ if (eep->baseEepHeader.featureEnable & 0x1) {
4684+ if (frequency < 4000) {
4685+ REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4686+ AR_PHY_TPC_19_ALPHA_THERM,
4687+ eep->base_ext2.tempSlopeLow);
4688+ REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4689+ AR_PHY_TPC_19_ALPHA_THERM,
4690+ temp_slope);
4691+ REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4692+ AR_PHY_TPC_19_ALPHA_THERM,
4693+ eep->base_ext2.tempSlopeHigh);
4694+ } else {
4695+ REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4696+ AR_PHY_TPC_19_ALPHA_THERM,
4697+ temp_slope);
4698+ REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4699+ AR_PHY_TPC_19_ALPHA_THERM,
4700+ temp_slope1);
4701+ REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4702+ AR_PHY_TPC_19_ALPHA_THERM,
4703+ temp_slope2);
4704+ }
4705+ } else {
4706+ /*
4707+ * If temp compensation is not enabled,
4708+ * set all registers to 0.
4709+ */
4710+ REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4711+ AR_PHY_TPC_19_ALPHA_THERM, 0);
4712+ REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4713+ AR_PHY_TPC_19_ALPHA_THERM, 0);
4714+ REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4715+ AR_PHY_TPC_19_ALPHA_THERM, 0);
4716+ }
4717+ } else {
4718+ REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4719+ AR_PHY_TPC_19_ALPHA_THERM, temp_slope);
4720+ }
46494721
46504722 if (AR_SREV_9462_20(ah))
46514723 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4652− AR_PHY_TPC_19_B1_ALPHA_THERM, tempSlope);
4724+ AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope);
46534725
46544726
46554727 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
46564728 temperature[0]);
4657−
4658− return 0;
46594729 }
46604730
46614731 /* Apply the recorded correction values. */
drivers/net/wireless/ath/ath9k/ar9003_hw.c+51−20
@@ -507,28 +507,59 @@ static void ar9003_tx_gain_table_mode4(struct ath_hw *ah) · 506 unmodified lines
507507 else if (AR_SREV_9580(ah))
508508 INIT_INI_ARRAY(&ah->iniModesTxGain,
509509 ar9580_1p0_mixed_ob_db_tx_gain_table);
510+ else
511+ INIT_INI_ARRAY(&ah->iniModesTxGain,
512+ ar9300Modes_mixed_ob_db_tx_gain_table_2p2);
513+}
514+
515+static void ar9003_tx_gain_table_mode5(struct ath_hw *ah)
516+{
517+ if (AR_SREV_9485_11(ah))
518+ INIT_INI_ARRAY(&ah->iniModesTxGain,
519+ ar9485Modes_green_ob_db_tx_gain_1_1);
520+ else if (AR_SREV_9340(ah))
521+ INIT_INI_ARRAY(&ah->iniModesTxGain,
522+ ar9340Modes_ub124_tx_gain_table_1p0);
523+ else if (AR_SREV_9580(ah))
524+ INIT_INI_ARRAY(&ah->iniModesTxGain,
525+ ar9580_1p0_type5_tx_gain_table);
526+ else if (AR_SREV_9300_22(ah))
527+ INIT_INI_ARRAY(&ah->iniModesTxGain,
528+ ar9300Modes_type5_tx_gain_table_2p2);
529+}
530+
531+static void ar9003_tx_gain_table_mode6(struct ath_hw *ah)
532+{
533+ if (AR_SREV_9340(ah))
534+ INIT_INI_ARRAY(&ah->iniModesTxGain,
535+ ar9340Modes_low_ob_db_and_spur_tx_gain_table_1p0);
536+ else if (AR_SREV_9485_11(ah))
537+ INIT_INI_ARRAY(&ah->iniModesTxGain,
538+ ar9485Modes_green_spur_ob_db_tx_gain_1_1);
539+ else if (AR_SREV_9580(ah))
540+ INIT_INI_ARRAY(&ah->iniModesTxGain,
541+ ar9580_1p0_type6_tx_gain_table);
510542 }
511543
544+typedef void (*ath_txgain_tab)(struct ath_hw *ah);
545+
512546 static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
513547 {
514− switch (ar9003_hw_get_tx_gain_idx(ah)) {
515− case 0:
516− default:
517− ar9003_tx_gain_table_mode0(ah);
518− break;
519− case 1:
520− ar9003_tx_gain_table_mode1(ah);
521− break;
522− case 2:
523− ar9003_tx_gain_table_mode2(ah);
524− break;
525− case 3:
526− ar9003_tx_gain_table_mode3(ah);
527− break;
528− case 4:
529− ar9003_tx_gain_table_mode4(ah);
530− break;
531− }
548+ static const ath_txgain_tab modes[] = {
549+ ar9003_tx_gain_table_mode0,
550+ ar9003_tx_gain_table_mode1,
551+ ar9003_tx_gain_table_mode2,
552+ ar9003_tx_gain_table_mode3,
553+ ar9003_tx_gain_table_mode4,
554+ ar9003_tx_gain_table_mode5,
555+ ar9003_tx_gain_table_mode6,
556+ };
557+ int idx = ar9003_hw_get_tx_gain_idx(ah);
558+
559+ if (idx >= ARRAY_SIZE(modes))
560+ idx = 0;
561+
562+ modes[idx](ah);
532563 }
533564
534565 static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
@@ -544,7 +575,7 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah) · 9 unmodified lines
544575 ar9340Common_rx_gain_table_1p0);
545576 else if (AR_SREV_9485_11(ah))
546577 INIT_INI_ARRAY(&ah->iniModesRxGain,
547− ar9485Common_wo_xlna_rx_gain_1_1);
578+ ar9485_common_rx_gain_1_1);
548579 else if (AR_SREV_9550(ah)) {
549580 INIT_INI_ARRAY(&ah->iniModesRxGain,
550581 ar955x_1p0_common_rx_gain_table);
@@ -673,7 +704,7 @@ void ar9003_hw_attach_ops(struct ath_hw *ah) · 122 unmodified lines
673704 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
674705 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
675706
676− priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
707+ ar9003_hw_init_mode_regs(ah);
677708 priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
678709
679710 ops->config_pci_powersave = ar9003_hw_configpcipowersave;
drivers/net/wireless/ath/ath9k/ar9003_phy.c+88−34
@@ -68,7 +68,7 @@ static const int m2ThreshExt_off = 127; · 67 unmodified lines
6868 static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
6969 {
7070 u16 bMode, fracMode = 0, aModeRefSel = 0;
71− u32 freq, channelSel = 0, reg32 = 0;
71+ u32 freq, chan_frac, div, channelSel = 0, reg32 = 0;
7272 struct chan_centers centers;
7373 int loadSynthChannel;
7474
@@ -77,9 +77,6 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) · 2 unmodified lines
7777
7878 if (freq < 4800) { /* 2 GHz, fractional mode */
7979 if (AR_SREV_9330(ah)) {
80− u32 chan_frac;
81− u32 div;
82−
8380 if (ah->is_clk_25mhz)
8481 div = 75;
8582 else
@@ -89,34 +86,40 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) · 3 unmodified lines
8986 chan_frac = (((freq * 4) % div) * 0x20000) / div;
9087 channelSel = (channelSel << 17) | chan_frac;
9188 } else if (AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
92− u32 chan_frac;
93−
9489 /*
95− * freq_ref = 40 / (refdiva >> amoderefsel); where refdiva=1 and amoderefsel=0
90+ * freq_ref = 40 / (refdiva >> amoderefsel);
91+ * where refdiva=1 and amoderefsel=0
9692 * ndiv = ((chan_mhz * 4) / 3) / freq_ref;
9793 * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000
9894 */
9995 channelSel = (freq * 4) / 120;
10096 chan_frac = (((freq * 4) % 120) * 0x20000) / 120;
10197 channelSel = (channelSel << 17) | chan_frac;
102− } else if (AR_SREV_9340(ah) || AR_SREV_9550(ah)) {
98+ } else if (AR_SREV_9340(ah)) {
10399 if (ah->is_clk_25mhz) {
104− u32 chan_frac;
105−
106100 channelSel = (freq * 2) / 75;
107101 chan_frac = (((freq * 2) % 75) * 0x20000) / 75;
108102 channelSel = (channelSel << 17) | chan_frac;
109− } else
103+ } else {
110104 channelSel = CHANSEL_2G(freq) >> 1;
111− } else
105+ }
106+ } else if (AR_SREV_9550(ah)) {
107+ if (ah->is_clk_25mhz)
108+ div = 75;
109+ else
110+ div = 120;
111+
112+ channelSel = (freq * 4) / div;
113+ chan_frac = (((freq * 4) % div) * 0x20000) / div;
114+ channelSel = (channelSel << 17) | chan_frac;
115+ } else {
112116 channelSel = CHANSEL_2G(freq);
117+ }
113118 /* Set to 2G mode */
114119 bMode = 1;
115120 } else {
116121 if ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) &&
117122 ah->is_clk_25mhz) {
118− u32 chan_frac;
119−
120123 channelSel = freq / 75;
121124 chan_frac = ((freq % 75) * 0x20000) / 75;
122125 channelSel = (channelSel << 17) | chan_frac;
@@ -586,32 +589,19 @@ static void ar9003_hw_init_bb(struct ath_hw *ah, · 463 unmodified lines
586589 ath9k_hw_synth_delay(ah, chan, synthDelay);
587590 }
588591
589−static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
592+void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
590593 {
591− switch (rx) {
592− case 0x5:
594+ if (ah->caps.tx_chainmask == 5 || ah->caps.rx_chainmask == 5)
593595 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
594596 AR_PHY_SWAP_ALT_CHAIN);
595− case 0x3:
596− case 0x1:
597− case 0x2:
598− case 0x7:
599− REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx);
600− REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);
601− break;
602− default:
603− break;
604− }
597+
598+ REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx);
599+ REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);
605600
606601 if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7))
607− REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
608− else
609− REG_WRITE(ah, AR_SELFGEN_MASK, tx);
602+ tx = 3;
610603
611− if (tx == 0x5) {
612− REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
613− AR_PHY_SWAP_ALT_CHAIN);
614− }
604+ REG_WRITE(ah, AR_SELFGEN_MASK, tx);
615605 }
616606
617607 /*
@@ -1450,6 +1440,67 @@ set_rfmode: · 832 unmodified lines
14501440 return 0;
14511441 }
14521442
1443+static void ar9003_hw_spectral_scan_config(struct ath_hw *ah,
1444+ struct ath_spec_scan *param)
1445+{
1446+ u8 count;
1447+
1448+ if (!param->enabled) {
1449+ REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN,
1450+ AR_PHY_SPECTRAL_SCAN_ENABLE);
1451+ return;
1452+ }
1453+
1454+ REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_FFT_ENA);
1455+ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE);
1456+
1457+ /* on AR93xx and newer, count = 0 will make the the chip send
1458+ * spectral samples endlessly. Check if this really was intended,
1459+ * and fix otherwise.
1460+ */
1461+ count = param->count;
1462+ if (param->endless)
1463+ count = 0;
1464+ else if (param->count == 0)
1465+ count = 1;
1466+
1467+ if (param->short_repeat)
1468+ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
1469+ AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);
1470+ else
1471+ REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN,
1472+ AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);
1473+
1474+ REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
1475+ AR_PHY_SPECTRAL_SCAN_COUNT, count);
1476+ REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
1477+ AR_PHY_SPECTRAL_SCAN_PERIOD, param->period);
1478+ REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
1479+ AR_PHY_SPECTRAL_SCAN_FFT_PERIOD, param->fft_period);
1480+
1481+ return;
1482+}
1483+
1484+static void ar9003_hw_spectral_scan_trigger(struct ath_hw *ah)
1485+{
1486+ /* Activate spectral scan */
1487+ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
1488+ AR_PHY_SPECTRAL_SCAN_ACTIVE);
1489+}
1490+
1491+static void ar9003_hw_spectral_scan_wait(struct ath_hw *ah)
1492+{
1493+ struct ath_common *common = ath9k_hw_common(ah);
1494+
1495+ /* Poll for spectral scan complete */
1496+ if (!ath9k_hw_wait(ah, AR_PHY_SPECTRAL_SCAN,
1497+ AR_PHY_SPECTRAL_SCAN_ACTIVE,
1498+ 0, AH_WAIT_TIMEOUT)) {
1499+ ath_err(common, "spectral scan wait failed\n");
1500+ return;
1501+ }
1502+}
1503+
14531504 void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
14541505 {
14551506 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -1483,6 +1534,9 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah) · 27 unmodified lines
14831534 ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get;
14841535 ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set;
14851536 ops->antctrl_shared_chain_lnadiv = ar9003_hw_antctrl_shared_chain_lnadiv;
1537+ ops->spectral_scan_config = ar9003_hw_spectral_scan_config;
1538+ ops->spectral_scan_trigger = ar9003_hw_spectral_scan_trigger;
1539+ ops->spectral_scan_wait = ar9003_hw_spectral_scan_wait;
14861540
14871541 ar9003_hw_set_nf_limits(ah);
14881542 ar9003_hw_set_radar_conf(ah);
drivers/net/wireless/ath/ath9k/ar9003_phy.h+1−1
@@ -1028,7 +1028,7 @@ · 1027 unmodified lines
10281028 #define AR_PHY_TPC_5_B2 (AR_SM2_BASE + 0x208)
10291029 #define AR_PHY_TPC_6_B2 (AR_SM2_BASE + 0x20c)
10301030 #define AR_PHY_TPC_11_B2 (AR_SM2_BASE + 0x220)
1031−#define AR_PHY_PDADC_TAB_2 (AR_SM2_BASE + 0x240)
1031+#define AR_PHY_TPC_19_B2 (AR_SM2_BASE + 0x240)
10321032 #define AR_PHY_TX_IQCAL_STATUS_B2 (AR_SM2_BASE + 0x48c)
10331033 #define AR_PHY_TX_IQCAL_CORR_COEFF_B2(_i) (AR_SM2_BASE + 0x450 + ((_i) << 2))
10341034
drivers/net/wireless/ath/ath9k/ar9340_initvals.h+100−0
@@ -1172,6 +1172,106 @@ static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = { · 1171 unmodified lines
11721172 {0x00016448, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266},
11731173 };
11741174
1175+static const u32 ar9340Modes_low_ob_db_and_spur_tx_gain_table_1p0[][5] = {
1176+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1177+ {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03eaac5a, 0x03eaac5a},
1178+ {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03f330ac, 0x03f330ac},
1179+ {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc3f00, 0x03fc3f00},
1180+ {0x0000a2e8, 0x00000000, 0x00000000, 0x03ffc000, 0x03ffc000},
1181+ {0x0000a394, 0x00000444, 0x00000444, 0x00000404, 0x00000404},
1182+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
1183+ {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1184+ {0x0000a504, 0x06000003, 0x06000003, 0x02000001, 0x02000001},
1185+ {0x0000a508, 0x0a000020, 0x0a000020, 0x05000003, 0x05000003},
1186+ {0x0000a50c, 0x10000023, 0x10000023, 0x0a000005, 0x0a000005},
1187+ {0x0000a510, 0x16000220, 0x16000220, 0x0e000201, 0x0e000201},
1188+ {0x0000a514, 0x1c000223, 0x1c000223, 0x11000203, 0x11000203},
1189+ {0x0000a518, 0x21002220, 0x21002220, 0x14000401, 0x14000401},
1190+ {0x0000a51c, 0x27002223, 0x27002223, 0x18000403, 0x18000403},
1191+ {0x0000a520, 0x2b022220, 0x2b022220, 0x1b000602, 0x1b000602},
1192+ {0x0000a524, 0x2f022222, 0x2f022222, 0x1f000802, 0x1f000802},
1193+ {0x0000a528, 0x34022225, 0x34022225, 0x21000620, 0x21000620},
1194+ {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x25000820, 0x25000820},
1195+ {0x0000a530, 0x3e02222c, 0x3e02222c, 0x29000822, 0x29000822},
1196+ {0x0000a534, 0x4202242a, 0x4202242a, 0x2d000824, 0x2d000824},
1197+ {0x0000a538, 0x4702244a, 0x4702244a, 0x30000828, 0x30000828},
1198+ {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x3400082a, 0x3400082a},
1199+ {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38000849, 0x38000849},
1200+ {0x0000a544, 0x5302266c, 0x5302266c, 0x3b000a2c, 0x3b000a2c},
1201+ {0x0000a548, 0x5702286c, 0x5702286c, 0x3e000e2b, 0x3e000e2b},
1202+ {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x42000e2d, 0x42000e2d},
1203+ {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4500124a, 0x4500124a},
1204+ {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4900124c, 0x4900124c},
1205+ {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x4c00126c, 0x4c00126c},
1206+ {0x0000a55c, 0x7002708c, 0x7002708c, 0x4f00128c, 0x4f00128c},
1207+ {0x0000a560, 0x7302b08a, 0x7302b08a, 0x52001290, 0x52001290},
1208+ {0x0000a564, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
1209+ {0x0000a568, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
1210+ {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
1211+ {0x0000a570, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
1212+ {0x0000a574, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
1213+ {0x0000a578, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
1214+ {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
1215+ {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
1216+ {0x0000a584, 0x06800003, 0x06800003, 0x02800001, 0x02800001},
1217+ {0x0000a588, 0x0a800020, 0x0a800020, 0x05800003, 0x05800003},
1218+ {0x0000a58c, 0x10800023, 0x10800023, 0x0a800005, 0x0a800005},
1219+ {0x0000a590, 0x16800220, 0x16800220, 0x0e800201, 0x0e800201},
1220+ {0x0000a594, 0x1c800223, 0x1c800223, 0x11800203, 0x11800203},
1221+ {0x0000a598, 0x21820220, 0x21820220, 0x14800401, 0x14800401},
1222+ {0x0000a59c, 0x27820223, 0x27820223, 0x18800403, 0x18800403},
1223+ {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800602, 0x1b800602},
1224+ {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800802, 0x1f800802},
1225+ {0x0000a5a8, 0x34822225, 0x34822225, 0x21800620, 0x21800620},
1226+ {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x25800820, 0x25800820},
1227+ {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x29800822, 0x29800822},
1228+ {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2d800824, 0x2d800824},
1229+ {0x0000a5b8, 0x4782244a, 0x4782244a, 0x30800828, 0x30800828},
1230+ {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x3480082a, 0x3480082a},
1231+ {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38800849, 0x38800849},
1232+ {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3b800a2c, 0x3b800a2c},
1233+ {0x0000a5c8, 0x5782286c, 0x5782286c, 0x3e800e2b, 0x3e800e2b},
1234+ {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x42800e2d, 0x42800e2d},
1235+ {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4580124a, 0x4580124a},
1236+ {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4980124c, 0x4980124c},
1237+ {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x4c80126c, 0x4c80126c},
1238+ {0x0000a5dc, 0x7086308c, 0x7086308c, 0x4f80128c, 0x4f80128c},
1239+ {0x0000a5e0, 0x738a308a, 0x738a308a, 0x52801290, 0x52801290},
1240+ {0x0000a5e4, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
1241+ {0x0000a5e8, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
1242+ {0x0000a5ec, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
1243+ {0x0000a5f0, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
1244+ {0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
1245+ {0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
1246+ {0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
1247+ {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1248+ {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1249+ {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1250+ {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1251+ {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1252+ {0x0000a614, 0x01404000, 0x01404000, 0x01404501, 0x01404501},
1253+ {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
1254+ {0x0000a61c, 0x02008802, 0x02008802, 0x01404501, 0x01404501},
1255+ {0x0000a620, 0x0300cc03, 0x0300cc03, 0x03c0cf02, 0x03c0cf02},
1256+ {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03c0cf03, 0x03c0cf03},
1257+ {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04011004, 0x04011004},
1258+ {0x0000a62c, 0x03810c03, 0x03810c03, 0x05419405, 0x05419405},
1259+ {0x0000a630, 0x03810e04, 0x03810e04, 0x05419506, 0x05419506},
1260+ {0x0000a634, 0x03810e04, 0x03810e04, 0x05419506, 0x05419506},
1261+ {0x0000a638, 0x03810e04, 0x03810e04, 0x05419506, 0x05419506},
1262+ {0x0000a63c, 0x03810e04, 0x03810e04, 0x05419506, 0x05419506},
1263+ {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03eaac5a, 0x03eaac5a},
1264+ {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03f330ac, 0x03f330ac},
1265+ {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc3f00, 0x03fc3f00},
1266+ {0x0000b2e8, 0x00000000, 0x00000000, 0x03ffc000, 0x03ffc000},
1267+ {0x00016044, 0x022492db, 0x022492db, 0x022492db, 0x022492db},
1268+ {0x00016048, 0x24925666, 0x24925666, 0x24925266, 0x24925266},
1269+ {0x00016280, 0x01000015, 0x01000015, 0x01001015, 0x01001015},
1270+ {0x00016288, 0xf0318000, 0xf0318000, 0xf0318000, 0xf0318000},
1271+ {0x00016444, 0x022492db, 0x022492db, 0x022492db, 0x022492db},
1272+ {0x00016448, 0x24925666, 0x24925666, 0x24925266, 0x24925266},
1273+};
1274+
11751275 static const u32 ar9340_1p0_mac_core[][2] = {
11761276 /* Addr allmodes */
11771277 {0x00000008, 0x00000000},
drivers/net/wireless/ath/ath9k/ar9485_initvals.h+146−0
@@ -260,6 +260,79 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { · 259 unmodified lines
260260 {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
261261 };
262262
263+static const u32 ar9485Modes_green_ob_db_tx_gain_1_1[][5] = {
264+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
265+ {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003},
266+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
267+ {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
268+ {0x0000a500, 0x00022200, 0x00022200, 0x00000006, 0x00000006},
269+ {0x0000a504, 0x05062002, 0x05062002, 0x03000201, 0x03000201},
270+ {0x0000a508, 0x0c002e00, 0x0c002e00, 0x06000203, 0x06000203},
271+ {0x0000a50c, 0x11062202, 0x11062202, 0x0a000401, 0x0a000401},
272+ {0x0000a510, 0x17022e00, 0x17022e00, 0x0e000403, 0x0e000403},
273+ {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x12000405, 0x12000405},
274+ {0x0000a518, 0x25020ec0, 0x25020ec0, 0x15000604, 0x15000604},
275+ {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x18000605, 0x18000605},
276+ {0x0000a520, 0x2f001f04, 0x2f001f04, 0x1c000a04, 0x1c000a04},
277+ {0x0000a524, 0x35001fc4, 0x35001fc4, 0x21000a06, 0x21000a06},
278+ {0x0000a528, 0x3c022f04, 0x3c022f04, 0x29000a24, 0x29000a24},
279+ {0x0000a52c, 0x41023e85, 0x41023e85, 0x2f000e21, 0x2f000e21},
280+ {0x0000a530, 0x48023ec6, 0x48023ec6, 0x31000e20, 0x31000e20},
281+ {0x0000a534, 0x4d023f01, 0x4d023f01, 0x33000e20, 0x33000e20},
282+ {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
283+ {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
284+ {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
285+ {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
286+ {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
287+ {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
288+ {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
289+ {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
290+ {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
291+ {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
292+ {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
293+ {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
294+ {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
295+ {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
296+ {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
297+ {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
298+ {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
299+ {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
300+ {0x0000b500, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
301+ {0x0000b504, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
302+ {0x0000b508, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
303+ {0x0000b50c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
304+ {0x0000b510, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
305+ {0x0000b514, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
306+ {0x0000b518, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
307+ {0x0000b51c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
308+ {0x0000b520, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
309+ {0x0000b524, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
310+ {0x0000b528, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
311+ {0x0000b52c, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a},
312+ {0x0000b530, 0x0000003a, 0x0000003a, 0x0000003a, 0x0000003a},
313+ {0x0000b534, 0x0000004a, 0x0000004a, 0x0000004a, 0x0000004a},
314+ {0x0000b538, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
315+ {0x0000b53c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
316+ {0x0000b540, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
317+ {0x0000b544, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
318+ {0x0000b548, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
319+ {0x0000b54c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
320+ {0x0000b550, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
321+ {0x0000b554, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
322+ {0x0000b558, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
323+ {0x0000b55c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
324+ {0x0000b560, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
325+ {0x0000b564, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
326+ {0x0000b568, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
327+ {0x0000b56c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
328+ {0x0000b570, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
329+ {0x0000b574, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
330+ {0x0000b578, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
331+ {0x0000b57c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
332+ {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
333+ {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
334+};
335+
263336 static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = {
264337 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
265338 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
@@ -450,6 +523,79 @@ static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = { · 184 unmodified lines
450523
451524 #define ar9485_modes_lowest_ob_db_tx_gain_1_1 ar9485Modes_low_ob_db_tx_gain_1_1
452525
526+static const u32 ar9485Modes_green_spur_ob_db_tx_gain_1_1[][5] = {
527+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
528+ {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003},
529+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
530+ {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
531+ {0x0000a500, 0x00022200, 0x00022200, 0x00000006, 0x00000006},
532+ {0x0000a504, 0x05062002, 0x05062002, 0x03000201, 0x03000201},
533+ {0x0000a508, 0x0c002e00, 0x0c002e00, 0x07000203, 0x07000203},
534+ {0x0000a50c, 0x11062202, 0x11062202, 0x0a000401, 0x0a000401},
535+ {0x0000a510, 0x17022e00, 0x17022e00, 0x0e000403, 0x0e000403},
536+ {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x12000405, 0x12000405},
537+ {0x0000a518, 0x25020ec0, 0x25020ec0, 0x14000406, 0x14000406},
538+ {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1800040a, 0x1800040a},
539+ {0x0000a520, 0x2f001f04, 0x2f001f04, 0x1c000460, 0x1c000460},
540+ {0x0000a524, 0x35001fc4, 0x35001fc4, 0x22000463, 0x22000463},
541+ {0x0000a528, 0x3c022f04, 0x3c022f04, 0x26000465, 0x26000465},
542+ {0x0000a52c, 0x41023e85, 0x41023e85, 0x2e0006e0, 0x2e0006e0},
543+ {0x0000a530, 0x48023ec6, 0x48023ec6, 0x310006e0, 0x310006e0},
544+ {0x0000a534, 0x4d023f01, 0x4d023f01, 0x330006e0, 0x330006e0},
545+ {0x0000a538, 0x53023f4b, 0x53023f4b, 0x3e0008e3, 0x3e0008e3},
546+ {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x410008e5, 0x410008e5},
547+ {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x430008e6, 0x430008e6},
548+ {0x0000a544, 0x6502feca, 0x6502feca, 0x4a0008ec, 0x4a0008ec},
549+ {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4e0008f1, 0x4e0008f1},
550+ {0x0000a54c, 0x7203feca, 0x7203feca, 0x520008f3, 0x520008f3},
551+ {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x54000eed, 0x54000eed},
552+ {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x58000ef1, 0x58000ef1},
553+ {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5c000ef3, 0x5c000ef3},
554+ {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x60000ef5, 0x60000ef5},
555+ {0x0000a560, 0x900fff0b, 0x900fff0b, 0x62000ef6, 0x62000ef6},
556+ {0x0000a564, 0x960fffcb, 0x960fffcb, 0x62000ef6, 0x62000ef6},
557+ {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
558+ {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
559+ {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
560+ {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
561+ {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
562+ {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
563+ {0x0000b500, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
564+ {0x0000b504, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
565+ {0x0000b508, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
566+ {0x0000b50c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
567+ {0x0000b510, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
568+ {0x0000b514, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
569+ {0x0000b518, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
570+ {0x0000b51c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
571+ {0x0000b520, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
572+ {0x0000b524, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
573+ {0x0000b528, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
574+ {0x0000b52c, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a},
575+ {0x0000b530, 0x0000003a, 0x0000003a, 0x0000003a, 0x0000003a},
576+ {0x0000b534, 0x0000004a, 0x0000004a, 0x0000004a, 0x0000004a},
577+ {0x0000b538, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
578+ {0x0000b53c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
579+ {0x0000b540, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
580+ {0x0000b544, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
581+ {0x0000b548, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
582+ {0x0000b54c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
583+ {0x0000b550, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
584+ {0x0000b554, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
585+ {0x0000b558, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
586+ {0x0000b55c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
587+ {0x0000b560, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
588+ {0x0000b564, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
589+ {0x0000b568, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
590+ {0x0000b56c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
591+ {0x0000b570, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
592+ {0x0000b574, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
593+ {0x0000b578, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
594+ {0x0000b57c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
595+ {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
596+ {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
597+};
598+
453599 static const u32 ar9485_1_1[][2] = {
454600 /* Addr allmodes */
455601 {0x0000a580, 0x00000000},
drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h+66−66
@@ -23,16 +23,16 @@ · 22 unmodified lines
2323 static const u32 ar955x_1p0_radio_postamble[][5] = {
2424 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
2525 {0x00016098, 0xd2dd5554, 0xd2dd5554, 0xd28b3330, 0xd28b3330},
26− {0x0001609c, 0x0a566f3a, 0x0a566f3a, 0x06345f2a, 0x06345f2a},
27− {0x000160ac, 0xa4647c00, 0xa4647c00, 0xa4646800, 0xa4646800},
28− {0x000160b0, 0x01885f52, 0x01885f52, 0x04accf3a, 0x04accf3a},
29− {0x00016104, 0xb7a00001, 0xb7a00001, 0xb7a00001, 0xb7a00001},
26+ {0x0001609c, 0x0a566f3a, 0x0a566f3a, 0x0a566f3a, 0x0a566f3a},
27+ {0x000160ac, 0xa4647c00, 0xa4647c00, 0x24647c00, 0x24647c00},
28+ {0x000160b0, 0x01885f52, 0x01885f52, 0x01885f52, 0x01885f52},
29+ {0x00016104, 0xb7a00000, 0xb7a00000, 0xb7a00001, 0xb7a00001},
3030 {0x0001610c, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000},
3131 {0x00016140, 0x10804008, 0x10804008, 0x10804008, 0x10804008},
32− {0x00016504, 0xb7a00001, 0xb7a00001, 0xb7a00001, 0xb7a00001},
32+ {0x00016504, 0xb7a00000, 0xb7a00000, 0xb7a00001, 0xb7a00001},
3333 {0x0001650c, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000},
3434 {0x00016540, 0x10804008, 0x10804008, 0x10804008, 0x10804008},
35− {0x00016904, 0xb7a00001, 0xb7a00001, 0xb7a00001, 0xb7a00001},
35+ {0x00016904, 0xb7a00000, 0xb7a00000, 0xb7a00001, 0xb7a00001},
3636 {0x0001690c, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000},
3737 {0x00016940, 0x10804008, 0x10804008, 0x10804008, 0x10804008},
3838 };
@@ -69,15 +69,15 @@ static const u32 ar955x_1p0_baseband_postamble[][5] = { · 30 unmodified lines
6969 {0x0000a204, 0x005c0ec0, 0x005c0ec4, 0x005c0ec4, 0x005c0ec0},
7070 {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
7171 {0x0000a22c, 0x07e26a2f, 0x07e26a2f, 0x01026a2f, 0x01026a2f},
72− {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
72+ {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b},
7373 {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff},
7474 {0x0000a238, 0xffb01018, 0xffb01018, 0xffb01018, 0xffb01018},
7575 {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
7676 {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
7777 {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
78− {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
78+ {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01010e0e, 0x01010e0e},
7979 {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
80− {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
80+ {0x0000a264, 0x00000e0e, 0x00000e0e, 0x01000e0e, 0x01000e0e},
8181 {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
8282 {0x0000a284, 0x00000000, 0x00000000, 0x00000010, 0x00000010},
8383 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
@@ -125,7 +125,7 @@ static const u32 ar955x_1p0_radio_core[][2] = { · 41 unmodified lines
125125 {0x00016094, 0x00000000},
126126 {0x000160a0, 0x0a108ffe},
127127 {0x000160a4, 0x812fc370},
128− {0x000160a8, 0x423c8000},
128+ {0x000160a8, 0x423c8100},
129129 {0x000160b4, 0x92480080},
130130 {0x000160c0, 0x006db6d0},
131131 {0x000160c4, 0x6db6db60},
@@ -134,7 +134,7 @@ static const u32 ar955x_1p0_radio_core[][2] = { · 2 unmodified lines
134134 {0x00016100, 0x11999601},
135135 {0x00016108, 0x00080010},
136136 {0x00016144, 0x02084080},
137− {0x00016148, 0x000080c0},
137+ {0x00016148, 0x00008040},
138138 {0x00016280, 0x01800804},
139139 {0x00016284, 0x00038dc5},
140140 {0x00016288, 0x00000000},
@@ -178,7 +178,7 @@ static const u32 ar955x_1p0_radio_core[][2] = { · 37 unmodified lines
178178 {0x00016500, 0x11999601},
179179 {0x00016508, 0x00080010},
180180 {0x00016544, 0x02084080},
181− {0x00016548, 0x000080c0},
181+ {0x00016548, 0x00008040},
182182 {0x00016780, 0x00000000},
183183 {0x00016784, 0x00000000},
184184 {0x00016788, 0x00400705},
@@ -218,7 +218,7 @@ static const u32 ar955x_1p0_radio_core[][2] = { · 33 unmodified lines
218218 {0x00016900, 0x11999601},
219219 {0x00016908, 0x00080010},
220220 {0x00016944, 0x02084080},
221− {0x00016948, 0x000080c0},
221+ {0x00016948, 0x00008040},
222222 {0x00016b80, 0x00000000},
223223 {0x00016b84, 0x00000000},
224224 {0x00016b88, 0x00400705},
@@ -245,9 +245,9 @@ static const u32 ar955x_1p0_radio_core[][2] = { · 20 unmodified lines
245245
246246 static const u32 ar955x_1p0_modes_xpa_tx_gain_table[][9] = {
247247 /* Addr 5G_HT20_L 5G_HT40_L 5G_HT20_M 5G_HT40_M 5G_HT20_H 5G_HT40_H 2G_HT40 2G_HT20 */
248− {0x0000a2dc, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xfffd5aaa, 0xfffd5aaa},
249− {0x0000a2e0, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xfffe9ccc, 0xfffe9ccc},
250− {0x0000a2e4, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xffffe0f0, 0xffffe0f0},
248+ {0x0000a2dc, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xfffd5aaa, 0xfffd5aaa},
249+ {0x0000a2e0, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffe9ccc, 0xfffe9ccc},
250+ {0x0000a2e4, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffffe0f0, 0xffffe0f0},
251251 {0x0000a2e8, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xfffcff00, 0xfffcff00},
252252 {0x0000a410, 0x000050de, 0x000050de, 0x000050de, 0x000050de, 0x000050de, 0x000050de, 0x000050da, 0x000050da},
253253 {0x0000a500, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000000, 0x00000000},
@@ -256,63 +256,63 @@ static const u32 ar955x_1p0_modes_xpa_tx_gain_table[][9] = { · 2 unmodified lines
256256 {0x0000a50c, 0x0c00000b, 0x0c00000b, 0x0c00000b, 0x0c00000b, 0x0c00000b, 0x0c00000b, 0x0c000006, 0x0c000006},
257257 {0x0000a510, 0x1000000d, 0x1000000d, 0x1000000d, 0x1000000d, 0x1000000d, 0x1000000d, 0x0f00000a, 0x0f00000a},
258258 {0x0000a514, 0x14000011, 0x14000011, 0x14000011, 0x14000011, 0x14000011, 0x14000011, 0x1300000c, 0x1300000c},
259− {0x0000a518, 0x19004008, 0x19004008, 0x19004008, 0x19004008, 0x18004008, 0x18004008, 0x1700000e, 0x1700000e},
260− {0x0000a51c, 0x1d00400a, 0x1d00400a, 0x1d00400a, 0x1d00400a, 0x1c00400a, 0x1c00400a, 0x1b000064, 0x1b000064},
261− {0x0000a520, 0x230020a2, 0x230020a2, 0x210020a2, 0x210020a2, 0x200020a2, 0x200020a2, 0x1f000242, 0x1f000242},
262− {0x0000a524, 0x2500006e, 0x2500006e, 0x2500006e, 0x2500006e, 0x2400006e, 0x2400006e, 0x23000229, 0x23000229},
263− {0x0000a528, 0x29022221, 0x29022221, 0x28022221, 0x28022221, 0x27022221, 0x27022221, 0x270002a2, 0x270002a2},
264− {0x0000a52c, 0x2d00062a, 0x2d00062a, 0x2c00062a, 0x2c00062a, 0x2a00062a, 0x2a00062a, 0x2c001203, 0x2c001203},
265− {0x0000a530, 0x340220a5, 0x340220a5, 0x320220a5, 0x320220a5, 0x2f0220a5, 0x2f0220a5, 0x30001803, 0x30001803},
266− {0x0000a534, 0x380022c5, 0x380022c5, 0x350022c5, 0x350022c5, 0x320022c5, 0x320022c5, 0x33000881, 0x33000881},
267− {0x0000a538, 0x3b002486, 0x3b002486, 0x39002486, 0x39002486, 0x36002486, 0x36002486, 0x38001809, 0x38001809},
268− {0x0000a53c, 0x3f00248a, 0x3f00248a, 0x3d00248a, 0x3d00248a, 0x3a00248a, 0x3a00248a, 0x3a000814, 0x3a000814},
269− {0x0000a540, 0x4202242c, 0x4202242c, 0x4102242c, 0x4102242c, 0x3f02242c, 0x3f02242c, 0x3f001a0c, 0x3f001a0c},
270− {0x0000a544, 0x490044c6, 0x490044c6, 0x460044c6, 0x460044c6, 0x420044c6, 0x420044c6, 0x43001a0e, 0x43001a0e},
271− {0x0000a548, 0x4d024485, 0x4d024485, 0x4a024485, 0x4a024485, 0x46024485, 0x46024485, 0x46001812, 0x46001812},
272− {0x0000a54c, 0x51044483, 0x51044483, 0x4e044483, 0x4e044483, 0x4a044483, 0x4a044483, 0x49001884, 0x49001884},
273− {0x0000a550, 0x5404a40c, 0x5404a40c, 0x5204a40c, 0x5204a40c, 0x4d04a40c, 0x4d04a40c, 0x4d001e84, 0x4d001e84},
274− {0x0000a554, 0x57024632, 0x57024632, 0x55024632, 0x55024632, 0x52024632, 0x52024632, 0x50001e69, 0x50001e69},
275− {0x0000a558, 0x5c00a634, 0x5c00a634, 0x5900a634, 0x5900a634, 0x5600a634, 0x5600a634, 0x550006f4, 0x550006f4},
276− {0x0000a55c, 0x5f026832, 0x5f026832, 0x5d026832, 0x5d026832, 0x5a026832, 0x5a026832, 0x59000ad3, 0x59000ad3},
277− {0x0000a560, 0x6602b012, 0x6602b012, 0x6202b012, 0x6202b012, 0x5d02b012, 0x5d02b012, 0x5e000ad5, 0x5e000ad5},
278− {0x0000a564, 0x6e02d0e1, 0x6e02d0e1, 0x6802d0e1, 0x6802d0e1, 0x6002d0e1, 0x6002d0e1, 0x61001ced, 0x61001ced},
279− {0x0000a568, 0x7202b4c4, 0x7202b4c4, 0x6c02b4c4, 0x6c02b4c4, 0x6502b4c4, 0x6502b4c4, 0x660018d4, 0x660018d4},
280− {0x0000a56c, 0x75007894, 0x75007894, 0x70007894, 0x70007894, 0x6b007894, 0x6b007894, 0x660018d4, 0x660018d4},
281− {0x0000a570, 0x7b025c74, 0x7b025c74, 0x75025c74, 0x75025c74, 0x70025c74, 0x70025c74, 0x660018d4, 0x660018d4},
282− {0x0000a574, 0x8300bcb5, 0x8300bcb5, 0x7a00bcb5, 0x7a00bcb5, 0x7600bcb5, 0x7600bcb5, 0x660018d4, 0x660018d4},
283− {0x0000a578, 0x8a04dc74, 0x8a04dc74, 0x7f04dc74, 0x7f04dc74, 0x7c04dc74, 0x7c04dc74, 0x660018d4, 0x660018d4},
284− {0x0000a57c, 0x8a04dc74, 0x8a04dc74, 0x7f04dc74, 0x7f04dc74, 0x7c04dc74, 0x7c04dc74, 0x660018d4, 0x660018d4},
259+ {0x0000a518, 0x1700002b, 0x1700002b, 0x1700002b, 0x1700002b, 0x1600002b, 0x1600002b, 0x1700000e, 0x1700000e},
260+ {0x0000a51c, 0x1b00002d, 0x1b00002d, 0x1b00002d, 0x1b00002d, 0x1a00002d, 0x1a00002d, 0x1b000064, 0x1b000064},
261+ {0x0000a520, 0x20000031, 0x20000031, 0x1f000031, 0x1f000031, 0x1e000031, 0x1e000031, 0x1f000242, 0x1f000242},
262+ {0x0000a524, 0x24000051, 0x24000051, 0x23000051, 0x23000051, 0x23000051, 0x23000051, 0x23000229, 0x23000229},
263+ {0x0000a528, 0x27000071, 0x27000071, 0x27000071, 0x27000071, 0x26000071, 0x26000071, 0x270002a2, 0x270002a2},
264+ {0x0000a52c, 0x2b000092, 0x2b000092, 0x2b000092, 0x2b000092, 0x2b000092, 0x2b000092, 0x2c001203, 0x2c001203},
265+ {0x0000a530, 0x3000028c, 0x3000028c, 0x2f00028c, 0x2f00028c, 0x2e00028c, 0x2e00028c, 0x30001803, 0x30001803},
266+ {0x0000a534, 0x34000290, 0x34000290, 0x33000290, 0x33000290, 0x32000290, 0x32000290, 0x33000881, 0x33000881},
267+ {0x0000a538, 0x37000292, 0x37000292, 0x36000292, 0x36000292, 0x35000292, 0x35000292, 0x38001809, 0x38001809},
268+ {0x0000a53c, 0x3b02028d, 0x3b02028d, 0x3a02028d, 0x3a02028d, 0x3902028d, 0x3902028d, 0x3a000814, 0x3a000814},
269+ {0x0000a540, 0x3f020291, 0x3f020291, 0x3e020291, 0x3e020291, 0x3d020291, 0x3d020291, 0x3f001a0c, 0x3f001a0c},
270+ {0x0000a544, 0x44020490, 0x44020490, 0x43020490, 0x43020490, 0x42020490, 0x42020490, 0x43001a0e, 0x43001a0e},
271+ {0x0000a548, 0x48020492, 0x48020492, 0x47020492, 0x47020492, 0x46020492, 0x46020492, 0x46001812, 0x46001812},
272+ {0x0000a54c, 0x4c020692, 0x4c020692, 0x4b020692, 0x4b020692, 0x4a020692, 0x4a020692, 0x49001884, 0x49001884},
273+ {0x0000a550, 0x50020892, 0x50020892, 0x4f020892, 0x4f020892, 0x4e020892, 0x4e020892, 0x4d001e84, 0x4d001e84},
274+ {0x0000a554, 0x53040891, 0x53040891, 0x53040891, 0x53040891, 0x52040891, 0x52040891, 0x50001e69, 0x50001e69},
275+ {0x0000a558, 0x58040893, 0x58040893, 0x57040893, 0x57040893, 0x56040893, 0x56040893, 0x550006f4, 0x550006f4},
276+ {0x0000a55c, 0x5c0408b4, 0x5c0408b4, 0x5a0408b4, 0x5a0408b4, 0x5a0408b4, 0x5a0408b4, 0x59000ad3, 0x59000ad3},
277+ {0x0000a560, 0x610408b6, 0x610408b6, 0x5e0408b6, 0x5e0408b6, 0x5e0408b6, 0x5e0408b6, 0x5e000ad5, 0x5e000ad5},
278+ {0x0000a564, 0x670408f6, 0x670408f6, 0x620408f6, 0x620408f6, 0x620408f6, 0x620408f6, 0x61001ced, 0x61001ced},
279+ {0x0000a568, 0x6a040cf6, 0x6a040cf6, 0x66040cf6, 0x66040cf6, 0x66040cf6, 0x66040cf6, 0x660018d4, 0x660018d4},
280+ {0x0000a56c, 0x6d040d76, 0x6d040d76, 0x6a040d76, 0x6a040d76, 0x6a040d76, 0x6a040d76, 0x660018d4, 0x660018d4},
281+ {0x0000a570, 0x70060db6, 0x70060db6, 0x6e060db6, 0x6e060db6, 0x6e060db6, 0x6e060db6, 0x660018d4, 0x660018d4},
282+ {0x0000a574, 0x730a0df6, 0x730a0df6, 0x720a0df6, 0x720a0df6, 0x720a0df6, 0x720a0df6, 0x660018d4, 0x660018d4},
283+ {0x0000a578, 0x770a13f6, 0x770a13f6, 0x760a13f6, 0x760a13f6, 0x760a13f6, 0x760a13f6, 0x660018d4, 0x660018d4},
284+ {0x0000a57c, 0x770a13f6, 0x770a13f6, 0x760a13f6, 0x760a13f6, 0x760a13f6, 0x760a13f6, 0x660018d4, 0x660018d4},
285285 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
286286 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
287287 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
288− {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x03804000, 0x03804000},
289− {0x0000a610, 0x04c08c01, 0x04c08c01, 0x04808b01, 0x04808b01, 0x04808a01, 0x04808a01, 0x0300ca02, 0x0300ca02},
290− {0x0000a614, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00000e04, 0x00000e04},
291− {0x0000a618, 0x04010c01, 0x04010c01, 0x03c10b01, 0x03c10b01, 0x03810a01, 0x03810a01, 0x03014000, 0x03014000},
292− {0x0000a61c, 0x03814e05, 0x03814e05, 0x03414d05, 0x03414d05, 0x03414d05, 0x03414d05, 0x00000000, 0x00000000},
293− {0x0000a620, 0x04010303, 0x04010303, 0x03c10303, 0x03c10303, 0x03810303, 0x03810303, 0x00000000, 0x00000000},
294− {0x0000a624, 0x03814e05, 0x03814e05, 0x03414d05, 0x03414d05, 0x03414d05, 0x03414d05, 0x03014000, 0x03014000},
295− {0x0000a628, 0x00c0c000, 0x00c0c000, 0x00c0c000, 0x00c0c000, 0x00c0c000, 0x00c0c000, 0x03804c05, 0x03804c05},
296− {0x0000a62c, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x0701de06, 0x0701de06},
297− {0x0000a630, 0x03418000, 0x03418000, 0x03018000, 0x03018000, 0x02c18000, 0x02c18000, 0x07819c07, 0x07819c07},
298− {0x0000a634, 0x03815004, 0x03815004, 0x03414f04, 0x03414f04, 0x03414e04, 0x03414e04, 0x0701dc07, 0x0701dc07},
299− {0x0000a638, 0x03005302, 0x03005302, 0x02c05202, 0x02c05202, 0x02805202, 0x02805202, 0x0701dc07, 0x0701dc07},
300− {0x0000a63c, 0x04c09302, 0x04c09302, 0x04809202, 0x04809202, 0x04809202, 0x04809202, 0x0701dc07, 0x0701dc07},
301− {0x0000b2dc, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xfffd5aaa, 0xfffd5aaa},
302− {0x0000b2e0, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xfffe9ccc, 0xfffe9ccc},
303− {0x0000b2e4, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xffffe0f0, 0xffffe0f0},
288+ {0x0000a60c, 0x02c04b01, 0x02c04b01, 0x02c04b01, 0x02c04b01, 0x02c04b01, 0x02c04b01, 0x03804000, 0x03804000},
289+ {0x0000a610, 0x04008b01, 0x04008b01, 0x04008b01, 0x04008b01, 0x03c08b01, 0x03c08b01, 0x0300ca02, 0x0300ca02},
290+ {0x0000a614, 0x05811403, 0x05811403, 0x05411303, 0x05411303, 0x05411303, 0x05411303, 0x00000e04, 0x00000e04},
291+ {0x0000a618, 0x05811604, 0x05811604, 0x05411504, 0x05411504, 0x05411504, 0x05411504, 0x03014000, 0x03014000},
292+ {0x0000a61c, 0x05811604, 0x05811604, 0x05411504, 0x05411504, 0x05411504, 0x05411504, 0x00000000, 0x00000000},
293+ {0x0000a620, 0x05811604, 0x05811604, 0x05411504, 0x05411504, 0x05411504, 0x05411504, 0x00000000, 0x00000000},
294+ {0x0000a624, 0x05811604, 0x05811604, 0x05411504, 0x05411504, 0x05411504, 0x05411504, 0x03014000, 0x03014000},
295+ {0x0000a628, 0x05811604, 0x05811604, 0x05411504, 0x05411504, 0x05411504, 0x05411504, 0x03804c05, 0x03804c05},
296+ {0x0000a62c, 0x06815604, 0x06815604, 0x06415504, 0x06415504, 0x06015504, 0x06015504, 0x0701de06, 0x0701de06},
297+ {0x0000a630, 0x07819a05, 0x07819a05, 0x07419905, 0x07419905, 0x07019805, 0x07019805, 0x07819c07, 0x07819c07},
298+ {0x0000a634, 0x07819e06, 0x07819e06, 0x07419d06, 0x07419d06, 0x07019c06, 0x07019c06, 0x0701dc07, 0x0701dc07},
299+ {0x0000a638, 0x07819e06, 0x07819e06, 0x07419d06, 0x07419d06, 0x07019c06, 0x07019c06, 0x0701dc07, 0x0701dc07},
300+ {0x0000a63c, 0x07819e06, 0x07819e06, 0x07419d06, 0x07419d06, 0x07019c06, 0x07019c06, 0x0701dc07, 0x0701dc07},
301+ {0x0000b2dc, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xfffd5aaa, 0xfffd5aaa},
302+ {0x0000b2e0, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffe9ccc, 0xfffe9ccc},
303+ {0x0000b2e4, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffffe0f0, 0xffffe0f0},
304304 {0x0000b2e8, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xfffcff00, 0xfffcff00},
305− {0x0000c2dc, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xfffd5aaa, 0xfffd5aaa},
306− {0x0000c2e0, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xfffe9ccc, 0xfffe9ccc},
307− {0x0000c2e4, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xffffe0f0, 0xffffe0f0},
305+ {0x0000c2dc, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xfffd5aaa, 0xfffd5aaa},
306+ {0x0000c2e0, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffe9ccc, 0xfffe9ccc},
307+ {0x0000c2e4, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffffe0f0, 0xffffe0f0},
308308 {0x0000c2e8, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xfffcff00, 0xfffcff00},
309309 {0x00016044, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x010002d4, 0x010002d4},
310− {0x00016048, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x66482401, 0x66482401},
310+ {0x00016048, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401},
311311 {0x00016280, 0x01801e84, 0x01801e84, 0x01801e84, 0x01801e84, 0x01801e84, 0x01801e84, 0x01808e84, 0x01808e84},
312312 {0x00016444, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x010002d4, 0x010002d4},
313− {0x00016448, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x66482401, 0x66482401},
313+ {0x00016448, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401},
314314 {0x00016844, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x010002d4, 0x010002d4},
315− {0x00016848, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x66482401, 0x66482401},
315+ {0x00016848, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401},
316316 };
317317
318318 static const u32 ar955x_1p0_mac_core[][2] = {
@@ -846,7 +846,7 @@ static const u32 ar955x_1p0_baseband_core[][2] = { · 527 unmodified lines
846846 {0x0000a44c, 0x00000001},
847847 {0x0000a450, 0x00010000},
848848 {0x0000a458, 0x00000000},
849− {0x0000a644, 0x3fad9d74},
849+ {0x0000a644, 0xbfad9d74},
850850 {0x0000a648, 0x0048060a},
851851 {0x0000a64c, 0x00003c37},
852852 {0x0000a670, 0x03020100},
@@ -1277,7 +1277,7 @@ static const u32 ar955x_1p0_modes_fast_clock[][3] = { · 424 unmodified lines
12771277 {0x0000801c, 0x148ec02b, 0x148ec057},
12781278 {0x00008318, 0x000044c0, 0x00008980},
12791279 {0x00009e00, 0x0372131c, 0x0372131c},
1280− {0x0000a230, 0x0000000b, 0x00000016},
1280+ {0x0000a230, 0x0000400b, 0x00004016},
12811281 {0x0000a254, 0x00000898, 0x00001130},
12821282 };
12831283
drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h+76−0
@@ -685,6 +685,82 @@ static const u32 ar9580_1p0_mixed_ob_db_tx_gain_table[][5] = { · 684 unmodified lines
685685
686686 #define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2
687687
688+#define ar9580_1p0_type5_tx_gain_table ar9300Modes_type5_tx_gain_table_2p2
689+
690+static const u32 ar9580_1p0_type6_tx_gain_table[][5] = {
691+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
692+ {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
693+ {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
694+ {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
695+ {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
696+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
697+ {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
698+ {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
699+ {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
700+ {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
701+ {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202},
702+ {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400},
703+ {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402},
704+ {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404},
705+ {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603},
706+ {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02},
707+ {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04},
708+ {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20},
709+ {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20},
710+ {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22},
711+ {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24},
712+ {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640},
713+ {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660},
714+ {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861},
715+ {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81},
716+ {0x0000a54c, 0x5e08442e, 0x5e08442e, 0x47001a83, 0x47001a83},
717+ {0x0000a550, 0x620a4431, 0x620a4431, 0x4a001c84, 0x4a001c84},
718+ {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3},
719+ {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5},
720+ {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9},
721+ {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb},
722+ {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
723+ {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
724+ {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
725+ {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
726+ {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
727+ {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
728+ {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
729+ {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
730+ {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
731+ {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
732+ {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
733+ {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
734+ {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000},
735+ {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501},
736+ {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501},
737+ {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03},
738+ {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
739+ {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04},
740+ {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
741+ {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
742+ {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
743+ {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
744+ {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
745+ {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
746+ {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
747+ {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
748+ {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
749+ {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
750+ {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
751+ {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
752+ {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
753+ {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
754+ {0x00016048, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
755+ {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
756+ {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
757+ {0x00016448, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
758+ {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
759+ {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
760+ {0x00016848, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
761+ {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
762+};
763+
688764 static const u32 ar9580_1p0_soc_preamble[][2] = {
689765 /* Addr allmodes */
690766 {0x000040a4, 0x00a0c1c9},
drivers/net/wireless/ath/ath9k/ath9k.h+154−11
@@ -109,14 +109,11 @@ struct ath_descdma { · 108 unmodified lines
109109 void *dd_desc;
110110 dma_addr_t dd_desc_paddr;
111111 u32 dd_desc_len;
112− struct ath_buf *dd_bufptr;
113112 };
114113
115114 int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
116115 struct list_head *head, const char *name,
117116 int nbuf, int ndesc, bool is_tx);
118−void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
119− struct list_head *head);
120117
121118 /***********/
122119 /* RX / TX */
@@ -317,10 +314,8 @@ struct ath_rx { · 194 unmodified lines
317314 u32 *rxlink;
318315 u32 num_pkts;
319316 unsigned int rxfilter;
320− spinlock_t rxbuflock;
321317 struct list_head rxbuf;
322318 struct ath_descdma rxdma;
323− struct ath_buf *rx_bufptr;
324319 struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
325320
326321 struct sk_buff *frag;
@@ -328,7 +323,6 @@ struct ath_rx { · 1 unmodified line
328323
329324 int ath_startrecv(struct ath_softc *sc);
330325 bool ath_stoprecv(struct ath_softc *sc);
331−void ath_flushrecv(struct ath_softc *sc);
332326 u32 ath_calcrxfilter(struct ath_softc *sc);
333327 int ath_rx_init(struct ath_softc *sc, int nbufs);
334328 void ath_rx_cleanup(struct ath_softc *sc);
@@ -338,14 +332,12 @@ void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq); · 3 unmodified lines
338332 void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq);
339333 void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq);
340334 void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
341−bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
342−void ath_draintxq(struct ath_softc *sc,
343− struct ath_txq *txq, bool retry_tx);
335+bool ath_drain_all_txq(struct ath_softc *sc);
336+void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq);
344337 void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
345338 void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
346339 void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
347340 int ath_tx_init(struct ath_softc *sc, int nbufs);
348−void ath_tx_cleanup(struct ath_softc *sc);
349341 int ath_txq_update(struct ath_softc *sc, int qnum,
350342 struct ath9k_tx_queue_info *q);
351343 void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop);
@@ -646,7 +638,6 @@ void ath_ant_comb_update(struct ath_softc *sc); · 294 unmodified lines
646638 enum sc_op_flags {
647639 SC_OP_INVALID,
648640 SC_OP_BEACONS,
649− SC_OP_RXFLUSH,
650641 SC_OP_ANI_RUN,
651642 SC_OP_PRIM_STA_VIF,
652643 SC_OP_HW_RESET,
@@ -675,6 +666,23 @@ struct ath9k_vif_iter_data { · 22 unmodified lines
675666 int nadhocs; /* number of adhoc vifs */
676667 };
677668
669+/* enum spectral_mode:
670+ *
671+ * @SPECTRAL_DISABLED: spectral mode is disabled
672+ * @SPECTRAL_BACKGROUND: hardware sends samples when it is not busy with
673+ * something else.
674+ * @SPECTRAL_MANUAL: spectral scan is enabled, triggering for samples
675+ * is performed manually.
676+ * @SPECTRAL_CHANSCAN: Like manual, but also triggered when changing channels
677+ * during a channel scan.
678+ */
679+enum spectral_mode {
680+ SPECTRAL_DISABLED = 0,
681+ SPECTRAL_BACKGROUND,
682+ SPECTRAL_MANUAL,
683+ SPECTRAL_CHANSCAN,
684+};
685+
678686 struct ath_softc {
679687 struct ieee80211_hw *hw;
680688 struct device *dev;
@@ -743,6 +751,10 @@ struct ath_softc { · 62 unmodified lines
743751 u8 ant_tx, ant_rx;
744752 struct dfs_pattern_detector *dfs_detector;
745753 u32 wow_enabled;
754+ /* relay(fs) channel for spectral scan */
755+ struct rchan *rfs_chan_spec_scan;
756+ enum spectral_mode spectral_mode;
757+ int scanning;
746758
747759 #ifdef CONFIG_PM_SLEEP
748760 atomic_t wow_got_bmiss_intr;
@@ -751,6 +763,133 @@ struct ath_softc { · 2 unmodified lines
751763 #endif
752764 };
753765
766+#define SPECTRAL_SCAN_BITMASK 0x10
767+/* Radar info packet format, used for DFS and spectral formats. */
768+struct ath_radar_info {
769+ u8 pulse_length_pri;
770+ u8 pulse_length_ext;
771+ u8 pulse_bw_info;
772+} __packed;
773+
774+/* The HT20 spectral data has 4 bytes of additional information at it's end.
775+ *
776+ * [7:0]: all bins {max_magnitude[1:0], bitmap_weight[5:0]}
777+ * [7:0]: all bins max_magnitude[9:2]
778+ * [7:0]: all bins {max_index[5:0], max_magnitude[11:10]}
779+ * [3:0]: max_exp (shift amount to size max bin to 8-bit unsigned)
780+ */
781+struct ath_ht20_mag_info {
782+ u8 all_bins[3];
783+ u8 max_exp;
784+} __packed;
785+
786+#define SPECTRAL_HT20_NUM_BINS 56
787+
788+/* WARNING: don't actually use this struct! MAC may vary the amount of
789+ * data by -1/+2. This struct is for reference only.
790+ */
791+struct ath_ht20_fft_packet {
792+ u8 data[SPECTRAL_HT20_NUM_BINS];
793+ struct ath_ht20_mag_info mag_info;
794+ struct ath_radar_info radar_info;
795+} __packed;
796+
797+#define SPECTRAL_HT20_TOTAL_DATA_LEN (sizeof(struct ath_ht20_fft_packet))
798+
799+/* Dynamic 20/40 mode:
800+ *
801+ * [7:0]: lower bins {max_magnitude[1:0], bitmap_weight[5:0]}
802+ * [7:0]: lower bins max_magnitude[9:2]
803+ * [7:0]: lower bins {max_index[5:0], max_magnitude[11:10]}
804+ * [7:0]: upper bins {max_magnitude[1:0], bitmap_weight[5:0]}
805+ * [7:0]: upper bins max_magnitude[9:2]
806+ * [7:0]: upper bins {max_index[5:0], max_magnitude[11:10]}
807+ * [3:0]: max_exp (shift amount to size max bin to 8-bit unsigned)
808+ */
809+struct ath_ht20_40_mag_info {
810+ u8 lower_bins[3];
811+ u8 upper_bins[3];
812+ u8 max_exp;
813+} __packed;
814+
815+#define SPECTRAL_HT20_40_NUM_BINS 128
816+
817+/* WARNING: don't actually use this struct! MAC may vary the amount of
818+ * data. This struct is for reference only.
819+ */
820+struct ath_ht20_40_fft_packet {
821+ u8 data[SPECTRAL_HT20_40_NUM_BINS];
822+ struct ath_ht20_40_mag_info mag_info;
823+ struct ath_radar_info radar_info;
824+} __packed;
825+
826+
827+#define SPECTRAL_HT20_40_TOTAL_DATA_LEN (sizeof(struct ath_ht20_40_fft_packet))
828+
829+/* grabs the max magnitude from the all/upper/lower bins */
830+static inline u16 spectral_max_magnitude(u8 *bins)
831+{
832+ return (bins[0] & 0xc0) >> 6 |
833+ (bins[1] & 0xff) << 2 |
834+ (bins[2] & 0x03) << 10;
835+}
836+
837+/* return the max magnitude from the all/upper/lower bins */
838+static inline u8 spectral_max_index(u8 *bins)
839+{
840+ s8 m = (bins[2] & 0xfc) >> 2;
841+
842+ /* TODO: this still doesn't always report the right values ... */
843+ if (m > 32)
844+ m |= 0xe0;
845+ else
846+ m &= ~0xe0;
847+
848+ return m + 29;
849+}
850+
851+/* return the bitmap weight from the all/upper/lower bins */
852+static inline u8 spectral_bitmap_weight(u8 *bins)
853+{
854+ return bins[0] & 0x3f;
855+}
856+
857+/* FFT sample format given to userspace via debugfs.
858+ *
859+ * Please keep the type/length at the front position and change
860+ * other fields after adding another sample type
861+ *
862+ * TODO: this might need rework when switching to nl80211-based
863+ * interface.
864+ */
865+enum ath_fft_sample_type {
866+ ATH_FFT_SAMPLE_HT20 = 0,
867+};
868+
869+struct fft_sample_tlv {
870+ u8 type; /* see ath_fft_sample */
871+ u16 length;
872+ /* type dependent data follows */
873+} __packed;
874+
875+struct fft_sample_ht20 {
876+ struct fft_sample_tlv tlv;
877+
878+ u8 __alignment;
879+
880+ u16 freq;
881+ s8 rssi;
882+ s8 noise;
883+
884+ u16 max_magnitude;
885+ u8 max_index;
886+ u8 bitmap_weight;
887+
888+ u64 tsf;
889+
890+ u16 data[SPECTRAL_HT20_NUM_BINS];
891+} __packed;
892+
754893 void ath9k_tasklet(unsigned long data);
755894 int ath_cabq_update(struct ath_softc *);
756895
@@ -773,6 +912,10 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); · 16 unmodified lines
773912 void ath9k_reload_chainmask_settings(struct ath_softc *sc);
774913
775914 bool ath9k_uses_beacons(int type);
915+void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw);
916+int ath9k_spectral_scan_config(struct ieee80211_hw *hw,
917+ enum spectral_mode spectral_mode);
918+
776919
777920 #ifdef CONFIG_ATH9K_PCI
778921 int ath_pci_init(void);
drivers/net/wireless/ath/ath9k/beacon.c+2−2
@@ -147,6 +147,7 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw, · 146 unmodified lines
147147 skb->len, DMA_TO_DEVICE);
148148 dev_kfree_skb_any(skb);
149149 bf->bf_buf_addr = 0;
150+ bf->bf_mpdu = NULL;
150151 }
151152
152153 skb = ieee80211_beacon_get(hw, vif);
@@ -198,7 +199,7 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw, · 45 unmodified lines
198199 if (sc->nvifs > 1) {
199200 ath_dbg(common, BEACON,
200201 "Flushing previous cabq traffic\n");
201− ath_draintxq(sc, cabq, false);
202+ ath_draintxq(sc, cabq);
202203 }
203204 }
204205
@@ -359,7 +360,6 @@ void ath9k_beacon_tasklet(unsigned long data) · 154 unmodified lines
359360 return;
360361
361362 bf = ath9k_beacon_generate(sc->hw, vif);
362− WARN_ON(!bf);
363363
364364 if (sc->beacon.bmisscnt != 0) {
365365 ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n",
drivers/net/wireless/ath/ath9k/debug.c+115−1
@@ -17,6 +17,7 @@ · 16 unmodified lines
1717 #include <linux/slab.h>
1818 #include <linux/vmalloc.h>
1919 #include <linux/export.h>
20+#include <linux/relay.h>
2021 #include <asm/unaligned.h>
2122
2223 #include "ath9k.h"
@@ -861,7 +862,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, · 838 unmodified lines
861862 RXS_ERR("RX-LENGTH-ERR", rx_len_err);
862863 RXS_ERR("RX-OOM-ERR", rx_oom_err);
863864 RXS_ERR("RX-RATE-ERR", rx_rate_err);
864− RXS_ERR("RX-DROP-RXFLUSH", rx_drop_rxflush);
865865 RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err);
866866
867867 PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
@@ -966,6 +966,112 @@ static const struct file_operations fops_recv = { · 98 unmodified lines
966966 .llseek = default_llseek,
967967 };
968968
969+static ssize_t read_file_spec_scan_ctl(struct file *file, char __user *user_buf,
970+ size_t count, loff_t *ppos)
971+{
972+ struct ath_softc *sc = file->private_data;
973+ char *mode = "";
974+ unsigned int len;
975+
976+ switch (sc->spectral_mode) {
977+ case SPECTRAL_DISABLED:
978+ mode = "disable";
979+ break;
980+ case SPECTRAL_BACKGROUND:
981+ mode = "background";
982+ break;
983+ case SPECTRAL_CHANSCAN:
984+ mode = "chanscan";
985+ break;
986+ case SPECTRAL_MANUAL:
987+ mode = "manual";
988+ break;
989+ }
990+ len = strlen(mode);
991+ return simple_read_from_buffer(user_buf, count, ppos, mode, len);
992+}
993+
994+static ssize_t write_file_spec_scan_ctl(struct file *file,
995+ const char __user *user_buf,
996+ size_t count, loff_t *ppos)
997+{
998+ struct ath_softc *sc = file->private_data;
999+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1000+ char buf[32];
1001+ ssize_t len;
1002+
1003+ len = min(count, sizeof(buf) - 1);
1004+ if (copy_from_user(buf, user_buf, len))
1005+ return -EFAULT;
1006+
1007+ buf[len] = '\0';
1008+
1009+ if (strncmp("trigger", buf, 7) == 0) {
1010+ ath9k_spectral_scan_trigger(sc->hw);
1011+ } else if (strncmp("background", buf, 9) == 0) {
1012+ ath9k_spectral_scan_config(sc->hw, SPECTRAL_BACKGROUND);
1013+ ath_dbg(common, CONFIG, "spectral scan: background mode enabled\n");
1014+ } else if (strncmp("chanscan", buf, 8) == 0) {
1015+ ath9k_spectral_scan_config(sc->hw, SPECTRAL_CHANSCAN);
1016+ ath_dbg(common, CONFIG, "spectral scan: channel scan mode enabled\n");
1017+ } else if (strncmp("manual", buf, 6) == 0) {
1018+ ath9k_spectral_scan_config(sc->hw, SPECTRAL_MANUAL);
1019+ ath_dbg(common, CONFIG, "spectral scan: manual mode enabled\n");
1020+ } else if (strncmp("disable", buf, 7) == 0) {
1021+ ath9k_spectral_scan_config(sc->hw, SPECTRAL_DISABLED);
1022+ ath_dbg(common, CONFIG, "spectral scan: disabled\n");
1023+ } else {
1024+ return -EINVAL;
1025+ }
1026+
1027+ return count;
1028+}
1029+
1030+static const struct file_operations fops_spec_scan_ctl = {
1031+ .read = read_file_spec_scan_ctl,
1032+ .write = write_file_spec_scan_ctl,
1033+ .open = simple_open,
1034+ .owner = THIS_MODULE,
1035+ .llseek = default_llseek,
1036+};
1037+
1038+static struct dentry *create_buf_file_handler(const char *filename,
1039+ struct dentry *parent,
1040+ umode_t mode,
1041+ struct rchan_buf *buf,
1042+ int *is_global)
1043+{
1044+ struct dentry *buf_file;
1045+
1046+ buf_file = debugfs_create_file(filename, mode, parent, buf,
1047+ &relay_file_operations);
1048+ *is_global = 1;
1049+ return buf_file;
1050+}
1051+
1052+static int remove_buf_file_handler(struct dentry *dentry)
1053+{
1054+ debugfs_remove(dentry);
1055+
1056+ return 0;
1057+}
1058+
1059+void ath_debug_send_fft_sample(struct ath_softc *sc,
1060+ struct fft_sample_tlv *fft_sample_tlv)
1061+{
1062+ if (!sc->rfs_chan_spec_scan)
1063+ return;
1064+
1065+ relay_write(sc->rfs_chan_spec_scan, fft_sample_tlv,
1066+ fft_sample_tlv->length + sizeof(*fft_sample_tlv));
1067+}
1068+
1069+static struct rchan_callbacks rfs_spec_scan_cb = {
1070+ .create_buf_file = create_buf_file_handler,
1071+ .remove_buf_file = remove_buf_file_handler,
1072+};
1073+
1074+
9691075 static ssize_t read_file_regidx(struct file *file, char __user *user_buf,
9701076 size_t count, loff_t *ppos)
9711077 {
@@ -1780,6 +1886,14 @@ int ath9k_init_debug(struct ath_hw *ah) · 808 unmodified lines
17801886 &fops_base_eeprom);
17811887 debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
17821888 &fops_modal_eeprom);
1889+ sc->rfs_chan_spec_scan = relay_open("spectral_scan",
1890+ sc->debug.debugfs_phy,
1891+ 262144, 4, &rfs_spec_scan_cb,
1892+ NULL);
1893+ debugfs_create_file("spectral_scan_ctl", S_IRUSR | S_IWUSR,
1894+ sc->debug.debugfs_phy, sc,
1895+ &fops_spec_scan_ctl);
1896+
17831897 #ifdef CONFIG_ATH9K_MAC_DEBUG
17841898 debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc,
17851899 &fops_samps);
drivers/net/wireless/ath/ath9k/debug.h+5−2
@@ -23,6 +23,7 @@ · 22 unmodified lines
2323
2424 struct ath_txq;
2525 struct ath_buf;
26+struct fft_sample_tlv;
2627
2728 #ifdef CONFIG_ATH9K_DEBUGFS
2829 #define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++
@@ -216,7 +217,6 @@ struct ath_tx_stats { · 187 unmodified lines
216217 * @rx_oom_err: No. of frames dropped due to OOM issues.
217218 * @rx_rate_err: No. of frames dropped due to rate errors.
218219 * @rx_too_many_frags_err: Frames dropped due to too-many-frags received.
219− * @rx_drop_rxflush: No. of frames dropped due to RX-FLUSH.
220220 * @rx_beacons: No. of beacons received.
221221 * @rx_frags: No. of rx-fragements received.
222222 */
@@ -235,7 +235,6 @@ struct ath_rx_stats { · 12 unmodified lines
235235 u32 rx_oom_err;
236236 u32 rx_rate_err;
237237 u32 rx_too_many_frags_err;
238− u32 rx_drop_rxflush;
239238 u32 rx_beacons;
240239 u32 rx_frags;
241240 };
@@ -323,6 +322,10 @@ void ath9k_sta_remove_debugfs(struct ieee80211_hw *hw, · 81 unmodified lines
323322 struct ieee80211_vif *vif,
324323 struct ieee80211_sta *sta,
325324 struct dentry *dir);
325+
326+void ath_debug_send_fft_sample(struct ath_softc *sc,
327+ struct fft_sample_tlv *fft_sample);
328+
326329 #else
327330
328331 #define RX_STAT_INC(c) /* NOP */
drivers/net/wireless/ath/ath9k/htc_hst.c+2−0
@@ -344,6 +344,8 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, · 343 unmodified lines
344344 endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv,
345345 skb, htc_hdr->endpoint_id,
346346 txok);
347+ } else {
348+ kfree_skb(skb);
347349 }
348350 }
349351
drivers/net/wireless/ath/ath9k/hw-ops.h+0−16
@@ -101,22 +101,6 @@ static inline void ath9k_hw_spur_mitigate_freq(struct ath_hw *ah, · 100 unmodified lines
101101 ath9k_hw_private_ops(ah)->spur_mitigate_freq(ah, chan);
102102 }
103103
104−static inline int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah)
105−{
106− if (!ath9k_hw_private_ops(ah)->rf_alloc_ext_banks)
107− return 0;
108−
109− return ath9k_hw_private_ops(ah)->rf_alloc_ext_banks(ah);
110−}
111−
112−static inline void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah)
113−{
114− if (!ath9k_hw_private_ops(ah)->rf_free_ext_banks)
115− return;
116−
117− ath9k_hw_private_ops(ah)->rf_free_ext_banks(ah);
118−}
119−
120104 static inline bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
121105 struct ath9k_channel *chan,
122106 u16 modesIndex)
drivers/net/wireless/ath/ath9k/hw.c+12−36
@@ -54,11 +54,6 @@ static void ath9k_hw_init_cal_settings(struct ath_hw *ah) · 53 unmodified lines
5454 ath9k_hw_private_ops(ah)->init_cal_settings(ah);
5555 }
5656
57−static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
58−{
59− ath9k_hw_private_ops(ah)->init_mode_regs(ah);
60−}
61−
6257 static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah,
6358 struct ath9k_channel *chan)
6459 {
@@ -208,7 +203,7 @@ void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan, · 143 unmodified lines
208203 udelay(hw_delay + BASE_ACTIVATE_DELAY);
209204 }
210205
211−void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array,
206+void ath9k_hw_write_array(struct ath_hw *ah, const struct ar5416IniArray *array,
212207 int column, unsigned int *writecnt)
213208 {
214209 int r;
@@ -554,28 +549,19 @@ static int ath9k_hw_post_init(struct ath_hw *ah) · 339 unmodified lines
554549 ah->eep_ops->get_eeprom_ver(ah),
555550 ah->eep_ops->get_eeprom_rev(ah));
556551
557− ecode = ath9k_hw_rf_alloc_ext_banks(ah);
558− if (ecode) {
559− ath_err(ath9k_hw_common(ah),
560− "Failed allocating banks for external radio\n");
561− ath9k_hw_rf_free_ext_banks(ah);
562− return ecode;
563− }
564−
565− if (ah->config.enable_ani) {
566− ath9k_hw_ani_setup(ah);
552+ if (ah->config.enable_ani)
567553 ath9k_hw_ani_init(ah);
568− }
569554
570555 return 0;
571556 }
572557
573−static void ath9k_hw_attach_ops(struct ath_hw *ah)
558+static int ath9k_hw_attach_ops(struct ath_hw *ah)
574559 {
575− if (AR_SREV_9300_20_OR_LATER(ah))
576− ar9003_hw_attach_ops(ah);
577− else
578− ar9002_hw_attach_ops(ah);
560+ if (!AR_SREV_9300_20_OR_LATER(ah))
561+ return ar9002_hw_attach_ops(ah);
562+
563+ ar9003_hw_attach_ops(ah);
564+ return 0;
579565 }
580566
581567 /* Called for all hardware families */
@@ -611,7 +597,9 @@ static int __ath9k_hw_init(struct ath_hw *ah) · 29 unmodified lines
611597 ath9k_hw_init_defaults(ah);
612598 ath9k_hw_init_config(ah);
613599
614− ath9k_hw_attach_ops(ah);
600+ r = ath9k_hw_attach_ops(ah);
601+ if (r)
602+ return r;
615603
616604 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
617605 ath_err(common, "Couldn't wakeup chip\n");
@@ -675,8 +663,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) · 57 unmodified lines
675663 if (!AR_SREV_9300_20_OR_LATER(ah))
676664 ah->ani_function &= ~ATH9K_ANI_MRC_CCK;
677665
678− ath9k_hw_init_mode_regs(ah);
679−
680666 if (!ah->is_pciexpress)
681667 ath9k_hw_disablepcie(ah);
682668
@@ -1153,12 +1139,9 @@ void ath9k_hw_deinit(struct ath_hw *ah) · 470 unmodified lines
11531139 struct ath_common *common = ath9k_hw_common(ah);
11541140
11551141 if (common->state < ATH_HW_INITIALIZED)
1156− goto free_hw;
1142+ return;
11571143
11581144 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
1159−
1160−free_hw:
1161− ath9k_hw_rf_free_ext_banks(ah);
11621145 }
11631146 EXPORT_SYMBOL(ath9k_hw_deinit);
11641147
@@ -2576,12 +2559,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) · 1411 unmodified lines
25762559 rx_chainmask >>= 1;
25772560 }
25782561
2579− if (AR_SREV_9300_20_OR_LATER(ah)) {
2580− ah->enabled_cals |= TX_IQ_CAL;
2581− if (AR_SREV_9485_OR_LATER(ah))
2582− ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
2583− }
2584−
25852562 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
25862563 if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE))
25872564 pCap->hw_caps |= ATH9K_HW_CAP_MCI;
@@ -2590,7 +2567,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) · 2 unmodified lines
25902567 pCap->hw_caps |= ATH9K_HW_CAP_RTT;
25912568 }
25922569
2593−
25942570 if (AR_SREV_9280_20_OR_LATER(ah)) {
25952571 pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE |
25962572 ATH9K_HW_WOW_PATTERN_MATCH_EXACT;
drivers/net/wireless/ath/ath9k/hw.h+45−14
@@ -397,6 +397,7 @@ enum ath9k_int { · 396 unmodified lines
397397 #define MAX_RTT_TABLE_ENTRY 6
398398 #define MAX_IQCAL_MEASUREMENT 8
399399 #define MAX_CL_TAB_ENTRY 16
400+#define CL_TAB_ENTRY(reg_base) (reg_base + (4 * j))
400401
401402 struct ath9k_hw_cal_data {
402403 u16 channel;
@@ -599,13 +600,10 @@ struct ath_hw_radar_conf { · 196 unmodified lines
599600 * @init_cal_settings: setup types of calibrations supported
600601 * @init_cal: starts actual calibration
601602 *
602− * @init_mode_regs: Initializes mode registers
603603 * @init_mode_gain_regs: Initialize TX/RX gain registers
604604 *
605605 * @rf_set_freq: change frequency
606606 * @spur_mitigate_freq: spur mitigation
607− * @rf_alloc_ext_banks:
608− * @rf_free_ext_banks:
609607 * @set_rf_regs:
610608 * @compute_pll_control: compute the PLL control value to use for
611609 * AR_RTC_PLL_CONTROL for a given channel
@@ -620,7 +618,6 @@ struct ath_hw_private_ops { · 8 unmodified lines
620618 void (*init_cal_settings)(struct ath_hw *ah);
621619 bool (*init_cal)(struct ath_hw *ah, struct ath9k_channel *chan);
622620
623− void (*init_mode_regs)(struct ath_hw *ah);
624621 void (*init_mode_gain_regs)(struct ath_hw *ah);
625622 void (*setup_calibration)(struct ath_hw *ah,
626623 struct ath9k_cal_list *currCal);
@@ -630,8 +627,6 @@ struct ath_hw_private_ops { · 3 unmodified lines
630627 struct ath9k_channel *chan);
631628 void (*spur_mitigate_freq)(struct ath_hw *ah,
632629 struct ath9k_channel *chan);
633− int (*rf_alloc_ext_banks)(struct ath_hw *ah);
634− void (*rf_free_ext_banks)(struct ath_hw *ah);
635630 bool (*set_rf_regs)(struct ath_hw *ah,
636631 struct ath9k_channel *chan,
637632 u16 modesIndex);
@@ -660,6 +655,37 @@ struct ath_hw_private_ops { · 22 unmodified lines
660655 void (*ani_cache_ini_regs)(struct ath_hw *ah);
661656 };
662657
658+/**
659+ * struct ath_spec_scan - parameters for Atheros spectral scan
660+ *
661+ * @enabled: enable/disable spectral scan
662+ * @short_repeat: controls whether the chip is in spectral scan mode
663+ * for 4 usec (enabled) or 204 usec (disabled)
664+ * @count: number of scan results requested. There are special meanings
665+ * in some chip revisions:
666+ * AR92xx: highest bit set (>=128) for endless mode
667+ * (spectral scan won't stopped until explicitly disabled)
668+ * AR9300 and newer: 0 for endless mode
669+ * @endless: true if endless mode is intended. Otherwise, count value is
670+ * corrected to the next possible value.
671+ * @period: time duration between successive spectral scan entry points
672+ * (period*256*Tclk). Tclk = ath_common->clockrate
673+ * @fft_period: PHY passes FFT frames to MAC every (fft_period+1)*4uS
674+ *
675+ * Note: Tclk = 40MHz or 44MHz depending upon operating mode.
676+ * Typically it's 44MHz in 2/5GHz on later chips, but there's
677+ * a "fast clock" check for this in 5GHz.
678+ *
679+ */
680+struct ath_spec_scan {
681+ bool enabled;
682+ bool short_repeat;
683+ bool endless;
684+ u8 count;
685+ u8 period;
686+ u8 fft_period;
687+};
688+
663689 /**
664690 * struct ath_hw_ops - callbacks used by hardware code and driver code
665691 *
@@ -668,6 +694,10 @@ struct ath_hw_private_ops { · 2 unmodified lines
668694 *
669695 * @config_pci_powersave:
670696 * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
697+ *
698+ * @spectral_scan_config: set parameters for spectral scan and enable/disable it
699+ * @spectral_scan_trigger: trigger a spectral scan run
700+ * @spectral_scan_wait: wait for a spectral scan run to finish
671701 */
672702 struct ath_hw_ops {
673703 void (*config_pci_powersave)(struct ath_hw *ah,
@@ -688,6 +718,10 @@ struct ath_hw_ops { · 14 unmodified lines
688718 void (*antdiv_comb_conf_set)(struct ath_hw *ah,
689719 struct ath_hw_antcomb_conf *antconf);
690720 void (*antctrl_shared_chain_lnadiv)(struct ath_hw *hw, bool enable);
721+ void (*spectral_scan_config)(struct ath_hw *ah,
722+ struct ath_spec_scan *param);
723+ void (*spectral_scan_trigger)(struct ath_hw *ah);
724+ void (*spectral_scan_wait)(struct ath_hw *ah);
691725 };
692726
693727 struct ath_nf_limits {
@@ -710,6 +744,7 @@ enum ath_cal_list { · 16 unmodified lines
710744 struct ath_hw {
711745 struct ath_ops reg_ops;
712746
747+ struct device *dev;
713748 struct ieee80211_hw *hw;
714749 struct ath_common common;
715750 struct ath9k_hw_version hw_version;
@@ -771,7 +806,6 @@ struct ath_hw { · 55 unmodified lines
771806 struct ath9k_cal_list iq_caldata;
772807 struct ath9k_cal_list adcgain_caldata;
773808 struct ath9k_cal_list adcdc_caldata;
774− struct ath9k_cal_list tempCompCalData;
775809 struct ath9k_cal_list *cal_list;
776810 struct ath9k_cal_list *cal_list_last;
777811 struct ath9k_cal_list *cal_list_curr;
@@ -830,10 +864,6 @@ struct ath_hw { · 52 unmodified lines
830864 /* ANI */
831865 u32 proc_phyerr;
832866 u32 aniperiod;
833− int totalSizeDesired[5];
834− int coarse_high[5];
835− int coarse_low[5];
836− int firpwr[5];
837867 enum ath9k_ani_cmd ani_function;
838868 u32 ani_skip_count;
839869
@@ -979,7 +1009,7 @@ void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); · 139 unmodified lines
9791009 void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan,
9801010 int hw_delay);
9811011 bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
982−void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array,
1012+void ath9k_hw_write_array(struct ath_hw *ah, const struct ar5416IniArray *array,
9831013 int column, unsigned int *writecnt);
9841014 u32 ath9k_hw_reverse_bits(u32 val, u32 n);
9851015 u16 ath9k_hw_computetxtime(struct ath_hw *ah,
@@ -1066,16 +1096,17 @@ void ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain); · 80 unmodified lines
10661096 int ar9003_paprd_init_table(struct ath_hw *ah);
10671097 bool ar9003_paprd_is_done(struct ath_hw *ah);
10681098 bool ar9003_is_paprd_enabled(struct ath_hw *ah);
1099+void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
10691100
10701101 /* Hardware family op attach helpers */
1071−void ar5008_hw_attach_phy_ops(struct ath_hw *ah);
1102+int ar5008_hw_attach_phy_ops(struct ath_hw *ah);
10721103 void ar9002_hw_attach_phy_ops(struct ath_hw *ah);
10731104 void ar9003_hw_attach_phy_ops(struct ath_hw *ah);
10741105
10751106 void ar9002_hw_attach_calib_ops(struct ath_hw *ah);
10761107 void ar9003_hw_attach_calib_ops(struct ath_hw *ah);
10771108
1078−void ar9002_hw_attach_ops(struct ath_hw *ah);
1109+int ar9002_hw_attach_ops(struct ath_hw *ah);
10791110 void ar9003_hw_attach_ops(struct ath_hw *ah);
10801111
10811112 void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan);
drivers/net/wireless/ath/ath9k/init.c+37−70
@@ -20,6 +20,7 @@ · 19 unmodified lines
2020 #include <linux/slab.h>
2121 #include <linux/ath9k_platform.h>
2222 #include <linux/module.h>
23+#include <linux/relay.h>
2324
2425 #include "ath9k.h"
2526
@@ -334,7 +335,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, · 308 unmodified lines
334335 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
335336 u8 *ds;
336337 struct ath_buf *bf;
337− int i, bsize, error, desc_len;
338+ int i, bsize, desc_len;
338339
339340 ath_dbg(common, CONFIG, "%s DMA: %u buffers %u desc/buf\n",
340341 name, nbuf, ndesc);
@@ -350,8 +351,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, · 9 unmodified lines
350351 if ((desc_len % 4) != 0) {
351352 ath_err(common, "ath_desc not DWORD aligned\n");
352353 BUG_ON((desc_len % 4) != 0);
353− error = -ENOMEM;
354− goto fail;
354+ return -ENOMEM;
355355 }
356356
357357 dd->dd_desc_len = desc_len * nbuf * ndesc;
@@ -375,12 +375,11 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, · 17 unmodified lines
375375 }
376376
377377 /* allocate descriptors */
378− dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
379− &dd->dd_desc_paddr, GFP_KERNEL);
380− if (dd->dd_desc == NULL) {
381− error = -ENOMEM;
382− goto fail;
383− }
378+ dd->dd_desc = dmam_alloc_coherent(sc->dev, dd->dd_desc_len,
379+ &dd->dd_desc_paddr, GFP_KERNEL);
380+ if (!dd->dd_desc)
381+ return -ENOMEM;
382+
384383 ds = (u8 *) dd->dd_desc;
385384 ath_dbg(common, CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
386385 name, ds, (u32) dd->dd_desc_len,
@@ -388,12 +387,9 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, · 1 unmodified line
388387
389388 /* allocate buffers */
390389 bsize = sizeof(struct ath_buf) * nbuf;
391− bf = kzalloc(bsize, GFP_KERNEL);
392− if (bf == NULL) {
393− error = -ENOMEM;
394− goto fail2;
395− }
396− dd->dd_bufptr = bf;
390+ bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL);
391+ if (!bf)
392+ return -ENOMEM;
397393
398394 for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
399395 bf->bf_desc = ds;
@@ -419,12 +415,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, · 19 unmodified lines
419415 list_add_tail(&bf->list, head);
420416 }
421417 return 0;
422−fail2:
423− dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
424− dd->dd_desc_paddr);
425−fail:
426− memset(dd, 0, sizeof(*dd));
427− return error;
428418 }
429419
430420 static int ath9k_init_queues(struct ath_softc *sc)
@@ -454,11 +444,13 @@ static int ath9k_init_channels_rates(struct ath_softc *sc) · 23 unmodified lines
454444 ATH9K_NUM_CHANNELS);
455445
456446 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
457− channels = kmemdup(ath9k_2ghz_chantable,
447+ channels = devm_kzalloc(sc->dev,
458448 sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
459449 if (!channels)
460450 return -ENOMEM;
461451
452+ memcpy(channels, ath9k_2ghz_chantable,
453+ sizeof(ath9k_2ghz_chantable));
462454 sc->sbands[IEEE80211_BAND_2GHZ].channels = channels;
463455 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
464456 sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
@@ -469,14 +461,13 @@ static int ath9k_init_channels_rates(struct ath_softc *sc) · 4 unmodified lines
469461 }
470462
471463 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
472− channels = kmemdup(ath9k_5ghz_chantable,
464+ channels = devm_kzalloc(sc->dev,
473465 sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
474− if (!channels) {
475− if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
476− kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
466+ if (!channels)
477467 return -ENOMEM;
478− }
479468
469+ memcpy(channels, ath9k_5ghz_chantable,
470+ sizeof(ath9k_5ghz_chantable));
480471 sc->sbands[IEEE80211_BAND_5GHZ].channels = channels;
481472 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
482473 sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
@@ -562,10 +553,11 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, · 79 unmodified lines
562553 int ret = 0, i;
563554 int csz = 0;
564555
565− ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
556+ ah = devm_kzalloc(sc->dev, sizeof(struct ath_hw), GFP_KERNEL);
566557 if (!ah)
567558 return -ENOMEM;
568559
560+ ah->dev = sc->dev;
569561 ah->hw = sc->hw;
570562 ah->hw_version.devid = devid;
571563 ah->reg_ops.read = ath9k_ioread32;
@@ -633,7 +625,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, · 61 unmodified lines
633625 if (pdata && pdata->eeprom_name) {
634626 ret = ath9k_eeprom_request(sc, pdata->eeprom_name);
635627 if (ret)
636− goto err_eeprom;
628+ return ret;
637629 }
638630
639631 /* Initializes the hardware for all supported chipsets */
@@ -673,10 +665,6 @@ err_queues: · 33 unmodified lines
673665 ath9k_hw_deinit(ah);
674666 err_hw:
675667 ath9k_eeprom_release(sc);
676−err_eeprom:
677− kfree(ah);
678− sc->sc_ah = NULL;
679−
680668 return ret;
681669 }
682670
@@ -841,8 +829,8 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, · 158 unmodified lines
841829
842830 /* Bring up device */
843831 error = ath9k_init_softc(devid, sc, bus_ops);
844− if (error != 0)
845− goto error_init;
832+ if (error)
833+ return error;
846834
847835 ah = sc->sc_ah;
848836 common = ath9k_hw_common(ah);
@@ -852,19 +840,19 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, · 3 unmodified lines
852840 error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
853841 ath9k_reg_notifier);
854842 if (error)
855− goto error_regd;
843+ goto deinit;
856844
857845 reg = &common->regulatory;
858846
859847 /* Setup TX DMA */
860848 error = ath_tx_init(sc, ATH_TXBUF);
861849 if (error != 0)
862− goto error_tx;
850+ goto deinit;
863851
864852 /* Setup RX DMA */
865853 error = ath_rx_init(sc, ATH_RXBUF);
866854 if (error != 0)
867− goto error_rx;
855+ goto deinit;
868856
869857 ath9k_init_txpower_limits(sc);
870858
@@ -878,19 +866,19 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, · 7 unmodified lines
878866 /* Register with mac80211 */
879867 error = ieee80211_register_hw(hw);
880868 if (error)
881− goto error_register;
869+ goto rx_cleanup;
882870
883871 error = ath9k_init_debug(ah);
884872 if (error) {
885873 ath_err(common, "Unable to create debugfs files\n");
886− goto error_world;
874+ goto unregister;
887875 }
888876
889877 /* Handle world regulatory */
890878 if (!ath_is_world_regd(reg)) {
891879 error = regulatory_hint(hw->wiphy, reg->alpha2);
892880 if (error)
893− goto error_world;
881+ goto unregister;
894882 }
895883
896884 ath_init_leds(sc);
@@ -898,17 +886,12 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, · 1 unmodified line
898886
899887 return 0;
900888
901−error_world:
889+unregister:
902890 ieee80211_unregister_hw(hw);
903−error_register:
891+rx_cleanup:
904892 ath_rx_cleanup(sc);
905−error_rx:
906− ath_tx_cleanup(sc);
907−error_tx:
908− /* Nothing */
909−error_regd:
893+deinit:
910894 ath9k_deinit_softc(sc);
911−error_init:
912895 return error;
913896 }
914897
@@ -920,12 +903,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc) · 5 unmodified lines
920903 {
921904 int i = 0;
922905
923− if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
924− kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
925−
926− if (sc->sbands[IEEE80211_BAND_5GHZ].channels)
927− kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels);
928−
929906 ath9k_deinit_btcoex(sc);
930907
931908 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
@@ -937,8 +914,11 @@ static void ath9k_deinit_softc(struct ath_softc *sc) · 5 unmodified lines
937914 sc->dfs_detector->exit(sc->dfs_detector);
938915
939916 ath9k_eeprom_release(sc);
940− kfree(sc->sc_ah);
941− sc->sc_ah = NULL;
917+
918+ if (sc->rfs_chan_spec_scan) {
919+ relay_close(sc->rfs_chan_spec_scan);
920+ sc->rfs_chan_spec_scan = NULL;
921+ }
942922 }
943923
944924 void ath9k_deinit_device(struct ath_softc *sc)
@@ -954,22 +934,9 @@ void ath9k_deinit_device(struct ath_softc *sc) · 9 unmodified lines
954934
955935 ieee80211_unregister_hw(hw);
956936 ath_rx_cleanup(sc);
957− ath_tx_cleanup(sc);
958937 ath9k_deinit_softc(sc);
959938 }
960939
961−void ath_descdma_cleanup(struct ath_softc *sc,
962− struct ath_descdma *dd,
963− struct list_head *head)
964−{
965− dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
966− dd->dd_desc_paddr);
967−
968− INIT_LIST_HEAD(head);
969− kfree(dd->dd_bufptr);
970− memset(dd, 0, sizeof(*dd));
971−}
972−
973940 /************************/
974941 /* Module Hooks */
975942 /************************/
drivers/net/wireless/ath/ath9k/mac.h+2−1
@@ -226,7 +226,8 @@ enum ath9k_phyerr { · 225 unmodified lines
226226 ATH9K_PHYERR_HT_LENGTH_ILLEGAL = 35,
227227 ATH9K_PHYERR_HT_RATE_ILLEGAL = 36,
228228
229− ATH9K_PHYERR_MAX = 37,
229+ ATH9K_PHYERR_SPECTRAL = 38,
230+ ATH9K_PHYERR_MAX = 39,
230231 };
231232
232233 struct ath_desc {
drivers/net/wireless/ath/ath9k/main.c+126−33
@@ -182,7 +182,7 @@ static void ath_restart_work(struct ath_softc *sc) · 181 unmodified lines
182182 ath_start_ani(sc);
183183 }
184184
185−static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
185+static bool ath_prepare_reset(struct ath_softc *sc)
186186 {
187187 struct ath_hw *ah = sc->sc_ah;
188188 bool ret = true;
@@ -196,20 +196,12 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) · 7 unmodified lines
196196 ath9k_debug_samp_bb_mac(sc);
197197 ath9k_hw_disable_interrupts(ah);
198198
199− if (!ath_stoprecv(sc))
199+ if (!ath_drain_all_txq(sc))
200200 ret = false;
201201
202− if (!ath_drain_all_txq(sc, retry_tx))
202+ if (!ath_stoprecv(sc))
203203 ret = false;
204204
205− if (!flush) {
206− if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
207− ath_rx_tasklet(sc, 1, true);
208− ath_rx_tasklet(sc, 1, false);
209− } else {
210− ath_flushrecv(sc);
211− }
212−
213205 return ret;
214206 }
215207
@@ -255,18 +247,17 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) · 39 unmodified lines
255247 return true;
256248 }
257249
258−static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
259− bool retry_tx)
250+static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
260251 {
261252 struct ath_hw *ah = sc->sc_ah;
262253 struct ath_common *common = ath9k_hw_common(ah);
263254 struct ath9k_hw_cal_data *caldata = NULL;
264255 bool fastcc = true;
265− bool flush = false;
266256 int r;
267257
268258 __ath_cancel_work(sc);
269259
260+ tasklet_disable(&sc->intr_tq);
270261 spin_lock_bh(&sc->sc_pcu_lock);
271262
272263 if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
@@ -276,11 +267,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, · 3 unmodified lines
276267
277268 if (!hchan) {
278269 fastcc = false;
279− flush = true;
280270 hchan = ah->curchan;
281271 }
282272
283− if (!ath_prepare_reset(sc, retry_tx, flush))
273+ if (!ath_prepare_reset(sc))
284274 fastcc = false;
285275
286276 ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n",
@@ -302,6 +292,8 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, · 15 unmodified lines
302292
303293 out:
304294 spin_unlock_bh(&sc->sc_pcu_lock);
295+ tasklet_enable(&sc->intr_tq);
296+
305297 return r;
306298 }
307299
@@ -319,7 +311,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, · 11 unmodified lines
319311 if (test_bit(SC_OP_INVALID, &sc->sc_flags))
320312 return -EIO;
321313
322− r = ath_reset_internal(sc, hchan, false);
314+ r = ath_reset_internal(sc, hchan);
323315
324316 return r;
325317 }
@@ -549,23 +541,21 @@ chip_reset: · 223 unmodified lines
549541 #undef SCHED_INTR
550542 }
551543
552−static int ath_reset(struct ath_softc *sc, bool retry_tx)
544+static int ath_reset(struct ath_softc *sc)
553545 {
554− int r;
546+ int i, r;
555547
556548 ath9k_ps_wakeup(sc);
557549
558− r = ath_reset_internal(sc, NULL, retry_tx);
550+ r = ath_reset_internal(sc, NULL);
559551
560− if (retry_tx) {
561− int i;
562− for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
563− if (ATH_TXQ_SETUP(sc, i)) {
564− spin_lock_bh(&sc->tx.txq[i].axq_lock);
565− ath_txq_schedule(sc, &sc->tx.txq[i]);
566− spin_unlock_bh(&sc->tx.txq[i].axq_lock);
567− }
568− }
552+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
553+ if (!ATH_TXQ_SETUP(sc, i))
554+ continue;
555+
556+ spin_lock_bh(&sc->tx.txq[i].axq_lock);
557+ ath_txq_schedule(sc, &sc->tx.txq[i]);
558+ spin_unlock_bh(&sc->tx.txq[i].axq_lock);
569559 }
570560
571561 ath9k_ps_restore(sc);
@@ -586,7 +576,7 @@ void ath_reset_work(struct work_struct *work) · 14 unmodified lines
586576 {
587577 struct ath_softc *sc = container_of(work, struct ath_softc, hw_reset_work);
588578
589− ath_reset(sc, true);
579+ ath_reset(sc);
590580 }
591581
592582 /**********************/
@@ -804,7 +794,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) · 211 unmodified lines
804794 ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
805795 }
806796
807− ath_prepare_reset(sc, false, true);
797+ ath_prepare_reset(sc);
808798
809799 if (sc->rx.frag) {
810800 dev_kfree_skb_any(sc->rx.frag);
@@ -1075,6 +1065,86 @@ static void ath9k_disable_ps(struct ath_softc *sc) · 264 unmodified lines
10751065 ath_dbg(common, PS, "PowerSave disabled\n");
10761066 }
10771067
1068+void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw)
1069+{
1070+ struct ath_softc *sc = hw->priv;
1071+ struct ath_hw *ah = sc->sc_ah;
1072+ struct ath_common *common = ath9k_hw_common(ah);
1073+ u32 rxfilter;
1074+
1075+ if (!ath9k_hw_ops(ah)->spectral_scan_trigger) {
1076+ ath_err(common, "spectrum analyzer not implemented on this hardware\n");
1077+ return;
1078+ }
1079+
1080+ ath9k_ps_wakeup(sc);
1081+ rxfilter = ath9k_hw_getrxfilter(ah);
1082+ ath9k_hw_setrxfilter(ah, rxfilter |
1083+ ATH9K_RX_FILTER_PHYRADAR |
1084+ ATH9K_RX_FILTER_PHYERR);
1085+
1086+ /* TODO: usually this should not be neccesary, but for some reason
1087+ * (or in some mode?) the trigger must be called after the
1088+ * configuration, otherwise the register will have its values reset
1089+ * (on my ar9220 to value 0x01002310)
1090+ */
1091+ ath9k_spectral_scan_config(hw, sc->spectral_mode);
1092+ ath9k_hw_ops(ah)->spectral_scan_trigger(ah);
1093+ ath9k_ps_restore(sc);
1094+}
1095+
1096+int ath9k_spectral_scan_config(struct ieee80211_hw *hw,
1097+ enum spectral_mode spectral_mode)
1098+{
1099+ struct ath_softc *sc = hw->priv;
1100+ struct ath_hw *ah = sc->sc_ah;
1101+ struct ath_common *common = ath9k_hw_common(ah);
1102+ struct ath_spec_scan param;
1103+
1104+ if (!ath9k_hw_ops(ah)->spectral_scan_trigger) {
1105+ ath_err(common, "spectrum analyzer not implemented on this hardware\n");
1106+ return -1;
1107+ }
1108+
1109+ /* NOTE: this will generate a few samples ...
1110+ *
1111+ * TODO: review default parameters, and/or define an interface to set
1112+ * them.
1113+ */
1114+ param.enabled = 1;
1115+ param.short_repeat = true;
1116+ param.count = 8;
1117+ param.endless = false;
1118+ param.period = 0xFF;
1119+ param.fft_period = 0xF;
1120+
1121+ switch (spectral_mode) {
1122+ case SPECTRAL_DISABLED:
1123+ param.enabled = 0;
1124+ break;
1125+ case SPECTRAL_BACKGROUND:
1126+ /* send endless samples.
1127+ * TODO: is this really useful for "background"?
1128+ */
1129+ param.endless = 1;
1130+ break;
1131+ case SPECTRAL_CHANSCAN:
1132+ break;
1133+ case SPECTRAL_MANUAL:
1134+ break;
1135+ default:
1136+ return -1;
1137+ }
1138+
1139+ ath9k_ps_wakeup(sc);
1140+ ath9k_hw_ops(ah)->spectral_scan_config(ah, &param);
1141+ ath9k_ps_restore(sc);
1142+
1143+ sc->spectral_mode = spectral_mode;
1144+
1145+ return 0;
1146+}
1147+
10781148 static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
10791149 {
10801150 struct ath_softc *sc = hw->priv;
@@ -1188,6 +1258,11 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) · 107 unmodified lines
11881258 */
11891259 if (old_pos >= 0)
11901260 ath_update_survey_nf(sc, old_pos);
1261+
1262+ /* perform spectral scan if requested. */
1263+ if (sc->scanning && sc->spectral_mode == SPECTRAL_CHANSCAN)
1264+ ath9k_spectral_scan_trigger(hw);
1265+
11911266 }
11921267
11931268 if (changed & IEEE80211_CONF_CHANGE_POWER) {
@@ -1731,11 +1806,11 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) · 537 unmodified lines
17311806 if (drop) {
17321807 ath9k_ps_wakeup(sc);
17331808 spin_lock_bh(&sc->sc_pcu_lock);
1734− drain_txq = ath_drain_all_txq(sc, false);
1809+ drain_txq = ath_drain_all_txq(sc);
17351810 spin_unlock_bh(&sc->sc_pcu_lock);
17361811
17371812 if (!drain_txq)
1738− ath_reset(sc, false);
1813+ ath_reset(sc);
17391814
17401815 ath9k_ps_restore(sc);
17411816 ieee80211_wake_queues(hw);
@@ -1835,6 +1910,9 @@ static u32 fill_chainmask(u32 cap, u32 new) · 93 unmodified lines
18351910
18361911 static bool validate_antenna_mask(struct ath_hw *ah, u32 val)
18371912 {
1913+ if (AR_SREV_9300_20_OR_LATER(ah))
1914+ return true;
1915+
18381916 switch (val & 0x7) {
18391917 case 0x1:
18401918 case 0x3:
@@ -2240,6 +2318,19 @@ static void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled) · 399 unmodified lines
22402318 }
22412319
22422320 #endif
2321+static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
2322+{
2323+ struct ath_softc *sc = hw->priv;
2324+
2325+ sc->scanning = 1;
2326+}
2327+
2328+static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
2329+{
2330+ struct ath_softc *sc = hw->priv;
2331+
2332+ sc->scanning = 0;
2333+}
22432334
22442335 struct ieee80211_ops ath9k_ops = {
22452336 .tx = ath9k_tx,
@@ -2286,4 +2377,6 @@ struct ieee80211_ops ath9k_ops = { · 40 unmodified lines
22862377 .sta_add_debugfs = ath9k_sta_add_debugfs,
22872378 .sta_remove_debugfs = ath9k_sta_remove_debugfs,
22882379 #endif
2380+ .sw_scan_start = ath9k_sw_scan_start,
2381+ .sw_scan_complete = ath9k_sw_scan_complete,
22892382 };
drivers/net/wireless/ath/ath9k/mci.c+1−6
@@ -438,7 +438,7 @@ int ath_mci_setup(struct ath_softc *sc) · 437 unmodified lines
438438 struct ath_mci_buf *buf = &mci->sched_buf;
439439 int ret;
440440
441− buf->bf_addr = dma_alloc_coherent(sc->dev,
441+ buf->bf_addr = dmam_alloc_coherent(sc->dev,
442442 ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE,
443443 &buf->bf_paddr, GFP_KERNEL);
444444
@@ -477,11 +477,6 @@ void ath_mci_cleanup(struct ath_softc *sc) · 32 unmodified lines
477477 struct ath_mci_coex *mci = &sc->mci_coex;
478478 struct ath_mci_buf *buf = &mci->sched_buf;
479479
480− if (buf->bf_addr)
481− dma_free_coherent(sc->dev,
482− ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE,
483− buf->bf_addr, buf->bf_paddr);
484−
485480 ar9003_mci_cleanup(ah);
486481
487482 ath_dbg(common, MCI, "MCI De-Initialized\n");
drivers/net/wireless/ath/ath9k/pci.c+8−31
@@ -147,7 +147,6 @@ static const struct ath_bus_ops ath_pci_bus_ops = { · 146 unmodified lines
147147
148148 static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
149149 {
150− void __iomem *mem;
151150 struct ath_softc *sc;
152151 struct ieee80211_hw *hw;
153152 u8 csz;
@@ -155,19 +154,19 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 1 unmodified line
155154 int ret = 0;
156155 char hw_name[64];
157156
158− if (pci_enable_device(pdev))
157+ if (pcim_enable_device(pdev))
159158 return -EIO;
160159
161160 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
162161 if (ret) {
163162 pr_err("32-bit DMA not available\n");
164− goto err_dma;
163+ return ret;
165164 }
166165
167166 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
168167 if (ret) {
169168 pr_err("32-bit DMA consistent DMA enable failed\n");
170− goto err_dma;
169+ return ret;
171170 }
172171
173172 /*
@@ -203,25 +202,16 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 29 unmodified lines
203202 if ((val & 0x0000ff00) != 0)
204203 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
205204
206− ret = pci_request_region(pdev, 0, "ath9k");
205+ ret = pcim_iomap_regions(pdev, BIT(0), "ath9k");
207206 if (ret) {
208207 dev_err(&pdev->dev, "PCI memory region reserve error\n");
209− ret = -ENODEV;
210− goto err_region;
211− }
212−
213− mem = pci_iomap(pdev, 0, 0);
214− if (!mem) {
215− pr_err("PCI memory map error\n") ;
216− ret = -EIO;
217− goto err_iomap;
208+ return -ENODEV;
218209 }
219210
220211 hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
221212 if (!hw) {
222213 dev_err(&pdev->dev, "No memory for ieee80211_hw\n");
223− ret = -ENOMEM;
224− goto err_alloc_hw;
214+ return -ENOMEM;
225215 }
226216
227217 SET_IEEE80211_DEV(hw, &pdev->dev);
@@ -230,7 +220,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 2 unmodified lines
230220 sc = hw->priv;
231221 sc->hw = hw;
232222 sc->dev = &pdev->dev;
233− sc->mem = mem;
223+ sc->mem = pcim_iomap_table(pdev)[0];
234224
235225 /* Will be cleared in ath9k_start() */
236226 set_bit(SC_OP_INVALID, &sc->sc_flags);
@@ -251,7 +241,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 14 unmodified lines
251241
252242 ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name));
253243 wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
254− hw_name, (unsigned long)mem, pdev->irq);
244+ hw_name, (unsigned long)sc->mem, pdev->irq);
255245
256246 return 0;
257247
@@ -259,14 +249,6 @@ err_init: · 1 unmodified line
259249 free_irq(sc->irq, sc);
260250 err_irq:
261251 ieee80211_free_hw(hw);
262−err_alloc_hw:
263− pci_iounmap(pdev, mem);
264−err_iomap:
265− pci_release_region(pdev, 0);
266−err_region:
267− /* Nothing */
268−err_dma:
269− pci_disable_device(pdev);
270252 return ret;
271253 }
272254
@@ -274,17 +256,12 @@ static void ath_pci_remove(struct pci_dev *pdev) · 1 unmodified line
274256 {
275257 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
276258 struct ath_softc *sc = hw->priv;
277− void __iomem *mem = sc->mem;
278259
279260 if (!is_ath9k_unloaded)
280261 sc->sc_ah->ah_flags |= AH_UNPLUGGED;
281262 ath9k_deinit_device(sc);
282263 free_irq(sc->irq, sc);
283264 ieee80211_free_hw(sc->hw);
284−
285− pci_iounmap(pdev, mem);
286− pci_disable_device(pdev);
287− pci_release_region(pdev, 0);
288265 }
289266
290267 #ifdef CONFIG_PM_SLEEP
drivers/net/wireless/ath/ath9k/recv.c+122−49
@@ -15,6 +15,7 @@ · 14 unmodified lines
1515 */
1616
1717 #include <linux/dma-mapping.h>
18+#include <linux/relay.h>
1819 #include "ath9k.h"
1920 #include "ar9003_mac.h"
2021
@@ -180,11 +181,6 @@ static void ath_rx_edma_cleanup(struct ath_softc *sc) · 159 unmodified lines
180181 bf->bf_mpdu = NULL;
181182 }
182183 }
183−
184− INIT_LIST_HEAD(&sc->rx.rxbuf);
185−
186− kfree(sc->rx.rx_bufptr);
187− sc->rx.rx_bufptr = NULL;
188184 }
189185
190186 static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size)
@@ -211,12 +207,11 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs) · 20 unmodified lines
211207 ah->caps.rx_hp_qdepth);
212208
213209 size = sizeof(struct ath_buf) * nbufs;
214− bf = kzalloc(size, GFP_KERNEL);
210+ bf = devm_kzalloc(sc->dev, size, GFP_KERNEL);
215211 if (!bf)
216212 return -ENOMEM;
217213
218214 INIT_LIST_HEAD(&sc->rx.rxbuf);
219− sc->rx.rx_bufptr = bf;
220215
221216 for (i = 0; i < nbufs; i++, bf++) {
222217 skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_KERNEL);
@@ -254,8 +249,6 @@ rx_init_fail: · 31 unmodified lines
254249
255250 static void ath_edma_start_recv(struct ath_softc *sc)
256251 {
257− spin_lock_bh(&sc->rx.rxbuflock);
258−
259252 ath9k_hw_rxena(sc->sc_ah);
260253
261254 ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP,
@@ -267,8 +260,6 @@ static void ath_edma_start_recv(struct ath_softc *sc) · 5 unmodified lines
267260 ath_opmode_init(sc);
268261
269262 ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
270−
271− spin_unlock_bh(&sc->rx.rxbuflock);
272263 }
273264
274265 static void ath_edma_stop_recv(struct ath_softc *sc)
@@ -285,8 +276,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) · 10 unmodified lines
285276 int error = 0;
286277
287278 spin_lock_init(&sc->sc_pcu_lock);
288− spin_lock_init(&sc->rx.rxbuflock);
289− clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
290279
291280 common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +
292281 sc->sc_ah->caps.rx_status_len;
@@ -363,9 +352,6 @@ void ath_rx_cleanup(struct ath_softc *sc) · 70 unmodified lines
363352 bf->bf_mpdu = NULL;
364353 }
365354 }
366−
367− if (sc->rx.rxdma.dd_desc_len != 0)
368− ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
369355 }
370356 }
371357
@@ -447,7 +433,6 @@ int ath_startrecv(struct ath_softc *sc) · 75 unmodified lines
447433 return 0;
448434 }
449435
450− spin_lock_bh(&sc->rx.rxbuflock);
451436 if (list_empty(&sc->rx.rxbuf))
452437 goto start_recv;
453438
@@ -468,26 +453,31 @@ start_recv: · 14 unmodified lines
468453 ath_opmode_init(sc);
469454 ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
470455
471− spin_unlock_bh(&sc->rx.rxbuflock);
472−
473456 return 0;
474457 }
475458
459+static void ath_flushrecv(struct ath_softc *sc)
460+{
461+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
462+ ath_rx_tasklet(sc, 1, true);
463+ ath_rx_tasklet(sc, 1, false);
464+}
465+
476466 bool ath_stoprecv(struct ath_softc *sc)
477467 {
478468 struct ath_hw *ah = sc->sc_ah;
479469 bool stopped, reset = false;
480470
481− spin_lock_bh(&sc->rx.rxbuflock);
482471 ath9k_hw_abortpcurecv(ah);
483472 ath9k_hw_setrxfilter(ah, 0);
484473 stopped = ath9k_hw_stopdmarecv(ah, &reset);
485474
475+ ath_flushrecv(sc);
476+
486477 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
487478 ath_edma_stop_recv(sc);
488479 else
489480 sc->rx.rxlink = NULL;
490− spin_unlock_bh(&sc->rx.rxbuflock);
491481
492482 if (!(ah->ah_flags & AH_UNPLUGGED) &&
493483 unlikely(!stopped)) {
@@ -499,15 +489,6 @@ bool ath_stoprecv(struct ath_softc *sc) · 5 unmodified lines
499489 return stopped && !reset;
500490 }
501491
502−void ath_flushrecv(struct ath_softc *sc)
503−{
504− set_bit(SC_OP_RXFLUSH, &sc->sc_flags);
505− if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
506− ath_rx_tasklet(sc, 1, true);
507− ath_rx_tasklet(sc, 1, false);
508− clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
509−}
510−
511492 static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
512493 {
513494 /* Check whether the Beacon frame has DTIM indicating buffered bc/mc */
@@ -744,6 +725,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, · 230 unmodified lines
744725 return NULL;
745726 }
746727
728+ list_del(&bf->list);
747729 if (!bf->bf_mpdu)
748730 return bf;
749731
@@ -1034,6 +1016,108 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common, · 284 unmodified lines
10341016 rxs->flag &= ~RX_FLAG_DECRYPTED;
10351017 }
10361018
1019+static s8 fix_rssi_inv_only(u8 rssi_val)
1020+{
1021+ if (rssi_val == 128)
1022+ rssi_val = 0;
1023+ return (s8) rssi_val;
1024+}
1025+
1026+
1027+static void ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr,
1028+ struct ath_rx_status *rs, u64 tsf)
1029+{
1030+#ifdef CONFIG_ATH_DEBUG
1031+ struct ath_hw *ah = sc->sc_ah;
1032+ u8 bins[SPECTRAL_HT20_NUM_BINS];
1033+ u8 *vdata = (u8 *)hdr;
1034+ struct fft_sample_ht20 fft_sample;
1035+ struct ath_radar_info *radar_info;
1036+ struct ath_ht20_mag_info *mag_info;
1037+ int len = rs->rs_datalen;
1038+ int i, dc_pos;
1039+
1040+ /* AR9280 and before report via ATH9K_PHYERR_RADAR, AR93xx and newer
1041+ * via ATH9K_PHYERR_SPECTRAL. Haven't seen ATH9K_PHYERR_FALSE_RADAR_EXT
1042+ * yet, but this is supposed to be possible as well.
1043+ */
1044+ if (rs->rs_phyerr != ATH9K_PHYERR_RADAR &&
1045+ rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT &&
1046+ rs->rs_phyerr != ATH9K_PHYERR_SPECTRAL)
1047+ return;
1048+
1049+ /* Variation in the data length is possible and will be fixed later.
1050+ * Note that we only support HT20 for now.
1051+ *
1052+ * TODO: add HT20_40 support as well.
1053+ */
1054+ if ((len > SPECTRAL_HT20_TOTAL_DATA_LEN + 2) ||
1055+ (len < SPECTRAL_HT20_TOTAL_DATA_LEN - 1))
1056+ return;
1057+
1058+ /* check if spectral scan bit is set. This does not have to be checked
1059+ * if received through a SPECTRAL phy error, but shouldn't hurt.
1060+ */
1061+ radar_info = ((struct ath_radar_info *)&vdata[len]) - 1;
1062+ if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK))
1063+ return;
1064+
1065+ fft_sample.tlv.type = ATH_FFT_SAMPLE_HT20;
1066+ fft_sample.tlv.length = sizeof(fft_sample) - sizeof(fft_sample.tlv);
1067+
1068+ fft_sample.freq = ah->curchan->chan->center_freq;
1069+ fft_sample.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0);
1070+ fft_sample.noise = ah->noise;
1071+
1072+ switch (len - SPECTRAL_HT20_TOTAL_DATA_LEN) {
1073+ case 0:
1074+ /* length correct, nothing to do. */
1075+ memcpy(bins, vdata, SPECTRAL_HT20_NUM_BINS);
1076+ break;
1077+ case -1:
1078+ /* first byte missing, duplicate it. */
1079+ memcpy(&bins[1], vdata, SPECTRAL_HT20_NUM_BINS - 1);
1080+ bins[0] = vdata[0];
1081+ break;
1082+ case 2:
1083+ /* MAC added 2 extra bytes at bin 30 and 32, remove them. */
1084+ memcpy(bins, vdata, 30);
1085+ bins[30] = vdata[31];
1086+ memcpy(&bins[31], &vdata[33], SPECTRAL_HT20_NUM_BINS - 31);
1087+ break;
1088+ case 1:
1089+ /* MAC added 2 extra bytes AND first byte is missing. */
1090+ bins[0] = vdata[0];
1091+ memcpy(&bins[0], vdata, 30);
1092+ bins[31] = vdata[31];
1093+ memcpy(&bins[32], &vdata[33], SPECTRAL_HT20_NUM_BINS - 32);
1094+ break;
1095+ default:
1096+ return;
1097+ }
1098+
1099+ /* DC value (value in the middle) is the blind spot of the spectral
1100+ * sample and invalid, interpolate it.
1101+ */
1102+ dc_pos = SPECTRAL_HT20_NUM_BINS / 2;
1103+ bins[dc_pos] = (bins[dc_pos + 1] + bins[dc_pos - 1]) / 2;
1104+
1105+ /* mag data is at the end of the frame, in front of radar_info */
1106+ mag_info = ((struct ath_ht20_mag_info *)radar_info) - 1;
1107+
1108+ /* Apply exponent and grab further auxiliary information. */
1109+ for (i = 0; i < SPECTRAL_HT20_NUM_BINS; i++)
1110+ fft_sample.data[i] = bins[i] << mag_info->max_exp;
1111+
1112+ fft_sample.max_magnitude = spectral_max_magnitude(mag_info->all_bins);
1113+ fft_sample.max_index = spectral_max_index(mag_info->all_bins);
1114+ fft_sample.bitmap_weight = spectral_bitmap_weight(mag_info->all_bins);
1115+ fft_sample.tsf = tsf;
1116+
1117+ ath_debug_send_fft_sample(sc, &fft_sample.tlv);
1118+#endif
1119+}
1120+
10371121 int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
10381122 {
10391123 struct ath_buf *bf;
@@ -1059,16 +1143,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) · 19 unmodified lines
10591143 dma_type = DMA_FROM_DEVICE;
10601144
10611145 qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
1062− spin_lock_bh(&sc->rx.rxbuflock);
10631146
10641147 tsf = ath9k_hw_gettsf64(ah);
10651148 tsf_lower = tsf & 0xffffffff;
10661149
10671150 do {
10681151 bool decrypt_error = false;
1069− /* If handling rx interrupt and flush is in progress => exit */
1070− if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0))
1071− break;
10721152
10731153 memset(&rs, 0, sizeof(rs));
10741154 if (edma)
@@ -1111,15 +1191,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) · 36 unmodified lines
11111191
11121192 ath_debug_stat_rx(sc, &rs);
11131193
1114− /*
1115− * If we're asked to flush receive queue, directly
1116− * chain it back at the queue without processing it.
1117− */
1118− if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags)) {
1119− RX_STAT_INC(rx_drop_rxflush);
1120− goto requeue_drop_frag;
1121− }
1122−
11231194 memset(rxs, 0, sizeof(struct ieee80211_rx_status));
11241195
11251196 rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
@@ -1131,6 +1202,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) · 5 unmodified lines
11311202 unlikely(tsf_lower - rs.rs_tstamp > 0x10000000))
11321203 rxs->mactime += 0x100000000ULL;
11331204
1205+ if ((rs.rs_status & ATH9K_RXERR_PHY))
1206+ ath_process_fft(sc, hdr, &rs, rxs->mactime);
1207+
11341208 retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
11351209 rxs, &decrypt_error);
11361210 if (retval)
@@ -1254,19 +1328,18 @@ requeue_drop_frag: · 117 unmodified lines
12541328 sc->rx.frag = NULL;
12551329 }
12561330 requeue:
1331+ list_add_tail(&bf->list, &sc->rx.rxbuf);
1332+ if (flush)
1333+ continue;
1334+
12571335 if (edma) {
1258− list_add_tail(&bf->list, &sc->rx.rxbuf);
12591336 ath_rx_edma_buf_link(sc, qtype);
12601337 } else {
1261− list_move_tail(&bf->list, &sc->rx.rxbuf);
12621338 ath_rx_buf_link(sc, bf);
1263− if (!flush)
1264− ath9k_hw_rxena(ah);
1339+ ath9k_hw_rxena(ah);
12651340 }
12661341 } while (1);
12671342
1268− spin_unlock_bh(&sc->rx.rxbuflock);
1269−
12701343 if (!(ah->imask & ATH9K_INT_RXEOL)) {
12711344 ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
12721345 ath9k_hw_set_interrupts(ah);
drivers/net/wireless/ath/ath9k/reg.h+4−3
@@ -789,6 +789,7 @@ · 788 unmodified lines
789789 #define AR_SREV_REVISION_9271_11 1
790790 #define AR_SREV_VERSION_9300 0x1c0
791791 #define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */
792+#define AR_SREV_REVISION_9300_22 3
792793 #define AR_SREV_VERSION_9330 0x200
793794 #define AR_SREV_REVISION_9330_10 0
794795 #define AR_SREV_REVISION_9330_11 1
@@ -869,6 +870,9 @@ · 74 unmodified lines
869870 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300))
870871 #define AR_SREV_9300_20_OR_LATER(_ah) \
871872 ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300)
873+#define AR_SREV_9300_22(_ah) \
874+ (AR_SREV_9300(ah) && \
875+ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9300_22))
872876
873877 #define AR_SREV_9330(_ah) \
874878 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9330))
@@ -884,9 +888,6 @@ · 9 unmodified lines
884888
885889 #define AR_SREV_9485(_ah) \
886890 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485))
887−#define AR_SREV_9485_10(_ah) \
888− (AR_SREV_9485(_ah) && \
889− ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_10))
890891 #define AR_SREV_9485_11(_ah) \
891892 (AR_SREV_9485(_ah) && \
892893 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11))
drivers/net/wireless/ath/ath9k/xmit.c+45−100
@@ -378,7 +378,7 @@ static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf, · 377 unmodified lines
378378
379379 static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
380380 struct ath_buf *bf, struct list_head *bf_q,
381− struct ath_tx_status *ts, int txok, bool retry)
381+ struct ath_tx_status *ts, int txok)
382382 {
383383 struct ath_node *an = NULL;
384384 struct sk_buff *skb;
@@ -490,7 +490,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, · 105 unmodified lines
490490 } else if (!isaggr && txok) {
491491 /* transmit completion */
492492 acked_cnt++;
493− } else if ((tid->state & AGGR_CLEANUP) || !retry) {
493+ } else if (tid->state & AGGR_CLEANUP) {
494494 /*
495495 * cleanup in progress, just fail
496496 * the un-acked sub-frames
@@ -604,6 +604,37 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, · 107 unmodified lines
604604 ath9k_queue_reset(sc, RESET_TYPE_TX_ERROR);
605605 }
606606
607+static bool bf_is_ampdu_not_probing(struct ath_buf *bf)
608+{
609+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf->bf_mpdu);
610+ return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE);
611+}
612+
613+static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
614+ struct ath_tx_status *ts, struct ath_buf *bf,
615+ struct list_head *bf_head)
616+{
617+ bool txok, flush;
618+
619+ txok = !(ts->ts_status & ATH9K_TXERR_MASK);
620+ flush = !!(ts->ts_status & ATH9K_TX_FLUSH);
621+ txq->axq_tx_inprogress = false;
622+
623+ txq->axq_depth--;
624+ if (bf_is_ampdu_not_probing(bf))
625+ txq->axq_ampdu_depth--;
626+
627+ if (!bf_isampdu(bf)) {
628+ if (!flush)
629+ ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok);
630+ ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok);
631+ } else
632+ ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok);
633+
634+ if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && !flush)
635+ ath_txq_schedule(sc, txq);
636+}
637+
607638 static bool ath_lookup_legacy(struct ath_buf *bf)
608639 {
609640 struct sk_buff *skb;
@@ -1331,23 +1362,6 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid · 721 unmodified lines
13311362 /* Queue Management */
13321363 /********************/
13331364
1334−static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
1335− struct ath_txq *txq)
1336−{
1337− struct ath_atx_ac *ac, *ac_tmp;
1338− struct ath_atx_tid *tid, *tid_tmp;
1339−
1340− list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
1341− list_del(&ac->list);
1342− ac->sched = false;
1343− list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) {
1344− list_del(&tid->list);
1345− tid->sched = false;
1346− ath_tid_drain(sc, txq, tid);
1347− }
1348− }
1349−}
1350−
13511365 struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
13521366 {
13531367 struct ath_hw *ah = sc->sc_ah;
@@ -1470,14 +1484,8 @@ int ath_cabq_update(struct ath_softc *sc) · 116 unmodified lines
14701484 return 0;
14711485 }
14721486
1473−static bool bf_is_ampdu_not_probing(struct ath_buf *bf)
1474−{
1475− struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf->bf_mpdu);
1476− return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE);
1477−}
1478−
14791487 static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq,
1480− struct list_head *list, bool retry_tx)
1488+ struct list_head *list)
14811489 {
14821490 struct ath_buf *bf, *lastbf;
14831491 struct list_head bf_head;
@@ -1499,16 +1507,7 @@ static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq, · 15 unmodified lines
14991507
15001508 lastbf = bf->bf_lastbf;
15011509 list_cut_position(&bf_head, list, &lastbf->list);
1502−
1503− txq->axq_depth--;
1504− if (bf_is_ampdu_not_probing(bf))
1505− txq->axq_ampdu_depth--;
1506−
1507− if (bf_isampdu(bf))
1508− ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0,
1509− retry_tx);
1510− else
1511− ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
1510+ ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head);
15121511 }
15131512 }
15141513
@@ -1518,7 +1517,7 @@ static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq, · 3 unmodified lines
15181517 * This assumes output has been stopped and
15191518 * we do not need to block ath_tx_tasklet.
15201519 */
1521−void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
1520+void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq)
15221521 {
15231522 ath_txq_lock(sc, txq);
15241523
@@ -1526,8 +1525,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) · 1 unmodified line
15261525 int idx = txq->txq_tailidx;
15271526
15281527 while (!list_empty(&txq->txq_fifo[idx])) {
1529− ath_drain_txq_list(sc, txq, &txq->txq_fifo[idx],
1530− retry_tx);
1528+ ath_drain_txq_list(sc, txq, &txq->txq_fifo[idx]);
15311529
15321530 INCR(idx, ATH_TXFIFO_DEPTH);
15331531 }
@@ -1536,16 +1534,12 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) · 2 unmodified lines
15361534
15371535 txq->axq_link = NULL;
15381536 txq->axq_tx_inprogress = false;
1539− ath_drain_txq_list(sc, txq, &txq->axq_q, retry_tx);
1540−
1541− /* flush any pending frames if aggregation is enabled */
1542− if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && !retry_tx)
1543− ath_txq_drain_pending_buffers(sc, txq);
1537+ ath_drain_txq_list(sc, txq, &txq->axq_q);
15441538
15451539 ath_txq_unlock_complete(sc, txq);
15461540 }
15471541
1548−bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
1542+bool ath_drain_all_txq(struct ath_softc *sc)
15491543 {
15501544 struct ath_hw *ah = sc->sc_ah;
15511545 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -1581,7 +1575,7 @@ bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) · 29 unmodified lines
15811575 */
15821576 txq = &sc->tx.txq[i];
15831577 txq->stopped = false;
1584− ath_draintxq(sc, txq, retry_tx);
1578+ ath_draintxq(sc, txq);
15851579 }
15861580
15871581 return !npend;
@@ -2175,28 +2169,6 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, · 587 unmodified lines
21752169 tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1;
21762170 }
21772171
2178−static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
2179− struct ath_tx_status *ts, struct ath_buf *bf,
2180− struct list_head *bf_head)
2181−{
2182− int txok;
2183−
2184− txq->axq_depth--;
2185− txok = !(ts->ts_status & ATH9K_TXERR_MASK);
2186− txq->axq_tx_inprogress = false;
2187− if (bf_is_ampdu_not_probing(bf))
2188− txq->axq_ampdu_depth--;
2189−
2190− if (!bf_isampdu(bf)) {
2191− ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok);
2192− ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok);
2193− } else
2194− ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true);
2195−
2196− if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
2197− ath_txq_schedule(sc, txq);
2198−}
2199−
22002172 static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
22012173 {
22022174 struct ath_hw *ah = sc->sc_ah;
@@ -2361,8 +2333,8 @@ static int ath_txstatus_setup(struct ath_softc *sc, int size) · 158 unmodified lines
23612333 u8 txs_len = sc->sc_ah->caps.txs_len;
23622334
23632335 dd->dd_desc_len = size * txs_len;
2364− dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
2365− &dd->dd_desc_paddr, GFP_KERNEL);
2336+ dd->dd_desc = dmam_alloc_coherent(sc->dev, dd->dd_desc_len,
2337+ &dd->dd_desc_paddr, GFP_KERNEL);
23662338 if (!dd->dd_desc)
23672339 return -ENOMEM;
23682340
@@ -2382,14 +2354,6 @@ static int ath_tx_edma_init(struct ath_softc *sc) · 13 unmodified lines
23822354 return err;
23832355 }
23842356
2385−static void ath_tx_edma_cleanup(struct ath_softc *sc)
2386−{
2387− struct ath_descdma *dd = &sc->txsdma;
2388−
2389− dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
2390− dd->dd_desc_paddr);
2391−}
2392−
23932357 int ath_tx_init(struct ath_softc *sc, int nbufs)
23942358 {
23952359 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -2402,7 +2366,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) · 6 unmodified lines
24022366 if (error != 0) {
24032367 ath_err(common,
24042368 "Failed to allocate tx descriptors: %d\n", error);
2405− goto err;
2369+ return error;
24062370 }
24072371
24082372 error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
@@ -2410,36 +2374,17 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) · 1 unmodified line
24102374 if (error != 0) {
24112375 ath_err(common,
24122376 "Failed to allocate beacon descriptors: %d\n", error);
2413− goto err;
2377+ return error;
24142378 }
24152379
24162380 INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
24172381
2418− if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
2382+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
24192383 error = ath_tx_edma_init(sc);
2420− if (error)
2421− goto err;
2422− }
2423−
2424−err:
2425− if (error != 0)
2426− ath_tx_cleanup(sc);
24272384
24282385 return error;
24292386 }
24302387
2431−void ath_tx_cleanup(struct ath_softc *sc)
2432−{
2433− if (sc->beacon.bdma.dd_desc_len != 0)
2434− ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf);
2435−
2436− if (sc->tx.txdma.dd_desc_len != 0)
2437− ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
2438−
2439− if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
2440− ath_tx_edma_cleanup(sc);
2441−}
2442−
24432388 void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
24442389 {
24452390 struct ath_atx_tid *tid;
drivers/net/wireless/ath/carl9170/carl9170.h+7−12
@@ -85,20 +85,14 @@ enum carl9170_device_state { · 84 unmodified lines
8585 CARL9170_STARTED,
8686 };
8787
88−#define CARL9170_NUM_TID 16
8988 #define WME_BA_BMP_SIZE 64
9089 #define CARL9170_TX_USER_RATE_TRIES 3
9190
92−#define WME_AC_BE 2
93−#define WME_AC_BK 3
94−#define WME_AC_VI 1
95−#define WME_AC_VO 0
96−
9791 #define TID_TO_WME_AC(_tid) \
98− ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
99− (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
100− (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
101− WME_AC_VO)
92+ ((((_tid) == 0) || ((_tid) == 3)) ? IEEE80211_AC_BE : \
93+ (((_tid) == 1) || ((_tid) == 2)) ? IEEE80211_AC_BK : \
94+ (((_tid) == 4) || ((_tid) == 5)) ? IEEE80211_AC_VI : \
95+ IEEE80211_AC_VO)
10296
10397 #define SEQ_DIFF(_start, _seq) \
10498 (((_start) - (_seq)) & 0x0fff)
@@ -290,6 +284,7 @@ struct ar9170 { · 185 unmodified lines
290284 unsigned int rx_size;
291285 unsigned int tx_seq_table;
292286 bool ba_filter;
287+ bool disable_offload_fw;
293288 } fw;
294289
295290 /* interface configuration combinations */
@@ -493,8 +488,8 @@ struct carl9170_sta_info { · 197 unmodified lines
493488 bool sleeping;
494489 atomic_t pending_frames;
495490 unsigned int ampdu_max_len;
496− struct carl9170_sta_tid __rcu *agg[CARL9170_NUM_TID];
497− struct carl9170_ba_stats stats[CARL9170_NUM_TID];
491+ struct carl9170_sta_tid __rcu *agg[IEEE80211_NUM_TIDS];
492+ struct carl9170_ba_stats stats[IEEE80211_NUM_TIDS];
498493 };
499494
500495 struct carl9170_tx_info {
drivers/net/wireless/ath/carl9170/fw.c+30−13
@@ -215,6 +215,24 @@ static int carl9170_fw_tx_sequence(struct ar9170 *ar) · 214 unmodified lines
215215 return 0;
216216 }
217217
218+static void carl9170_fw_set_if_combinations(struct ar9170 *ar,
219+ u16 if_comb_types)
220+{
221+ if (ar->fw.vif_num < 2)
222+ return;
223+
224+ ar->if_comb_limits[0].max = ar->fw.vif_num;
225+ ar->if_comb_limits[0].types = if_comb_types;
226+
227+ ar->if_combs[0].num_different_channels = 1;
228+ ar->if_combs[0].max_interfaces = ar->fw.vif_num;
229+ ar->if_combs[0].limits = ar->if_comb_limits;
230+ ar->if_combs[0].n_limits = ARRAY_SIZE(ar->if_comb_limits);
231+
232+ ar->hw->wiphy->iface_combinations = ar->if_combs;
233+ ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ar->if_combs);
234+}
235+
218236 static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
219237 {
220238 const struct carl9170fw_otus_desc *otus_desc;
@@ -264,7 +282,7 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) · 43 unmodified lines
264282 if (!SUPP(CARL9170FW_COMMAND_CAM)) {
265283 dev_info(&ar->udev->dev, "crypto offloading is disabled "
266284 "by firmware.\n");
267− ar->disable_offload = true;
285+ ar->fw.disable_offload_fw = true;
268286 }
269287
270288 if (SUPP(CARL9170FW_PSM) && SUPP(CARL9170FW_FIXED_5GHZ_PSM))
@@ -336,25 +354,24 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) · 65 unmodified lines
336354 if (SUPP(CARL9170FW_WLANTX_CAB)) {
337355 if_comb_types |=
338356 BIT(NL80211_IFTYPE_AP) |
339− BIT(NL80211_IFTYPE_MESH_POINT) |
340357 BIT(NL80211_IFTYPE_P2P_GO);
358+
359+#ifdef CONFIG_MAC80211_MESH
360+ if_comb_types |=
361+ BIT(NL80211_IFTYPE_MESH_POINT);
362+#endif /* CONFIG_MAC80211_MESH */
341363 }
342364 }
343365
344− ar->if_comb_limits[0].max = ar->fw.vif_num;
345− ar->if_comb_limits[0].types = if_comb_types;
346−
347− ar->if_combs[0].num_different_channels = 1;
348− ar->if_combs[0].max_interfaces = ar->fw.vif_num;
349− ar->if_combs[0].limits = ar->if_comb_limits;
350− ar->if_combs[0].n_limits = ARRAY_SIZE(ar->if_comb_limits);
351−
352− ar->hw->wiphy->iface_combinations = ar->if_combs;
353− ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ar->if_combs);
366+ carl9170_fw_set_if_combinations(ar, if_comb_types);
354367
355368 ar->hw->wiphy->interface_modes |= if_comb_types;
356369
357− ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
370+ ar->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
371+
372+ /* As IBSS Encryption is software-based, IBSS RSN is supported. */
373+ ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
374+ WIPHY_FLAG_IBSS_RSN | WIPHY_FLAG_SUPPORTS_TDLS;
358375
359376 #undef SUPPORTED
360377 return carl9170_fw_tx_sequence(ar);
drivers/net/wireless/ath/carl9170/fwcmd.h+8−0
@@ -156,6 +156,14 @@ struct carl9170_psm { · 155 unmodified lines
156156 } __packed;
157157 #define CARL9170_PSM_SIZE 4
158158
159+/*
160+ * Note: If a bit in rx_filter is set, then it
161+ * means that the particular frames which matches
162+ * the condition are FILTERED/REMOVED/DISCARDED!
163+ * (This is can be a bit confusing, especially
164+ * because someone people think it's the exact
165+ * opposite way, so watch out!)
166+ */
159167 struct carl9170_rx_filter_cmd {
160168 __le32 rx_filter;
161169 } __packed;
drivers/net/wireless/ath/carl9170/hw.h+1−1
@@ -384,7 +384,7 @@ · 383 unmodified lines
384384
385385 #define AR9170_MAC_REG_BCN_ADDR (AR9170_MAC_REG_BASE + 0xd84)
386386 #define AR9170_MAC_REG_BCN_LENGTH (AR9170_MAC_REG_BASE + 0xd88)
387−#define AR9170_MAC_BCN_LENGTH_MAX 256
387+#define AR9170_MAC_BCN_LENGTH_MAX (512 - 32)
388388
389389 #define AR9170_MAC_REG_BCN_STATUS (AR9170_MAC_REG_BASE + 0xd8c)
390390
drivers/net/wireless/ath/carl9170/main.c+83−20
@@ -358,8 +358,13 @@ static int carl9170_op_start(struct ieee80211_hw *hw) · 357 unmodified lines
358358 ar->ps.last_action = jiffies;
359359 ar->ps.last_slept = jiffies;
360360 ar->erp_mode = CARL9170_ERP_AUTO;
361− ar->rx_software_decryption = false;
362− ar->disable_offload = false;
361+
362+ /* Set "disable hw crypto offload" whenever the module parameter
363+ * nohwcrypt is true or if the firmware does not support it.
364+ */
365+ ar->disable_offload = modparam_nohwcrypt |
366+ ar->fw.disable_offload_fw;
367+ ar->rx_software_decryption = ar->disable_offload;
363368
364369 for (i = 0; i < ar->hw->queues; i++) {
365370 ar->queue_stop_timeout[i] = jiffies;
@@ -565,12 +570,28 @@ static int carl9170_init_interface(struct ar9170 *ar, · 199 unmodified lines
565570
566571 memcpy(common->macaddr, vif->addr, ETH_ALEN);
567572
568− if (modparam_nohwcrypt ||
569− ((vif->type != NL80211_IFTYPE_STATION) &&
570− (vif->type != NL80211_IFTYPE_AP))) {
571− ar->rx_software_decryption = true;
572− ar->disable_offload = true;
573− }
573+ /* We have to fall back to software crypto, whenever
574+ * the user choose to participates in an IBSS. HW
575+ * offload for IBSS RSN is not supported by this driver.
576+ *
577+ * NOTE: If the previous main interface has already
578+ * disabled hw crypto offload, we have to keep this
579+ * previous disable_offload setting as it was.
580+ * Altough ideally, we should notify mac80211 and tell
581+ * it to forget about any HW crypto offload for now.
582+ */
583+ ar->disable_offload |= ((vif->type != NL80211_IFTYPE_STATION) &&
584+ (vif->type != NL80211_IFTYPE_AP));
585+
586+ /* While the driver supports HW offload in a single
587+ * P2P client configuration, it doesn't support HW
588+ * offload in the favourit, concurrent P2P GO+CLIENT
589+ * configuration. Hence, HW offload will always be
590+ * disabled for P2P.
591+ */
592+ ar->disable_offload |= vif->p2p;
593+
594+ ar->rx_software_decryption = ar->disable_offload;
574595
575596 err = carl9170_set_operating_mode(ar);
576597 return err;
@@ -580,7 +601,7 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, · 3 unmodified lines
580601 struct ieee80211_vif *vif)
581602 {
582603 struct carl9170_vif_info *vif_priv = (void *) vif->drv_priv;
583− struct ieee80211_vif *main_vif;
604+ struct ieee80211_vif *main_vif, *old_main = NULL;
584605 struct ar9170 *ar = hw->priv;
585606 int vif_id = -1, err = 0;
586607
@@ -602,6 +623,15 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, · 15 unmodified lines
602623 goto init;
603624 }
604625
626+ /* Because the AR9170 HW's MAC doesn't provide full support for
627+ * multiple, independent interfaces [of different operation modes].
628+ * We have to select ONE main interface [main mode of HW], but we
629+ * can have multiple slaves [AKA: entry in the ACK-table].
630+ *
631+ * The first (from HEAD/TOP) interface in the ar->vif_list is
632+ * always the main intf. All following intfs in this list
633+ * are considered to be slave intfs.
634+ */
605635 main_vif = carl9170_get_main_vif(ar);
606636
607637 if (main_vif) {
@@ -610,6 +640,18 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, · 2 unmodified lines
610640 if (vif->type == NL80211_IFTYPE_STATION)
611641 break;
612642
643+ /* P2P GO [master] use-case
644+ * Because the P2P GO station is selected dynamically
645+ * by all participating peers of a WIFI Direct network,
646+ * the driver has be able to change the main interface
647+ * operating mode on the fly.
648+ */
649+ if (main_vif->p2p && vif->p2p &&
650+ vif->type == NL80211_IFTYPE_AP) {
651+ old_main = main_vif;
652+ break;
653+ }
654+
613655 err = -EBUSY;
614656 rcu_read_unlock();
615657
@@ -648,14 +690,41 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, · 32 unmodified lines
648690 vif_priv->id = vif_id;
649691 vif_priv->enable_beacon = false;
650692 ar->vifs++;
651− list_add_tail_rcu(&vif_priv->list, &ar->vif_list);
693+ if (old_main) {
694+ /* We end up in here, if the main interface is being replaced.
695+ * Put the new main interface at the HEAD of the list and the
696+ * previous inteface will automatically become second in line.
697+ */
698+ list_add_rcu(&vif_priv->list, &ar->vif_list);
699+ } else {
700+ /* Add new inteface. If the list is empty, it will become the
701+ * main inteface, otherwise it will be slave.
702+ */
703+ list_add_tail_rcu(&vif_priv->list, &ar->vif_list);
704+ }
652705 rcu_assign_pointer(ar->vif_priv[vif_id].vif, vif);
653706
654707 init:
655− if (carl9170_get_main_vif(ar) == vif) {
708+ main_vif = carl9170_get_main_vif(ar);
709+
710+ if (main_vif == vif) {
656711 rcu_assign_pointer(ar->beacon_iter, vif_priv);
657712 rcu_read_unlock();
658713
714+ if (old_main) {
715+ struct carl9170_vif_info *old_main_priv =
716+ (void *) old_main->drv_priv;
717+ /* downgrade old main intf to slave intf.
718+ * NOTE: We are no longer under rcu_read_lock.
719+ * But we are still holding ar->mutex, so the
720+ * vif data [id, addr] is safe.
721+ */
722+ err = carl9170_mod_virtual_mac(ar, old_main_priv->id,
723+ old_main->addr);
724+ if (err)
725+ goto unlock;
726+ }
727+
659728 err = carl9170_init_interface(ar, vif);
660729 if (err)
661730 goto unlock;
@@ -1112,9 +1181,7 @@ static int carl9170_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, · 450 unmodified lines
11121181 if (ar->disable_offload || !vif)
11131182 return -EOPNOTSUPP;
11141183
1115− /*
1116− * We have to fall back to software encryption, whenever
1117− * the user choose to participates in an IBSS or is connected
1184+ /* Fall back to software encryption whenever the driver is connected
11181185 * to more than one network.
11191186 *
11201187 * This is very unfortunate, because some machines cannot handle
@@ -1263,7 +1330,7 @@ static int carl9170_op_sta_add(struct ieee80211_hw *hw, · 142 unmodified lines
12631330 return 0;
12641331 }
12651332
1266− for (i = 0; i < CARL9170_NUM_TID; i++)
1333+ for (i = 0; i < ARRAY_SIZE(sta_info->agg); i++)
12671334 RCU_INIT_POINTER(sta_info->agg[i], NULL);
12681335
12691336 sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor);
@@ -1287,7 +1354,7 @@ static int carl9170_op_sta_remove(struct ieee80211_hw *hw, · 17 unmodified lines
12871354 sta_info->ht_sta = false;
12881355
12891356 rcu_read_lock();
1290− for (i = 0; i < CARL9170_NUM_TID; i++) {
1357+ for (i = 0; i < ARRAY_SIZE(sta_info->agg); i++) {
12911358 struct carl9170_sta_tid *tid_info;
12921359
12931360 tid_info = rcu_dereference(sta_info->agg[i]);
@@ -1807,10 +1874,6 @@ void *carl9170_alloc(size_t priv_size) · 513 unmodified lines
18071874 for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
18081875 ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
18091876
1810− hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
1811−
1812− /* As IBSS Encryption is software-based, IBSS RSN is supported. */
1813− hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
18141877 return ar;
18151878
18161879 err_nomem:
drivers/net/wireless/ath/carl9170/tx.c+80−53
@@ -1520,35 +1520,92 @@ void carl9170_tx_scheduler(struct ar9170 *ar) · 1519 unmodified lines
15201520 carl9170_tx(ar);
15211521 }
15221522
1523−int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
1523+/* caller has to take rcu_read_lock */
1524+static struct carl9170_vif_info *carl9170_pick_beaconing_vif(struct ar9170 *ar)
15241525 {
1525− struct sk_buff *skb = NULL;
15261526 struct carl9170_vif_info *cvif;
1527+ int i = 1;
1528+
1529+ /* The AR9170 hardware has no fancy beacon queue or some
1530+ * other scheduling mechanism. So, the driver has to make
1531+ * due by setting the two beacon timers (pretbtt and tbtt)
1532+ * once and then swapping the beacon address in the HW's
1533+ * register file each time the pretbtt fires.
1534+ */
1535+
1536+ cvif = rcu_dereference(ar->beacon_iter);
1537+ if (ar->vifs > 0 && cvif) {
1538+ do {
1539+ list_for_each_entry_continue_rcu(cvif, &ar->vif_list,
1540+ list) {
1541+ if (cvif->active && cvif->enable_beacon)
1542+ goto out;
1543+ }
1544+ } while (ar->beacon_enabled && i--);
1545+ }
1546+
1547+out:
1548+ rcu_assign_pointer(ar->beacon_iter, cvif);
1549+ return cvif;
1550+}
1551+
1552+static bool carl9170_tx_beacon_physet(struct ar9170 *ar, struct sk_buff *skb,
1553+ u32 *ht1, u32 *plcp)
1554+{
15271555 struct ieee80211_tx_info *txinfo;
15281556 struct ieee80211_tx_rate *rate;
1529− __le32 *data, *old = NULL;
1530− unsigned int plcp, power, chains;
1531− u32 word, ht1, off, addr, len;
1532− int i = 0, err = 0;
1557+ unsigned int power, chains;
1558+ bool ht_rate;
15331559
1534− rcu_read_lock();
1535− cvif = rcu_dereference(ar->beacon_iter);
1536−retry:
1537− if (ar->vifs == 0 || !cvif)
1538− goto out_unlock;
1560+ txinfo = IEEE80211_SKB_CB(skb);
1561+ rate = &txinfo->control.rates[0];
1562+ ht_rate = !!(txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS);
1563+ carl9170_tx_rate_tpc_chains(ar, txinfo, rate, plcp, &power, &chains);
15391564
1540− list_for_each_entry_continue_rcu(cvif, &ar->vif_list, list) {
1541− if (cvif->active && cvif->enable_beacon)
1542− goto found;
1565+ *ht1 = AR9170_MAC_BCN_HT1_TX_ANT0;
1566+ if (chains == AR9170_TX_PHY_TXCHAIN_2)
1567+ *ht1 |= AR9170_MAC_BCN_HT1_TX_ANT1;
1568+ SET_VAL(AR9170_MAC_BCN_HT1_PWR_CTRL, *ht1, 7);
1569+ SET_VAL(AR9170_MAC_BCN_HT1_TPC, *ht1, power);
1570+ SET_VAL(AR9170_MAC_BCN_HT1_CHAIN_MASK, *ht1, chains);
1571+
1572+ if (ht_rate) {
1573+ *ht1 |= AR9170_MAC_BCN_HT1_HT_EN;
1574+ if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
1575+ *plcp |= AR9170_MAC_BCN_HT2_SGI;
1576+
1577+ if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
1578+ *ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_SHARED;
1579+ *plcp |= AR9170_MAC_BCN_HT2_BW40;
1580+ } else if (rate->flags & IEEE80211_TX_RC_DUP_DATA) {
1581+ *ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_DUP;
1582+ *plcp |= AR9170_MAC_BCN_HT2_BW40;
1583+ }
1584+
1585+ SET_VAL(AR9170_MAC_BCN_HT2_LEN, *plcp, skb->len + FCS_LEN);
1586+ } else {
1587+ if (*plcp <= AR9170_TX_PHY_RATE_CCK_11M)
1588+ *plcp |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
1589+ else
1590+ *plcp |= ((skb->len + FCS_LEN) << 16) + 0x0010;
15431591 }
15441592
1545− if (!ar->beacon_enabled || i++)
1546− goto out_unlock;
1593+ return ht_rate;
1594+}
15471595
1548− goto retry;
1596+int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
1597+{
1598+ struct sk_buff *skb = NULL;
1599+ struct carl9170_vif_info *cvif;
1600+ __le32 *data, *old = NULL;
1601+ u32 word, ht1, plcp, off, addr, len;
1602+ int i = 0, err = 0;
1603+ bool ht_rate;
15491604
1550−found:
1551− rcu_assign_pointer(ar->beacon_iter, cvif);
1605+ rcu_read_lock();
1606+ cvif = carl9170_pick_beaconing_vif(ar);
1607+ if (!cvif)
1608+ goto out_unlock;
15521609
15531610 skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif),
15541611 NULL, NULL);
@@ -1558,7 +1615,6 @@ found: · 3 unmodified lines
15581615 goto err_free;
15591616 }
15601617
1561− txinfo = IEEE80211_SKB_CB(skb);
15621618 spin_lock_bh(&ar->beacon_lock);
15631619 data = (__le32 *)skb->data;
15641620 if (cvif->beacon)
@@ -1588,43 +1644,14 @@ found: · 23 unmodified lines
15881644 goto err_unlock;
15891645 }
15901646
1591− ht1 = AR9170_MAC_BCN_HT1_TX_ANT0;
1592− rate = &txinfo->control.rates[0];
1593− carl9170_tx_rate_tpc_chains(ar, txinfo, rate, &plcp, &power, &chains);
1594− if (!(txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS)) {
1595− if (plcp <= AR9170_TX_PHY_RATE_CCK_11M)
1596− plcp |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
1597− else
1598− plcp |= ((skb->len + FCS_LEN) << 16) + 0x0010;
1599− } else {
1600− ht1 |= AR9170_MAC_BCN_HT1_HT_EN;
1601− if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
1602− plcp |= AR9170_MAC_BCN_HT2_SGI;
1603−
1604− if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
1605− ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_SHARED;
1606− plcp |= AR9170_MAC_BCN_HT2_BW40;
1607− }
1608− if (rate->flags & IEEE80211_TX_RC_DUP_DATA) {
1609− ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_DUP;
1610− plcp |= AR9170_MAC_BCN_HT2_BW40;
1611− }
1612−
1613− SET_VAL(AR9170_MAC_BCN_HT2_LEN, plcp, skb->len + FCS_LEN);
1614− }
1615−
1616− SET_VAL(AR9170_MAC_BCN_HT1_PWR_CTRL, ht1, 7);
1617− SET_VAL(AR9170_MAC_BCN_HT1_TPC, ht1, power);
1618− SET_VAL(AR9170_MAC_BCN_HT1_CHAIN_MASK, ht1, chains);
1619− if (chains == AR9170_TX_PHY_TXCHAIN_2)
1620− ht1 |= AR9170_MAC_BCN_HT1_TX_ANT1;
1647+ ht_rate = carl9170_tx_beacon_physet(ar, skb, &ht1, &plcp);
16211648
16221649 carl9170_async_regwrite_begin(ar);
16231650 carl9170_async_regwrite(AR9170_MAC_REG_BCN_HT1, ht1);
1624− if (!(txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS))
1625− carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, plcp);
1626− else
1651+ if (ht_rate)
16271652 carl9170_async_regwrite(AR9170_MAC_REG_BCN_HT2, plcp);
1653+ else
1654+ carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, plcp);
16281655
16291656 for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
16301657 /*
drivers/net/wireless/ath/carl9170/version.h+3−3
@@ -1,7 +1,7 @@
11 #ifndef __CARL9170_SHARED_VERSION_H
22 #define __CARL9170_SHARED_VERSION_H
33 #define CARL9170FW_VERSION_YEAR 12
4−#define CARL9170FW_VERSION_MONTH 7
5−#define CARL9170FW_VERSION_DAY 7
6−#define CARL9170FW_VERSION_GIT "1.9.6"
4+#define CARL9170FW_VERSION_MONTH 12
5+#define CARL9170FW_VERSION_DAY 15
6+#define CARL9170FW_VERSION_GIT "1.9.7"
77 #endif /* __CARL9170_SHARED_VERSION_H */
drivers/net/wireless/ath/wil6210/Kconfig+29−0
@@ -0,0 +1,29 @@
1+config WIL6210
2+ tristate "Wilocity 60g WiFi card wil6210 support"
3+ depends on CFG80211
4+ depends on PCI
5+ default n
6+ ---help---
7+ This module adds support for wireless adapter based on
8+ wil6210 chip by Wilocity. It supports operation on the
9+ 60 GHz band, covered by the IEEE802.11ad standard.
10+
11+ http://wireless.kernel.org/en/users/Drivers/wil6210
12+
13+ If you choose to build it as a module, it will be called
14+ wil6210
15+
16+config WIL6210_ISR_COR
17+ bool "Use Clear-On-Read mode for ISR registers for wil6210"
18+ depends on WIL6210
19+ default y
20+ ---help---
21+ ISR registers on wil6210 chip may operate in either
22+ COR (Clear-On-Read) or W1C (Write-1-to-Clear) mode.
23+ For production code, use COR (say y); is default since
24+ it saves extra target transaction;
25+ For ISR debug, use W1C (say n); is allows to monitor ISR
26+ registers with debugfs. If COR were used, ISR would
27+ self-clear when accessed for debug purposes, it makes
28+ such monitoring impossible.
29+ Say y unless you debug interrupts
drivers/net/wireless/ath/wil6210/Makefile+13−0
@@ -0,0 +1,13 @@
1+obj-$(CONFIG_WIL6210) += wil6210.o
2+
3+wil6210-objs := main.o
4+wil6210-objs += netdev.o
5+wil6210-objs += cfg80211.o
6+wil6210-objs += pcie_bus.o
7+wil6210-objs += debugfs.o
8+wil6210-objs += wmi.o
9+wil6210-objs += interrupt.o
10+wil6210-objs += txrx.o
11+
12+subdir-ccflags-y += -Werror
13+subdir-ccflags-y += -D__CHECK_ENDIAN__
drivers/net/wireless/ath/wil6210/cfg80211.c+573−0
@@ -0,0 +1,573 @@
1+/*
2+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
3+ *
4+ * Permission to use, copy, modify, and/or distribute this software for any
5+ * purpose with or without fee is hereby granted, provided that the above
6+ * copyright notice and this permission notice appear in all copies.
7+ *
8+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+ */
16+
17+#include <linux/kernel.h>
18+#include <linux/netdevice.h>
19+#include <linux/sched.h>
20+#include <linux/etherdevice.h>
21+#include <linux/wireless.h>
22+#include <linux/ieee80211.h>
23+#include <linux/slab.h>
24+#include <linux/version.h>
25+#include <net/cfg80211.h>
26+
27+#include "wil6210.h"
28+#include "wmi.h"
29+
30+#define CHAN60G(_channel, _flags) { \
31+ .band = IEEE80211_BAND_60GHZ, \
32+ .center_freq = 56160 + (2160 * (_channel)), \
33+ .hw_value = (_channel), \
34+ .flags = (_flags), \
35+ .max_antenna_gain = 0, \
36+ .max_power = 40, \
37+}
38+
39+static struct ieee80211_channel wil_60ghz_channels[] = {
40+ CHAN60G(1, 0),
41+ CHAN60G(2, 0),
42+ CHAN60G(3, 0),
43+/* channel 4 not supported yet */
44+};
45+
46+static struct ieee80211_supported_band wil_band_60ghz = {
47+ .channels = wil_60ghz_channels,
48+ .n_channels = ARRAY_SIZE(wil_60ghz_channels),
49+ .ht_cap = {
50+ .ht_supported = true,
51+ .cap = 0, /* TODO */
52+ .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, /* TODO */
53+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, /* TODO */
54+ .mcs = {
55+ /* MCS 1..12 - SC PHY */
56+ .rx_mask = {0xfe, 0x1f}, /* 1..12 */
57+ .tx_params = IEEE80211_HT_MCS_TX_DEFINED, /* TODO */
58+ },
59+ },
60+};
61+
62+static const struct ieee80211_txrx_stypes
63+wil_mgmt_stypes[NUM_NL80211_IFTYPES] = {
64+ [NL80211_IFTYPE_STATION] = {
65+ .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
66+ BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
67+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
68+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
69+ },
70+ [NL80211_IFTYPE_AP] = {
71+ .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
72+ BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
73+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
74+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
75+ },
76+ [NL80211_IFTYPE_P2P_CLIENT] = {
77+ .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
78+ BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
79+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
80+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
81+ },
82+ [NL80211_IFTYPE_P2P_GO] = {
83+ .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
84+ BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
85+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
86+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
87+ },
88+};
89+
90+static const u32 wil_cipher_suites[] = {
91+ WLAN_CIPHER_SUITE_GCMP,
92+};
93+
94+int wil_iftype_nl2wmi(enum nl80211_iftype type)
95+{
96+ static const struct {
97+ enum nl80211_iftype nl;
98+ enum wmi_network_type wmi;
99+ } __nl2wmi[] = {
100+ {NL80211_IFTYPE_ADHOC, WMI_NETTYPE_ADHOC},
101+ {NL80211_IFTYPE_STATION, WMI_NETTYPE_INFRA},
102+ {NL80211_IFTYPE_AP, WMI_NETTYPE_AP},
103+ {NL80211_IFTYPE_P2P_CLIENT, WMI_NETTYPE_P2P},
104+ {NL80211_IFTYPE_P2P_GO, WMI_NETTYPE_P2P},
105+ {NL80211_IFTYPE_MONITOR, WMI_NETTYPE_ADHOC}, /* FIXME */
106+ };
107+ uint i;
108+
109+ for (i = 0; i < ARRAY_SIZE(__nl2wmi); i++) {
110+ if (__nl2wmi[i].nl == type)
111+ return __nl2wmi[i].wmi;
112+ }
113+
114+ return -EOPNOTSUPP;
115+}
116+
117+static int wil_cfg80211_get_station(struct wiphy *wiphy,
118+ struct net_device *ndev,
119+ u8 *mac, struct station_info *sinfo)
120+{
121+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
122+ int rc;
123+ struct wmi_notify_req_cmd cmd = {
124+ .cid = 0,
125+ .interval_usec = 0,
126+ };
127+
128+ if (memcmp(mac, wil->dst_addr[0], ETH_ALEN))
129+ return -ENOENT;
130+
131+ /* WMI_NOTIFY_REQ_DONE_EVENTID handler fills wil->stats.bf_mcs */
132+ rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, &cmd, sizeof(cmd),
133+ WMI_NOTIFY_REQ_DONE_EVENTID, NULL, 0, 20);
134+ if (rc)
135+ return rc;
136+
137+ sinfo->generation = wil->sinfo_gen;
138+
139+ sinfo->filled |= STATION_INFO_TX_BITRATE;
140+ sinfo->txrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
141+ sinfo->txrate.mcs = wil->stats.bf_mcs;
142+ sinfo->filled |= STATION_INFO_RX_BITRATE;
143+ sinfo->rxrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
144+ sinfo->rxrate.mcs = wil->stats.last_mcs_rx;
145+
146+ if (test_bit(wil_status_fwconnected, &wil->status)) {
147+ sinfo->filled |= STATION_INFO_SIGNAL;
148+ sinfo->signal = 12; /* TODO: provide real value */
149+ }
150+
151+ return 0;
152+}
153+
154+static int wil_cfg80211_change_iface(struct wiphy *wiphy,
155+ struct net_device *ndev,
156+ enum nl80211_iftype type, u32 *flags,
157+ struct vif_params *params)
158+{
159+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
160+ struct wireless_dev *wdev = wil->wdev;
161+
162+ switch (type) {
163+ case NL80211_IFTYPE_STATION:
164+ case NL80211_IFTYPE_AP:
165+ case NL80211_IFTYPE_P2P_CLIENT:
166+ case NL80211_IFTYPE_P2P_GO:
167+ break;
168+ case NL80211_IFTYPE_MONITOR:
169+ if (flags)
170+ wil->monitor_flags = *flags;
171+ else
172+ wil->monitor_flags = 0;
173+
174+ break;
175+ default:
176+ return -EOPNOTSUPP;
177+ }
178+
179+ wdev->iftype = type;
180+
181+ return 0;
182+}
183+
184+static int wil_cfg80211_scan(struct wiphy *wiphy,
185+ struct cfg80211_scan_request *request)
186+{
187+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
188+ struct wireless_dev *wdev = wil->wdev;
189+ struct {
190+ struct wmi_start_scan_cmd cmd;
191+ u16 chnl[4];
192+ } __packed cmd;
193+ uint i, n;
194+
195+ if (wil->scan_request) {
196+ wil_err(wil, "Already scanning\n");
197+ return -EAGAIN;
198+ }
199+
200+ /* check we are client side */
201+ switch (wdev->iftype) {
202+ case NL80211_IFTYPE_STATION:
203+ case NL80211_IFTYPE_P2P_CLIENT:
204+ break;
205+ default:
206+ return -EOPNOTSUPP;
207+
208+ }
209+
210+ /* FW don't support scan after connection attempt */
211+ if (test_bit(wil_status_dontscan, &wil->status)) {
212+ wil_err(wil, "Scan after connect attempt not supported\n");
213+ return -EBUSY;
214+ }
215+
216+ wil->scan_request = request;
217+
218+ memset(&cmd, 0, sizeof(cmd));
219+ cmd.cmd.num_channels = 0;
220+ n = min(request->n_channels, 4U);
221+ for (i = 0; i < n; i++) {
222+ int ch = request->channels[i]->hw_value;
223+ if (ch == 0) {
224+ wil_err(wil,
225+ "Scan requested for unknown frequency %dMhz\n",
226+ request->channels[i]->center_freq);
227+ continue;
228+ }
229+ /* 0-based channel indexes */
230+ cmd.cmd.channel_list[cmd.cmd.num_channels++].channel = ch - 1;
231+ wil_dbg(wil, "Scan for ch %d : %d MHz\n", ch,
232+ request->channels[i]->center_freq);
233+ }
234+
235+ return wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) +
236+ cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0]));
237+}
238+
239+static int wil_cfg80211_connect(struct wiphy *wiphy,
240+ struct net_device *ndev,
241+ struct cfg80211_connect_params *sme)
242+{
243+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
244+ struct cfg80211_bss *bss;
245+ struct wmi_connect_cmd conn;
246+ const u8 *ssid_eid;
247+ const u8 *rsn_eid;
248+ int ch;
249+ int rc = 0;
250+
251+ bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
252+ sme->ssid, sme->ssid_len,
253+ WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
254+ if (!bss) {
255+ wil_err(wil, "Unable to find BSS\n");
256+ return -ENOENT;
257+ }
258+
259+ ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
260+ if (!ssid_eid) {
261+ wil_err(wil, "No SSID\n");
262+ rc = -ENOENT;
263+ goto out;
264+ }
265+
266+ rsn_eid = sme->ie ?
267+ cfg80211_find_ie(WLAN_EID_RSN, sme->ie, sme->ie_len) :
268+ NULL;
269+ if (rsn_eid) {
270+ if (sme->ie_len > WMI_MAX_IE_LEN) {
271+ rc = -ERANGE;
272+ wil_err(wil, "IE too large (%td bytes)\n",
273+ sme->ie_len);
274+ goto out;
275+ }
276+ /*
277+ * For secure assoc, send:
278+ * (1) WMI_DELETE_CIPHER_KEY_CMD
279+ * (2) WMI_SET_APPIE_CMD
280+ */
281+ rc = wmi_del_cipher_key(wil, 0, bss->bssid);
282+ if (rc) {
283+ wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD failed\n");
284+ goto out;
285+ }
286+ /* WMI_SET_APPIE_CMD */
287+ rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie);
288+ if (rc) {
289+ wil_err(wil, "WMI_SET_APPIE_CMD failed\n");
290+ goto out;
291+ }
292+ }
293+
294+ /* WMI_CONNECT_CMD */
295+ memset(&conn, 0, sizeof(conn));
296+ switch (bss->capability & 0x03) {
297+ case WLAN_CAPABILITY_DMG_TYPE_AP:
298+ conn.network_type = WMI_NETTYPE_INFRA;
299+ break;
300+ case WLAN_CAPABILITY_DMG_TYPE_PBSS:
301+ conn.network_type = WMI_NETTYPE_P2P;
302+ break;
303+ default:
304+ wil_err(wil, "Unsupported BSS type, capability= 0x%04x\n",
305+ bss->capability);
306+ goto out;
307+ }
308+ if (rsn_eid) {
309+ conn.dot11_auth_mode = WMI_AUTH11_SHARED;
310+ conn.auth_mode = WMI_AUTH_WPA2_PSK;
311+ conn.pairwise_crypto_type = WMI_CRYPT_AES_GCMP;
312+ conn.pairwise_crypto_len = 16;
313+ } else {
314+ conn.dot11_auth_mode = WMI_AUTH11_OPEN;
315+ conn.auth_mode = WMI_AUTH_NONE;
316+ }
317+
318+ conn.ssid_len = min_t(u8, ssid_eid[1], 32);
319+ memcpy(conn.ssid, ssid_eid+2, conn.ssid_len);
320+
321+ ch = bss->channel->hw_value;
322+ if (ch == 0) {
323+ wil_err(wil, "BSS at unknown frequency %dMhz\n",
324+ bss->channel->center_freq);
325+ rc = -EOPNOTSUPP;
326+ goto out;
327+ }
328+ conn.channel = ch - 1;
329+
330+ memcpy(conn.bssid, bss->bssid, 6);
331+ memcpy(conn.dst_mac, bss->bssid, 6);
332+ /*
333+ * FW don't support scan after connection attempt
334+ */
335+ set_bit(wil_status_dontscan, &wil->status);
336+
337+ rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn));
338+ if (rc == 0) {
339+ /* Connect can take lots of time */
340+ mod_timer(&wil->connect_timer,
341+ jiffies + msecs_to_jiffies(2000));
342+ }
343+
344+ out:
345+ cfg80211_put_bss(bss);
346+
347+ return rc;
348+}
349+
350+static int wil_cfg80211_disconnect(struct wiphy *wiphy,
351+ struct net_device *ndev,
352+ u16 reason_code)
353+{
354+ int rc;
355+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
356+
357+ rc = wmi_send(wil, WMI_DISCONNECT_CMDID, NULL, 0);
358+
359+ return rc;
360+}
361+
362+static int wil_cfg80211_set_channel(struct wiphy *wiphy,
363+ struct cfg80211_chan_def *chandef)
364+{
365+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
366+ struct wireless_dev *wdev = wil->wdev;
367+
368+ wdev->preset_chandef = *chandef;
369+
370+ return 0;
371+}
372+
373+static int wil_cfg80211_add_key(struct wiphy *wiphy,
374+ struct net_device *ndev,
375+ u8 key_index, bool pairwise,
376+ const u8 *mac_addr,
377+ struct key_params *params)
378+{
379+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
380+
381+ /* group key is not used */
382+ if (!pairwise)
383+ return 0;
384+
385+ return wmi_add_cipher_key(wil, key_index, mac_addr,
386+ params->key_len, params->key);
387+}
388+
389+static int wil_cfg80211_del_key(struct wiphy *wiphy,
390+ struct net_device *ndev,
391+ u8 key_index, bool pairwise,
392+ const u8 *mac_addr)
393+{
394+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
395+
396+ /* group key is not used */
397+ if (!pairwise)
398+ return 0;
399+
400+ return wmi_del_cipher_key(wil, key_index, mac_addr);
401+}
402+
403+/* Need to be present or wiphy_new() will WARN */
404+static int wil_cfg80211_set_default_key(struct wiphy *wiphy,
405+ struct net_device *ndev,
406+ u8 key_index, bool unicast,
407+ bool multicast)
408+{
409+ return 0;
410+}
411+
412+static int wil_cfg80211_start_ap(struct wiphy *wiphy,
413+ struct net_device *ndev,
414+ struct cfg80211_ap_settings *info)
415+{
416+ int rc = 0;
417+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
418+ struct wireless_dev *wdev = ndev->ieee80211_ptr;
419+ struct ieee80211_channel *channel = info->chandef.chan;
420+ struct cfg80211_beacon_data *bcon = &info->beacon;
421+ u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);
422+
423+ if (!channel) {
424+ wil_err(wil, "AP: No channel???\n");
425+ return -EINVAL;
426+ }
427+
428+ wil_dbg(wil, "AP on Channel %d %d MHz, %s\n", channel->hw_value,
429+ channel->center_freq, info->privacy ? "secure" : "open");
430+ print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
431+ info->ssid, info->ssid_len);
432+
433+ rc = wil_reset(wil);
434+ if (rc)
435+ return rc;
436+
437+ rc = wmi_set_ssid(wil, info->ssid_len, info->ssid);
438+ if (rc)
439+ return rc;
440+
441+ rc = wmi_set_channel(wil, channel->hw_value);
442+ if (rc)
443+ return rc;
444+
445+ /* MAC address - pre-requisite for other commands */
446+ wmi_set_mac_address(wil, ndev->dev_addr);
447+
448+ /* IE's */
449+ /* bcon 'head IE's are not relevant for 60g band */
450+ wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->beacon_ies_len,
451+ bcon->beacon_ies);
452+ wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, bcon->proberesp_ies_len,
453+ bcon->proberesp_ies);
454+ wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, bcon->assocresp_ies_len,
455+ bcon->assocresp_ies);
456+
457+ wil->secure_pcp = info->privacy;
458+
459+ rc = wmi_set_bcon(wil, info->beacon_interval, wmi_nettype);
460+ if (rc)
461+ return rc;
462+
463+ /* Rx VRING. After MAC and beacon */
464+ rc = wil_rx_init(wil);
465+
466+ netif_carrier_on(ndev);
467+
468+ return rc;
469+}
470+
471+static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
472+ struct net_device *ndev)
473+{
474+ int rc = 0;
475+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
476+ struct wireless_dev *wdev = ndev->ieee80211_ptr;
477+ u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);
478+
479+ /* To stop beaconing, set BI to 0 */
480+ rc = wmi_set_bcon(wil, 0, wmi_nettype);
481+
482+ return rc;
483+}
484+
485+static struct cfg80211_ops wil_cfg80211_ops = {
486+ .scan = wil_cfg80211_scan,
487+ .connect = wil_cfg80211_connect,
488+ .disconnect = wil_cfg80211_disconnect,
489+ .change_virtual_intf = wil_cfg80211_change_iface,
490+ .get_station = wil_cfg80211_get_station,
491+ .set_monitor_channel = wil_cfg80211_set_channel,
492+ .add_key = wil_cfg80211_add_key,
493+ .del_key = wil_cfg80211_del_key,
494+ .set_default_key = wil_cfg80211_set_default_key,
495+ /* AP mode */
496+ .start_ap = wil_cfg80211_start_ap,
497+ .stop_ap = wil_cfg80211_stop_ap,
498+};
499+
500+static void wil_wiphy_init(struct wiphy *wiphy)
501+{
502+ /* TODO: set real value */
503+ wiphy->max_scan_ssids = 10;
504+ wiphy->max_num_pmkids = 0 /* TODO: */;
505+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
506+ BIT(NL80211_IFTYPE_AP) |
507+ BIT(NL80211_IFTYPE_MONITOR);
508+ /* TODO: enable P2P when integrated with supplicant:
509+ * BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO)
510+ */
511+ wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
512+ WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
513+ dev_warn(wiphy_dev(wiphy), "%s : flags = 0x%08x\n",
514+ __func__, wiphy->flags);
515+ wiphy->probe_resp_offload =
516+ NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
517+ NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
518+ NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
519+
520+ wiphy->bands[IEEE80211_BAND_60GHZ] = &wil_band_60ghz;
521+
522+ /* TODO: figure this out */
523+ wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
524+
525+ wiphy->cipher_suites = wil_cipher_suites;
526+ wiphy->n_cipher_suites = ARRAY_SIZE(wil_cipher_suites);
527+ wiphy->mgmt_stypes = wil_mgmt_stypes;
528+}
529+
530+struct wireless_dev *wil_cfg80211_init(struct device *dev)
531+{
532+ int rc = 0;
533+ struct wireless_dev *wdev;
534+
535+ wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
536+ if (!wdev)
537+ return ERR_PTR(-ENOMEM);
538+
539+ wdev->wiphy = wiphy_new(&wil_cfg80211_ops,
540+ sizeof(struct wil6210_priv));
541+ if (!wdev->wiphy) {
542+ rc = -ENOMEM;
543+ goto out;
544+ }
545+
546+ set_wiphy_dev(wdev->wiphy, dev);
547+ wil_wiphy_init(wdev->wiphy);
548+
549+ rc = wiphy_register(wdev->wiphy);
550+ if (rc < 0)
551+ goto out_failed_reg;
552+
553+ return wdev;
554+
555+out_failed_reg:
556+ wiphy_free(wdev->wiphy);
557+out:
558+ kfree(wdev);
559+
560+ return ERR_PTR(rc);
561+}
562+
563+void wil_wdev_free(struct wil6210_priv *wil)
564+{
565+ struct wireless_dev *wdev = wil_to_wdev(wil);
566+
567+ if (!wdev)
568+ return;
569+
570+ wiphy_unregister(wdev->wiphy);
571+ wiphy_free(wdev->wiphy);
572+ kfree(wdev);
573+}
drivers/net/wireless/ath/wil6210/dbg_hexdump.h+30−0
@@ -0,0 +1,30 @@
1+#ifndef WIL_DBG_HEXDUMP_H_
2+#define WIL_DBG_HEXDUMP_H_
3+
4+#if defined(CONFIG_DYNAMIC_DEBUG)
5+#define wil_dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
6+ groupsize, buf, len, ascii) \
7+do { \
8+ DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, \
9+ __builtin_constant_p(prefix_str) ? prefix_str : "hexdump");\
10+ if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
11+ print_hex_dump(KERN_DEBUG, prefix_str, \
12+ prefix_type, rowsize, groupsize, \
13+ buf, len, ascii); \
14+} while (0)
15+
16+#define wil_print_hex_dump_debug(prefix_str, prefix_type, rowsize, \
17+ groupsize, buf, len, ascii) \
18+ wil_dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
19+ groupsize, buf, len, ascii)
20+
21+#define print_hex_dump_bytes(prefix_str, prefix_type, buf, len) \
22+ wil_dynamic_hex_dump(prefix_str, prefix_type, 16, 1, buf, len, true)
23+#else /* defined(CONFIG_DYNAMIC_DEBUG) */
24+#define wil_print_hex_dump_debug(prefix_str, prefix_type, rowsize, \
25+ groupsize, buf, len, ascii) \
26+ print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, rowsize, \
27+ groupsize, buf, len, ascii)
28+#endif /* defined(CONFIG_DYNAMIC_DEBUG) */
29+
30+#endif /* WIL_DBG_HEXDUMP_H_ */
drivers/net/wireless/ath/wil6210/debugfs.c+603−0
@@ -0,0 +1,603 @@
1+/*
2+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
3+ *
4+ * Permission to use, copy, modify, and/or distribute this software for any
5+ * purpose with or without fee is hereby granted, provided that the above
6+ * copyright notice and this permission notice appear in all copies.
7+ *
8+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+ */
16+
17+#include <linux/module.h>
18+#include <linux/debugfs.h>
19+#include <linux/seq_file.h>
20+#include <linux/pci.h>
21+#include <linux/rtnetlink.h>
22+
23+#include "wil6210.h"
24+#include "txrx.h"
25+
26+/* Nasty hack. Better have per device instances */
27+static u32 mem_addr;
28+static u32 dbg_txdesc_index;
29+
30+static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil,
31+ const char *name, struct vring *vring)
32+{
33+ void __iomem *x = wmi_addr(wil, vring->hwtail);
34+
35+ seq_printf(s, "VRING %s = {\n", name);
36+ seq_printf(s, " pa = 0x%016llx\n", (unsigned long long)vring->pa);
37+ seq_printf(s, " va = 0x%p\n", vring->va);
38+ seq_printf(s, " size = %d\n", vring->size);
39+ seq_printf(s, " swtail = %d\n", vring->swtail);
40+ seq_printf(s, " swhead = %d\n", vring->swhead);
41+ seq_printf(s, " hwtail = [0x%08x] -> ", vring->hwtail);
42+ if (x)
43+ seq_printf(s, "0x%08x\n", ioread32(x));
44+ else
45+ seq_printf(s, "???\n");
46+
47+ if (vring->va && (vring->size < 1025)) {
48+ uint i;
49+ for (i = 0; i < vring->size; i++) {
50+ volatile struct vring_tx_desc *d = &vring->va[i].tx;
51+ if ((i % 64) == 0 && (i != 0))
52+ seq_printf(s, "\n");
53+ seq_printf(s, "%s", (d->dma.status & BIT(0)) ?
54+ "S" : (vring->ctx[i] ? "H" : "h"));
55+ }
56+ seq_printf(s, "\n");
57+ }
58+ seq_printf(s, "}\n");
59+}
60+
61+static int wil_vring_debugfs_show(struct seq_file *s, void *data)
62+{
63+ uint i;
64+ struct wil6210_priv *wil = s->private;
65+
66+ wil_print_vring(s, wil, "rx", &wil->vring_rx);
67+
68+ for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
69+ struct vring *vring = &(wil->vring_tx[i]);
70+ if (vring->va) {
71+ char name[10];
72+ snprintf(name, sizeof(name), "tx_%2d", i);
73+ wil_print_vring(s, wil, name, vring);
74+ }
75+ }
76+
77+ return 0;
78+}
79+
80+static int wil_vring_seq_open(struct inode *inode, struct file *file)
81+{
82+ return single_open(file, wil_vring_debugfs_show, inode->i_private);
83+}
84+
85+static const struct file_operations fops_vring = {
86+ .open = wil_vring_seq_open,
87+ .release = single_release,
88+ .read = seq_read,
89+ .llseek = seq_lseek,
90+};
91+
92+static void wil_print_ring(struct seq_file *s, const char *prefix,
93+ void __iomem *off)
94+{
95+ struct wil6210_priv *wil = s->private;
96+ struct wil6210_mbox_ring r;
97+ int rsize;
98+ uint i;
99+
100+ wil_memcpy_fromio_32(&r, off, sizeof(r));
101+ wil_mbox_ring_le2cpus(&r);
102+ /*
103+ * we just read memory block from NIC. This memory may be
104+ * garbage. Check validity before using it.
105+ */
106+ rsize = r.size / sizeof(struct wil6210_mbox_ring_desc);
107+
108+ seq_printf(s, "ring %s = {\n", prefix);
109+ seq_printf(s, " base = 0x%08x\n", r.base);
110+ seq_printf(s, " size = 0x%04x bytes -> %d entries\n", r.size, rsize);
111+ seq_printf(s, " tail = 0x%08x\n", r.tail);
112+ seq_printf(s, " head = 0x%08x\n", r.head);
113+ seq_printf(s, " entry size = %d\n", r.entry_size);
114+
115+ if (r.size % sizeof(struct wil6210_mbox_ring_desc)) {
116+ seq_printf(s, " ??? size is not multiple of %zd, garbage?\n",
117+ sizeof(struct wil6210_mbox_ring_desc));
118+ goto out;
119+ }
120+
121+ if (!wmi_addr(wil, r.base) ||
122+ !wmi_addr(wil, r.tail) ||
123+ !wmi_addr(wil, r.head)) {
124+ seq_printf(s, " ??? pointers are garbage?\n");
125+ goto out;
126+ }
127+
128+ for (i = 0; i < rsize; i++) {
129+ struct wil6210_mbox_ring_desc d;
130+ struct wil6210_mbox_hdr hdr;
131+ size_t delta = i * sizeof(d);
132+ void __iomem *x = wil->csr + HOSTADDR(r.base) + delta;
133+
134+ wil_memcpy_fromio_32(&d, x, sizeof(d));
135+
136+ seq_printf(s, " [%2x] %s %s%s 0x%08x", i,
137+ d.sync ? "F" : "E",
138+ (r.tail - r.base == delta) ? "t" : " ",
139+ (r.head - r.base == delta) ? "h" : " ",
140+ le32_to_cpu(d.addr));
141+ if (0 == wmi_read_hdr(wil, d.addr, &hdr)) {
142+ u16 len = le16_to_cpu(hdr.len);
143+ seq_printf(s, " -> %04x %04x %04x %02x\n",
144+ le16_to_cpu(hdr.seq), len,
145+ le16_to_cpu(hdr.type), hdr.flags);
146+ if (len <= MAX_MBOXITEM_SIZE) {
147+ int n = 0;
148+ unsigned char printbuf[16 * 3 + 2];
149+ unsigned char databuf[MAX_MBOXITEM_SIZE];
150+ void __iomem *src = wmi_buffer(wil, d.addr) +
151+ sizeof(struct wil6210_mbox_hdr);
152+ /*
153+ * No need to check @src for validity -
154+ * we already validated @d.addr while
155+ * reading header
156+ */
157+ wil_memcpy_fromio_32(databuf, src, len);
158+ while (n < len) {
159+ int l = min(len - n, 16);
160+ hex_dump_to_buffer(databuf + n, l,
161+ 16, 1, printbuf,
162+ sizeof(printbuf),
163+ false);
164+ seq_printf(s, " : %s\n", printbuf);
165+ n += l;
166+ }
167+ }
168+ } else {
169+ seq_printf(s, "\n");
170+ }
171+ }
172+ out:
173+ seq_printf(s, "}\n");
174+}
175+
176+static int wil_mbox_debugfs_show(struct seq_file *s, void *data)
177+{
178+ struct wil6210_priv *wil = s->private;
179+
180+ wil_print_ring(s, "tx", wil->csr + HOST_MBOX +
181+ offsetof(struct wil6210_mbox_ctl, tx));
182+ wil_print_ring(s, "rx", wil->csr + HOST_MBOX +
183+ offsetof(struct wil6210_mbox_ctl, rx));
184+
185+ return 0;
186+}
187+
188+static int wil_mbox_seq_open(struct inode *inode, struct file *file)
189+{
190+ return single_open(file, wil_mbox_debugfs_show, inode->i_private);
191+}
192+
193+static const struct file_operations fops_mbox = {
194+ .open = wil_mbox_seq_open,
195+ .release = single_release,
196+ .read = seq_read,
197+ .llseek = seq_lseek,
198+};
199+
200+static int wil_debugfs_iomem_x32_set(void *data, u64 val)
201+{
202+ iowrite32(val, (void __iomem *)data);
203+ wmb(); /* make sure write propagated to HW */
204+
205+ return 0;
206+}
207+
208+static int wil_debugfs_iomem_x32_get(void *data, u64 *val)
209+{
210+ *val = ioread32((void __iomem *)data);
211+
212+ return 0;
213+}
214+
215+DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x32, wil_debugfs_iomem_x32_get,
216+ wil_debugfs_iomem_x32_set, "0x%08llx\n");
217+
218+static struct dentry *wil_debugfs_create_iomem_x32(const char *name,
219+ mode_t mode,
220+ struct dentry *parent,
221+ void __iomem *value)
222+{
223+ return debugfs_create_file(name, mode, parent, (void * __force)value,
224+ &fops_iomem_x32);
225+}
226+
227+static int wil6210_debugfs_create_ISR(struct wil6210_priv *wil,
228+ const char *name,
229+ struct dentry *parent, u32 off)
230+{
231+ struct dentry *d = debugfs_create_dir(name, parent);
232+
233+ if (IS_ERR_OR_NULL(d))
234+ return -ENODEV;
235+
236+ wil_debugfs_create_iomem_x32("ICC", S_IRUGO | S_IWUSR, d,
237+ wil->csr + off);
238+ wil_debugfs_create_iomem_x32("ICR", S_IRUGO | S_IWUSR, d,
239+ wil->csr + off + 4);
240+ wil_debugfs_create_iomem_x32("ICM", S_IRUGO | S_IWUSR, d,
241+ wil->csr + off + 8);
242+ wil_debugfs_create_iomem_x32("ICS", S_IWUSR, d,
243+ wil->csr + off + 12);
244+ wil_debugfs_create_iomem_x32("IMV", S_IRUGO | S_IWUSR, d,
245+ wil->csr + off + 16);
246+ wil_debugfs_create_iomem_x32("IMS", S_IWUSR, d,
247+ wil->csr + off + 20);
248+ wil_debugfs_create_iomem_x32("IMC", S_IWUSR, d,
249+ wil->csr + off + 24);
250+
251+ return 0;
252+}
253+
254+static int wil6210_debugfs_create_pseudo_ISR(struct wil6210_priv *wil,
255+ struct dentry *parent)
256+{
257+ struct dentry *d = debugfs_create_dir("PSEUDO_ISR", parent);
258+
259+ if (IS_ERR_OR_NULL(d))
260+ return -ENODEV;
261+
262+ wil_debugfs_create_iomem_x32("CAUSE", S_IRUGO, d, wil->csr +
263+ HOSTADDR(RGF_DMA_PSEUDO_CAUSE));
264+ wil_debugfs_create_iomem_x32("MASK_SW", S_IRUGO, d, wil->csr +
265+ HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW));
266+ wil_debugfs_create_iomem_x32("MASK_FW", S_IRUGO, d, wil->csr +
267+ HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_FW));
268+
269+ return 0;
270+}
271+
272+static int wil6210_debugfs_create_ITR_CNT(struct wil6210_priv *wil,
273+ struct dentry *parent)
274+{
275+ struct dentry *d = debugfs_create_dir("ITR_CNT", parent);
276+
277+ if (IS_ERR_OR_NULL(d))
278+ return -ENODEV;
279+
280+ wil_debugfs_create_iomem_x32("TRSH", S_IRUGO, d, wil->csr +
281+ HOSTADDR(RGF_DMA_ITR_CNT_TRSH));
282+ wil_debugfs_create_iomem_x32("DATA", S_IRUGO, d, wil->csr +
283+ HOSTADDR(RGF_DMA_ITR_CNT_DATA));
284+ wil_debugfs_create_iomem_x32("CTL", S_IRUGO, d, wil->csr +
285+ HOSTADDR(RGF_DMA_ITR_CNT_CRL));
286+
287+ return 0;
288+}
289+
290+static int wil_memread_debugfs_show(struct seq_file *s, void *data)
291+{
292+ struct wil6210_priv *wil = s->private;
293+ void __iomem *a = wmi_buffer(wil, cpu_to_le32(mem_addr));
294+
295+ if (a)
296+ seq_printf(s, "[0x%08x] = 0x%08x\n", mem_addr, ioread32(a));
297+ else
298+ seq_printf(s, "[0x%08x] = INVALID\n", mem_addr);
299+
300+ return 0;
301+}
302+
303+static int wil_memread_seq_open(struct inode *inode, struct file *file)
304+{
305+ return single_open(file, wil_memread_debugfs_show, inode->i_private);
306+}
307+
308+static const struct file_operations fops_memread = {
309+ .open = wil_memread_seq_open,
310+ .release = single_release,
311+ .read = seq_read,
312+ .llseek = seq_lseek,
313+};
314+
315+static int wil_default_open(struct inode *inode, struct file *file)
316+{
317+ if (inode->i_private)
318+ file->private_data = inode->i_private;
319+
320+ return 0;
321+}
322+
323+static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
324+ size_t count, loff_t *ppos)
325+{
326+ enum { max_count = 4096 };
327+ struct debugfs_blob_wrapper *blob = file->private_data;
328+ loff_t pos = *ppos;
329+ size_t available = blob->size;
330+ void *buf;
331+ size_t ret;
332+
333+ if (pos < 0)
334+ return -EINVAL;
335+
336+ if (pos >= available || !count)
337+ return 0;
338+
339+ if (count > available - pos)
340+ count = available - pos;
341+ if (count > max_count)
342+ count = max_count;
343+
344+ buf = kmalloc(count, GFP_KERNEL);
345+ if (!buf)
346+ return -ENOMEM;
347+
348+ wil_memcpy_fromio_32(buf, (const volatile void __iomem *)blob->data +
349+ pos, count);
350+
351+ ret = copy_to_user(user_buf, buf, count);
352+ kfree(buf);
353+ if (ret == count)
354+ return -EFAULT;
355+
356+ count -= ret;
357+ *ppos = pos + count;
358+
359+ return count;
360+}
361+
362+static const struct file_operations fops_ioblob = {
363+ .read = wil_read_file_ioblob,
364+ .open = wil_default_open,
365+ .llseek = default_llseek,
366+};
367+
368+static
369+struct dentry *wil_debugfs_create_ioblob(const char *name,
370+ mode_t mode,
371+ struct dentry *parent,
372+ struct debugfs_blob_wrapper *blob)
373+{
374+ return debugfs_create_file(name, mode, parent, blob, &fops_ioblob);
375+}
376+/*---reset---*/
377+static ssize_t wil_write_file_reset(struct file *file, const char __user *buf,
378+ size_t len, loff_t *ppos)
379+{
380+ struct wil6210_priv *wil = file->private_data;
381+ struct net_device *ndev = wil_to_ndev(wil);
382+
383+ /**
384+ * BUG:
385+ * this code does NOT sync device state with the rest of system
386+ * use with care, debug only!!!
387+ */
388+ rtnl_lock();
389+ dev_close(ndev);
390+ ndev->flags &= ~IFF_UP;
391+ rtnl_unlock();
392+ wil_reset(wil);
393+
394+ return len;
395+}
396+
397+static const struct file_operations fops_reset = {
398+ .write = wil_write_file_reset,
399+ .open = wil_default_open,
400+};
401+/*---------Tx descriptor------------*/
402+
403+static int wil_txdesc_debugfs_show(struct seq_file *s, void *data)
404+{
405+ struct wil6210_priv *wil = s->private;
406+ struct vring *vring = &(wil->vring_tx[0]);
407+
408+ if (!vring->va) {
409+ seq_printf(s, "No Tx VRING\n");
410+ return 0;
411+ }
412+
413+ if (dbg_txdesc_index < vring->size) {
414+ volatile struct vring_tx_desc *d =
415+ &(vring->va[dbg_txdesc_index].tx);
416+ volatile u32 *u = (volatile u32 *)d;
417+ struct sk_buff *skb = vring->ctx[dbg_txdesc_index];
418+
419+ seq_printf(s, "Tx[%3d] = {\n", dbg_txdesc_index);
420+ seq_printf(s, " MAC = 0x%08x 0x%08x 0x%08x 0x%08x\n",
421+ u[0], u[1], u[2], u[3]);
422+ seq_printf(s, " DMA = 0x%08x 0x%08x 0x%08x 0x%08x\n",
423+ u[4], u[5], u[6], u[7]);
424+ seq_printf(s, " SKB = %p\n", skb);
425+
426+ if (skb) {
427+ unsigned char printbuf[16 * 3 + 2];
428+ int i = 0;
429+ int len = skb_headlen(skb);
430+ void *p = skb->data;
431+
432+ seq_printf(s, " len = %d\n", len);
433+
434+ while (i < len) {
435+ int l = min(len - i, 16);
436+ hex_dump_to_buffer(p + i, l, 16, 1, printbuf,
437+ sizeof(printbuf), false);
438+ seq_printf(s, " : %s\n", printbuf);
439+ i += l;
440+ }
441+ }
442+ seq_printf(s, "}\n");
443+ } else {
444+ seq_printf(s, "TxDesc index (%d) >= size (%d)\n",
445+ dbg_txdesc_index, vring->size);
446+ }
447+
448+ return 0;
449+}
450+
451+static int wil_txdesc_seq_open(struct inode *inode, struct file *file)
452+{
453+ return single_open(file, wil_txdesc_debugfs_show, inode->i_private);
454+}
455+
456+static const struct file_operations fops_txdesc = {
457+ .open = wil_txdesc_seq_open,
458+ .release = single_release,
459+ .read = seq_read,
460+ .llseek = seq_lseek,
461+};
462+
463+/*---------beamforming------------*/
464+static int wil_bf_debugfs_show(struct seq_file *s, void *data)
465+{
466+ struct wil6210_priv *wil = s->private;
467+ seq_printf(s,
468+ "TSF : 0x%016llx\n"
469+ "TxMCS : %d\n"
470+ "Sectors(rx:tx) my %2d:%2d peer %2d:%2d\n",
471+ wil->stats.tsf, wil->stats.bf_mcs,
472+ wil->stats.my_rx_sector, wil->stats.my_tx_sector,
473+ wil->stats.peer_rx_sector, wil->stats.peer_tx_sector);
474+ return 0;
475+}
476+
477+static int wil_bf_seq_open(struct inode *inode, struct file *file)
478+{
479+ return single_open(file, wil_bf_debugfs_show, inode->i_private);
480+}
481+
482+static const struct file_operations fops_bf = {
483+ .open = wil_bf_seq_open,
484+ .release = single_release,
485+ .read = seq_read,
486+ .llseek = seq_lseek,
487+};
488+/*---------SSID------------*/
489+static ssize_t wil_read_file_ssid(struct file *file, char __user *user_buf,
490+ size_t count, loff_t *ppos)
491+{
492+ struct wil6210_priv *wil = file->private_data;
493+ struct wireless_dev *wdev = wil_to_wdev(wil);
494+
495+ return simple_read_from_buffer(user_buf, count, ppos,
496+ wdev->ssid, wdev->ssid_len);
497+}
498+
499+static ssize_t wil_write_file_ssid(struct file *file, const char __user *buf,
500+ size_t count, loff_t *ppos)
501+{
502+ struct wil6210_priv *wil = file->private_data;
503+ struct wireless_dev *wdev = wil_to_wdev(wil);
504+ struct net_device *ndev = wil_to_ndev(wil);
505+
506+ if (*ppos != 0) {
507+ wil_err(wil, "Unable to set SSID substring from [%d]\n",
508+ (int)*ppos);
509+ return -EINVAL;
510+ }
511+
512+ if (count > sizeof(wdev->ssid)) {
513+ wil_err(wil, "SSID too long, len = %d\n", (int)count);
514+ return -EINVAL;
515+ }
516+ if (netif_running(ndev)) {
517+ wil_err(wil, "Unable to change SSID on running interface\n");
518+ return -EINVAL;
519+ }
520+
521+ wdev->ssid_len = count;
522+ return simple_write_to_buffer(wdev->ssid, wdev->ssid_len, ppos,
523+ buf, count);
524+}
525+
526+static const struct file_operations fops_ssid = {
527+ .read = wil_read_file_ssid,
528+ .write = wil_write_file_ssid,
529+ .open = wil_default_open,
530+};
531+
532+/*----------------*/
533+int wil6210_debugfs_init(struct wil6210_priv *wil)
534+{
535+ struct dentry *dbg = wil->debug = debugfs_create_dir(WIL_NAME,
536+ wil_to_wiphy(wil)->debugfsdir);
537+
538+ if (IS_ERR_OR_NULL(dbg))
539+ return -ENODEV;
540+
541+ debugfs_create_file("mbox", S_IRUGO, dbg, wil, &fops_mbox);
542+ debugfs_create_file("vrings", S_IRUGO, dbg, wil, &fops_vring);
543+ debugfs_create_file("txdesc", S_IRUGO, dbg, wil, &fops_txdesc);
544+ debugfs_create_u32("txdesc_index", S_IRUGO | S_IWUSR, dbg,
545+ &dbg_txdesc_index);
546+ debugfs_create_file("bf", S_IRUGO, dbg, wil, &fops_bf);
547+ debugfs_create_file("ssid", S_IRUGO | S_IWUSR, dbg, wil, &fops_ssid);
548+ debugfs_create_u32("secure_pcp", S_IRUGO | S_IWUSR, dbg,
549+ &wil->secure_pcp);
550+
551+ wil6210_debugfs_create_ISR(wil, "USER_ICR", dbg,
552+ HOSTADDR(RGF_USER_USER_ICR));
553+ wil6210_debugfs_create_ISR(wil, "DMA_EP_TX_ICR", dbg,
554+ HOSTADDR(RGF_DMA_EP_TX_ICR));
555+ wil6210_debugfs_create_ISR(wil, "DMA_EP_RX_ICR", dbg,
556+ HOSTADDR(RGF_DMA_EP_RX_ICR));
557+ wil6210_debugfs_create_ISR(wil, "DMA_EP_MISC_ICR", dbg,
558+ HOSTADDR(RGF_DMA_EP_MISC_ICR));
559+ wil6210_debugfs_create_pseudo_ISR(wil, dbg);
560+ wil6210_debugfs_create_ITR_CNT(wil, dbg);
561+
562+ debugfs_create_u32("mem_addr", S_IRUGO | S_IWUSR, dbg, &mem_addr);
563+ debugfs_create_file("mem_val", S_IRUGO, dbg, wil, &fops_memread);
564+
565+ debugfs_create_file("reset", S_IWUSR, dbg, wil, &fops_reset);
566+
567+ wil->rgf_blob.data = (void * __force)wil->csr + 0;
568+ wil->rgf_blob.size = 0xa000;
569+ wil_debugfs_create_ioblob("blob_rgf", S_IRUGO, dbg, &wil->rgf_blob);
570+
571+ wil->fw_code_blob.data = (void * __force)wil->csr + 0x40000;
572+ wil->fw_code_blob.size = 0x40000;
573+ wil_debugfs_create_ioblob("blob_fw_code", S_IRUGO, dbg,
574+ &wil->fw_code_blob);
575+
576+ wil->fw_data_blob.data = (void * __force)wil->csr + 0x80000;
577+ wil->fw_data_blob.size = 0x8000;
578+ wil_debugfs_create_ioblob("blob_fw_data", S_IRUGO, dbg,
579+ &wil->fw_data_blob);
580+
581+ wil->fw_peri_blob.data = (void * __force)wil->csr + 0x88000;
582+ wil->fw_peri_blob.size = 0x18000;
583+ wil_debugfs_create_ioblob("blob_fw_peri", S_IRUGO, dbg,
584+ &wil->fw_peri_blob);
585+
586+ wil->uc_code_blob.data = (void * __force)wil->csr + 0xa0000;
587+ wil->uc_code_blob.size = 0x10000;
588+ wil_debugfs_create_ioblob("blob_uc_code", S_IRUGO, dbg,
589+ &wil->uc_code_blob);
590+
591+ wil->uc_data_blob.data = (void * __force)wil->csr + 0xb0000;
592+ wil->uc_data_blob.size = 0x4000;
593+ wil_debugfs_create_ioblob("blob_uc_data", S_IRUGO, dbg,
594+ &wil->uc_data_blob);
595+
596+ return 0;
597+}
598+
599+void wil6210_debugfs_remove(struct wil6210_priv *wil)
600+{
601+ debugfs_remove_recursive(wil->debug);
602+ wil->debug = NULL;
603+}
drivers/net/wireless/ath/wil6210/interrupt.c+471−0
@@ -0,0 +1,471 @@
1+/*
2+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
3+ *
4+ * Permission to use, copy, modify, and/or distribute this software for any
5+ * purpose with or without fee is hereby granted, provided that the above
6+ * copyright notice and this permission notice appear in all copies.
7+ *
8+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+ */
16+
17+#include <linux/interrupt.h>
18+
19+#include "wil6210.h"
20+
21+/**
22+ * Theory of operation:
23+ *
24+ * There is ISR pseudo-cause register,
25+ * dma_rgf->DMA_RGF.PSEUDO_CAUSE.PSEUDO_CAUSE
26+ * Its bits represents OR'ed bits from 3 real ISR registers:
27+ * TX, RX, and MISC.
28+ *
29+ * Registers may be configured to either "write 1 to clear" or
30+ * "clear on read" mode
31+ *
32+ * When handling interrupt, one have to mask/unmask interrupts for the
33+ * real ISR registers, or hardware may malfunction.
34+ *
35+ */
36+
37+#define WIL6210_IRQ_DISABLE (0xFFFFFFFFUL)
38+#define WIL6210_IMC_RX BIT_DMA_EP_RX_ICR_RX_DONE
39+#define WIL6210_IMC_TX (BIT_DMA_EP_TX_ICR_TX_DONE | \
40+ BIT_DMA_EP_TX_ICR_TX_DONE_N(0))
41+#define WIL6210_IMC_MISC (ISR_MISC_FW_READY | ISR_MISC_MBOX_EVT)
42+
43+#define WIL6210_IRQ_PSEUDO_MASK (u32)(~(BIT_DMA_PSEUDO_CAUSE_RX | \
44+ BIT_DMA_PSEUDO_CAUSE_TX | \
45+ BIT_DMA_PSEUDO_CAUSE_MISC))
46+
47+#if defined(CONFIG_WIL6210_ISR_COR)
48+/* configure to Clear-On-Read mode */
49+#define WIL_ICR_ICC_VALUE (0xFFFFFFFFUL)
50+
51+static inline void wil_icr_clear(u32 x, void __iomem *addr)
52+{
53+
54+}
55+#else /* defined(CONFIG_WIL6210_ISR_COR) */
56+/* configure to Write-1-to-Clear mode */
57+#define WIL_ICR_ICC_VALUE (0UL)
58+
59+static inline void wil_icr_clear(u32 x, void __iomem *addr)
60+{
61+ iowrite32(x, addr);
62+}
63+#endif /* defined(CONFIG_WIL6210_ISR_COR) */
64+
65+static inline u32 wil_ioread32_and_clear(void __iomem *addr)
66+{
67+ u32 x = ioread32(addr);
68+
69+ wil_icr_clear(x, addr);
70+
71+ return x;
72+}
73+
74+static void wil6210_mask_irq_tx(struct wil6210_priv *wil)
75+{
76+ iowrite32(WIL6210_IRQ_DISABLE, wil->csr +
77+ HOSTADDR(RGF_DMA_EP_TX_ICR) +
78+ offsetof(struct RGF_ICR, IMS));
79+}
80+
81+static void wil6210_mask_irq_rx(struct wil6210_priv *wil)
82+{
83+ iowrite32(WIL6210_IRQ_DISABLE, wil->csr +
84+ HOSTADDR(RGF_DMA_EP_RX_ICR) +
85+ offsetof(struct RGF_ICR, IMS));
86+}
87+
88+static void wil6210_mask_irq_misc(struct wil6210_priv *wil)
89+{
90+ iowrite32(WIL6210_IRQ_DISABLE, wil->csr +
91+ HOSTADDR(RGF_DMA_EP_MISC_ICR) +
92+ offsetof(struct RGF_ICR, IMS));
93+}
94+
95+static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil)
96+{
97+ wil_dbg_IRQ(wil, "%s()\n", __func__);
98+
99+ iowrite32(WIL6210_IRQ_DISABLE, wil->csr +
100+ HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW));
101+
102+ clear_bit(wil_status_irqen, &wil->status);
103+}
104+
105+static void wil6210_unmask_irq_tx(struct wil6210_priv *wil)
106+{
107+ iowrite32(WIL6210_IMC_TX, wil->csr +
108+ HOSTADDR(RGF_DMA_EP_TX_ICR) +
109+ offsetof(struct RGF_ICR, IMC));
110+}
111+
112+static void wil6210_unmask_irq_rx(struct wil6210_priv *wil)
113+{
114+ iowrite32(WIL6210_IMC_RX, wil->csr +
115+ HOSTADDR(RGF_DMA_EP_RX_ICR) +
116+ offsetof(struct RGF_ICR, IMC));
117+}
118+
119+static void wil6210_unmask_irq_misc(struct wil6210_priv *wil)
120+{
121+ iowrite32(WIL6210_IMC_MISC, wil->csr +
122+ HOSTADDR(RGF_DMA_EP_MISC_ICR) +
123+ offsetof(struct RGF_ICR, IMC));
124+}
125+
126+static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil)
127+{
128+ wil_dbg_IRQ(wil, "%s()\n", __func__);
129+
130+ set_bit(wil_status_irqen, &wil->status);
131+
132+ iowrite32(WIL6210_IRQ_PSEUDO_MASK, wil->csr +
133+ HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW));
134+}
135+
136+void wil6210_disable_irq(struct wil6210_priv *wil)
137+{
138+ wil_dbg_IRQ(wil, "%s()\n", __func__);
139+
140+ wil6210_mask_irq_tx(wil);
141+ wil6210_mask_irq_rx(wil);
142+ wil6210_mask_irq_misc(wil);
143+ wil6210_mask_irq_pseudo(wil);
144+}
145+
146+void wil6210_enable_irq(struct wil6210_priv *wil)
147+{
148+ wil_dbg_IRQ(wil, "%s()\n", __func__);
149+
150+ iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_RX_ICR) +
151+ offsetof(struct RGF_ICR, ICC));
152+ iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_TX_ICR) +
153+ offsetof(struct RGF_ICR, ICC));
154+ iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) +
155+ offsetof(struct RGF_ICR, ICC));
156+
157+ wil6210_unmask_irq_pseudo(wil);
158+ wil6210_unmask_irq_tx(wil);
159+ wil6210_unmask_irq_rx(wil);
160+ wil6210_unmask_irq_misc(wil);
161+}
162+
163+static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
164+{
165+ struct wil6210_priv *wil = cookie;
166+ u32 isr = wil_ioread32_and_clear(wil->csr +
167+ HOSTADDR(RGF_DMA_EP_RX_ICR) +
168+ offsetof(struct RGF_ICR, ICR));
169+
170+ wil_dbg_IRQ(wil, "ISR RX 0x%08x\n", isr);
171+
172+ if (!isr) {
173+ wil_err(wil, "spurious IRQ: RX\n");
174+ return IRQ_NONE;
175+ }
176+
177+ wil6210_mask_irq_rx(wil);
178+
179+ if (isr & BIT_DMA_EP_RX_ICR_RX_DONE) {
180+ wil_dbg_IRQ(wil, "RX done\n");
181+ isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE;
182+ wil_rx_handle(wil);
183+ }
184+
185+ if (isr)
186+ wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr);
187+
188+ wil6210_unmask_irq_rx(wil);
189+
190+ return IRQ_HANDLED;
191+}
192+
193+static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
194+{
195+ struct wil6210_priv *wil = cookie;
196+ u32 isr = wil_ioread32_and_clear(wil->csr +
197+ HOSTADDR(RGF_DMA_EP_TX_ICR) +
198+ offsetof(struct RGF_ICR, ICR));
199+
200+ wil_dbg_IRQ(wil, "ISR TX 0x%08x\n", isr);
201+
202+ if (!isr) {
203+ wil_err(wil, "spurious IRQ: TX\n");
204+ return IRQ_NONE;
205+ }
206+
207+ wil6210_mask_irq_tx(wil);
208+
209+ if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) {
210+ uint i;
211+ wil_dbg_IRQ(wil, "TX done\n");
212+ isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE;
213+ for (i = 0; i < 24; i++) {
214+ u32 mask = BIT_DMA_EP_TX_ICR_TX_DONE_N(i);
215+ if (isr & mask) {
216+ isr &= ~mask;
217+ wil_dbg_IRQ(wil, "TX done(%i)\n", i);
218+ wil_tx_complete(wil, i);
219+ }
220+ }
221+ }
222+
223+ if (isr)
224+ wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr);
225+
226+ wil6210_unmask_irq_tx(wil);
227+
228+ return IRQ_HANDLED;
229+}
230+
231+static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
232+{
233+ struct wil6210_priv *wil = cookie;
234+ u32 isr = wil_ioread32_and_clear(wil->csr +
235+ HOSTADDR(RGF_DMA_EP_MISC_ICR) +
236+ offsetof(struct RGF_ICR, ICR));
237+
238+ wil_dbg_IRQ(wil, "ISR MISC 0x%08x\n", isr);
239+
240+ if (!isr) {
241+ wil_err(wil, "spurious IRQ: MISC\n");
242+ return IRQ_NONE;
243+ }
244+
245+ wil6210_mask_irq_misc(wil);
246+
247+ if (isr & ISR_MISC_FW_READY) {
248+ wil_dbg_IRQ(wil, "IRQ: FW ready\n");
249+ /**
250+ * Actual FW ready indicated by the
251+ * WMI_FW_READY_EVENTID
252+ */
253+ isr &= ~ISR_MISC_FW_READY;
254+ }
255+
256+ wil->isr_misc = isr;
257+
258+ if (isr) {
259+ return IRQ_WAKE_THREAD;
260+ } else {
261+ wil6210_unmask_irq_misc(wil);
262+ return IRQ_HANDLED;
263+ }
264+}
265+
266+static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie)
267+{
268+ struct wil6210_priv *wil = cookie;
269+ u32 isr = wil->isr_misc;
270+
271+ wil_dbg_IRQ(wil, "Thread ISR MISC 0x%08x\n", isr);
272+
273+ if (isr & ISR_MISC_MBOX_EVT) {
274+ wil_dbg_IRQ(wil, "MBOX event\n");
275+ wmi_recv_cmd(wil);
276+ isr &= ~ISR_MISC_MBOX_EVT;
277+ }
278+
279+ if (isr)
280+ wil_err(wil, "un-handled MISC ISR bits 0x%08x\n", isr);
281+
282+ wil->isr_misc = 0;
283+
284+ wil6210_unmask_irq_misc(wil);
285+
286+ return IRQ_HANDLED;
287+}
288+
289+/**
290+ * thread IRQ handler
291+ */
292+static irqreturn_t wil6210_thread_irq(int irq, void *cookie)
293+{
294+ struct wil6210_priv *wil = cookie;
295+
296+ wil_dbg_IRQ(wil, "Thread IRQ\n");
297+ /* Discover real IRQ cause */
298+ if (wil->isr_misc)
299+ wil6210_irq_misc_thread(irq, cookie);
300+
301+ wil6210_unmask_irq_pseudo(wil);
302+
303+ return IRQ_HANDLED;
304+}
305+
306+/* DEBUG
307+ * There is subtle bug in hardware that causes IRQ to raise when it should be
308+ * masked. It is quite rare and hard to debug.
309+ *
310+ * Catch irq issue if it happens and print all I can.
311+ */
312+static int wil6210_debug_irq_mask(struct wil6210_priv *wil, u32 pseudo_cause)
313+{
314+ if (!test_bit(wil_status_irqen, &wil->status)) {
315+ u32 icm_rx = wil_ioread32_and_clear(wil->csr +
316+ HOSTADDR(RGF_DMA_EP_RX_ICR) +
317+ offsetof(struct RGF_ICR, ICM));
318+ u32 icr_rx = wil_ioread32_and_clear(wil->csr +
319+ HOSTADDR(RGF_DMA_EP_RX_ICR) +
320+ offsetof(struct RGF_ICR, ICR));
321+ u32 imv_rx = ioread32(wil->csr +
322+ HOSTADDR(RGF_DMA_EP_RX_ICR) +
323+ offsetof(struct RGF_ICR, IMV));
324+ u32 icm_tx = wil_ioread32_and_clear(wil->csr +
325+ HOSTADDR(RGF_DMA_EP_TX_ICR) +
326+ offsetof(struct RGF_ICR, ICM));
327+ u32 icr_tx = wil_ioread32_and_clear(wil->csr +
328+ HOSTADDR(RGF_DMA_EP_TX_ICR) +
329+ offsetof(struct RGF_ICR, ICR));
330+ u32 imv_tx = ioread32(wil->csr +
331+ HOSTADDR(RGF_DMA_EP_TX_ICR) +
332+ offsetof(struct RGF_ICR, IMV));
333+ u32 icm_misc = wil_ioread32_and_clear(wil->csr +
334+ HOSTADDR(RGF_DMA_EP_MISC_ICR) +
335+ offsetof(struct RGF_ICR, ICM));
336+ u32 icr_misc = wil_ioread32_and_clear(wil->csr +
337+ HOSTADDR(RGF_DMA_EP_MISC_ICR) +
338+ offsetof(struct RGF_ICR, ICR));
339+ u32 imv_misc = ioread32(wil->csr +
340+ HOSTADDR(RGF_DMA_EP_MISC_ICR) +
341+ offsetof(struct RGF_ICR, IMV));
342+ wil_err(wil, "IRQ when it should be masked: pseudo 0x%08x\n"
343+ "Rx icm:icr:imv 0x%08x 0x%08x 0x%08x\n"
344+ "Tx icm:icr:imv 0x%08x 0x%08x 0x%08x\n"
345+ "Misc icm:icr:imv 0x%08x 0x%08x 0x%08x\n",
346+ pseudo_cause,
347+ icm_rx, icr_rx, imv_rx,
348+ icm_tx, icr_tx, imv_tx,
349+ icm_misc, icr_misc, imv_misc);
350+
351+ return -EINVAL;
352+ }
353+
354+ return 0;
355+}
356+
357+static irqreturn_t wil6210_hardirq(int irq, void *cookie)
358+{
359+ irqreturn_t rc = IRQ_HANDLED;
360+ struct wil6210_priv *wil = cookie;
361+ u32 pseudo_cause = ioread32(wil->csr + HOSTADDR(RGF_DMA_PSEUDO_CAUSE));
362+
363+ /**
364+ * pseudo_cause is Clear-On-Read, no need to ACK
365+ */
366+ if ((pseudo_cause == 0) || ((pseudo_cause & 0xff) == 0xff))
367+ return IRQ_NONE;
368+
369+ /* FIXME: IRQ mask debug */
370+ if (wil6210_debug_irq_mask(wil, pseudo_cause))
371+ return IRQ_NONE;
372+
373+ wil6210_mask_irq_pseudo(wil);
374+
375+ /* Discover real IRQ cause
376+ * There are 2 possible phases for every IRQ:
377+ * - hard IRQ handler called right here
378+ * - threaded handler called later
379+ *
380+ * Hard IRQ handler reads and clears ISR.
381+ *
382+ * If threaded handler requested, hard IRQ handler
383+ * returns IRQ_WAKE_THREAD and saves ISR register value
384+ * for the threaded handler use.
385+ *
386+ * voting for wake thread - need at least 1 vote
387+ */
388+ if ((pseudo_cause & BIT_DMA_PSEUDO_CAUSE_RX) &&
389+ (wil6210_irq_rx(irq, cookie) == IRQ_WAKE_THREAD))
390+ rc = IRQ_WAKE_THREAD;
391+
392+ if ((pseudo_cause & BIT_DMA_PSEUDO_CAUSE_TX) &&
393+ (wil6210_irq_tx(irq, cookie) == IRQ_WAKE_THREAD))
394+ rc = IRQ_WAKE_THREAD;
395+
396+ if ((pseudo_cause & BIT_DMA_PSEUDO_CAUSE_MISC) &&
397+ (wil6210_irq_misc(irq, cookie) == IRQ_WAKE_THREAD))
398+ rc = IRQ_WAKE_THREAD;
399+
400+ /* if thread is requested, it will unmask IRQ */
401+ if (rc != IRQ_WAKE_THREAD)
402+ wil6210_unmask_irq_pseudo(wil);
403+
404+ wil_dbg_IRQ(wil, "Hard IRQ 0x%08x\n", pseudo_cause);
405+
406+ return rc;
407+}
408+
409+static int wil6210_request_3msi(struct wil6210_priv *wil, int irq)
410+{
411+ int rc;
412+ /*
413+ * IRQ's are in the following order:
414+ * - Tx
415+ * - Rx
416+ * - Misc
417+ */
418+
419+ rc = request_irq(irq, wil6210_irq_tx, IRQF_SHARED,
420+ WIL_NAME"_tx", wil);
421+ if (rc)
422+ return rc;
423+
424+ rc = request_irq(irq + 1, wil6210_irq_rx, IRQF_SHARED,
425+ WIL_NAME"_rx", wil);
426+ if (rc)
427+ goto free0;
428+
429+ rc = request_threaded_irq(irq + 2, wil6210_irq_misc,
430+ wil6210_irq_misc_thread,
431+ IRQF_SHARED, WIL_NAME"_misc", wil);
432+ if (rc)
433+ goto free1;
434+
435+ return 0;
436+ /* error branch */
437+free1:
438+ free_irq(irq + 1, wil);
439+free0:
440+ free_irq(irq, wil);
441+
442+ return rc;
443+}
444+
445+int wil6210_init_irq(struct wil6210_priv *wil, int irq)
446+{
447+ int rc;
448+ if (wil->n_msi == 3)
449+ rc = wil6210_request_3msi(wil, irq);
450+ else
451+ rc = request_threaded_irq(irq, wil6210_hardirq,
452+ wil6210_thread_irq,
453+ wil->n_msi ? 0 : IRQF_SHARED,
454+ WIL_NAME, wil);
455+ if (rc)
456+ return rc;
457+
458+ wil6210_enable_irq(wil);
459+
460+ return 0;
461+}
462+
463+void wil6210_fini_irq(struct wil6210_priv *wil, int irq)
464+{
465+ wil6210_disable_irq(wil);
466+ free_irq(irq, wil);
467+ if (wil->n_msi == 3) {
468+ free_irq(irq + 1, wil);
469+ free_irq(irq + 2, wil);
470+ }
471+}
drivers/net/wireless/ath/wil6210/main.c+407−0
@@ -0,0 +1,407 @@
1+/*
2+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
3+ *
4+ * Permission to use, copy, modify, and/or distribute this software for any
5+ * purpose with or without fee is hereby granted, provided that the above
6+ * copyright notice and this permission notice appear in all copies.
7+ *
8+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+ */
16+
17+#include <linux/kernel.h>
18+#include <linux/netdevice.h>
19+#include <linux/sched.h>
20+#include <linux/ieee80211.h>
21+#include <linux/wireless.h>
22+#include <linux/slab.h>
23+#include <linux/moduleparam.h>
24+#include <linux/if_arp.h>
25+
26+#include "wil6210.h"
27+
28+/*
29+ * Due to a hardware issue,
30+ * one has to read/write to/from NIC in 32-bit chunks;
31+ * regular memcpy_fromio and siblings will
32+ * not work on 64-bit platform - it uses 64-bit transactions
33+ *
34+ * Force 32-bit transactions to enable NIC on 64-bit platforms
35+ *
36+ * To avoid byte swap on big endian host, __raw_{read|write}l
37+ * should be used - {read|write}l would swap bytes to provide
38+ * little endian on PCI value in host endianness.
39+ */
40+void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src,
41+ size_t count)
42+{
43+ u32 *d = dst;
44+ const volatile u32 __iomem *s = src;
45+
46+ /* size_t is unsigned, if (count%4 != 0) it will wrap */
47+ for (count += 4; count > 4; count -= 4)
48+ *d++ = __raw_readl(s++);
49+}
50+
51+void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
52+ size_t count)
53+{
54+ volatile u32 __iomem *d = dst;
55+ const u32 *s = src;
56+
57+ for (count += 4; count > 4; count -= 4)
58+ __raw_writel(*s++, d++);
59+}
60+
61+static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid)
62+{
63+ uint i;
64+ struct net_device *ndev = wil_to_ndev(wil);
65+ struct wireless_dev *wdev = wil->wdev;
66+
67+ wil_dbg(wil, "%s()\n", __func__);
68+
69+ wil_link_off(wil);
70+ clear_bit(wil_status_fwconnected, &wil->status);
71+
72+ switch (wdev->sme_state) {
73+ case CFG80211_SME_CONNECTED:
74+ cfg80211_disconnected(ndev, WLAN_STATUS_UNSPECIFIED_FAILURE,
75+ NULL, 0, GFP_KERNEL);
76+ break;
77+ case CFG80211_SME_CONNECTING:
78+ cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0,
79+ WLAN_STATUS_UNSPECIFIED_FAILURE,
80+ GFP_KERNEL);
81+ break;
82+ default:
83+ ;
84+ }
85+
86+ for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++)
87+ wil_vring_fini_tx(wil, i);
88+}
89+
90+static void wil_disconnect_worker(struct work_struct *work)
91+{
92+ struct wil6210_priv *wil = container_of(work,
93+ struct wil6210_priv, disconnect_worker);
94+
95+ _wil6210_disconnect(wil, NULL);
96+}
97+
98+static void wil_connect_timer_fn(ulong x)
99+{
100+ struct wil6210_priv *wil = (void *)x;
101+
102+ wil_dbg(wil, "Connect timeout\n");
103+
104+ /* reschedule to thread context - disconnect won't
105+ * run from atomic context
106+ */
107+ schedule_work(&wil->disconnect_worker);
108+}
109+
110+int wil_priv_init(struct wil6210_priv *wil)
111+{
112+ wil_dbg(wil, "%s()\n", __func__);
113+
114+ mutex_init(&wil->mutex);
115+ mutex_init(&wil->wmi_mutex);
116+
117+ init_completion(&wil->wmi_ready);
118+
119+ wil->pending_connect_cid = -1;
120+ setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil);
121+
122+ INIT_WORK(&wil->wmi_connect_worker, wmi_connect_worker);
123+ INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker);
124+ INIT_WORK(&wil->wmi_event_worker, wmi_event_worker);
125+
126+ INIT_LIST_HEAD(&wil->pending_wmi_ev);
127+ spin_lock_init(&wil->wmi_ev_lock);
128+
129+ wil->wmi_wq = create_singlethread_workqueue(WIL_NAME"_wmi");
130+ if (!wil->wmi_wq)
131+ return -EAGAIN;
132+
133+ wil->wmi_wq_conn = create_singlethread_workqueue(WIL_NAME"_connect");
134+ if (!wil->wmi_wq_conn) {
135+ destroy_workqueue(wil->wmi_wq);
136+ return -EAGAIN;
137+ }
138+
139+ /* make shadow copy of registers that should not change on run time */
140+ wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
141+ sizeof(struct wil6210_mbox_ctl));
142+ wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx);
143+ wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
144+
145+ return 0;
146+}
147+
148+void wil6210_disconnect(struct wil6210_priv *wil, void *bssid)
149+{
150+ del_timer_sync(&wil->connect_timer);
151+ _wil6210_disconnect(wil, bssid);
152+}
153+
154+void wil_priv_deinit(struct wil6210_priv *wil)
155+{
156+ cancel_work_sync(&wil->disconnect_worker);
157+ wil6210_disconnect(wil, NULL);
158+ wmi_event_flush(wil);
159+ destroy_workqueue(wil->wmi_wq_conn);
160+ destroy_workqueue(wil->wmi_wq);
161+}
162+
163+static void wil_target_reset(struct wil6210_priv *wil)
164+{
165+ wil_dbg(wil, "Resetting...\n");
166+
167+ /* register write */
168+#define W(a, v) iowrite32(v, wil->csr + HOSTADDR(a))
169+ /* register set = read, OR, write */
170+#define S(a, v) iowrite32(ioread32(wil->csr + HOSTADDR(a)) | v, \
171+ wil->csr + HOSTADDR(a))
172+
173+ /* hpal_perst_from_pad_src_n_mask */
174+ S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(6));
175+ /* car_perst_rst_src_n_mask */
176+ S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(7));
177+
178+ W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */
179+ W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */
180+
181+ msleep(100);
182+
183+ W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000);
184+ W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F);
185+ W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000170);
186+ W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00);
187+
188+ msleep(100);
189+
190+ W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0);
191+ W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0);
192+ W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0);
193+ W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
194+
195+ W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001);
196+ W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080);
197+ W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
198+
199+ msleep(2000);
200+
201+ W(RGF_USER_USER_CPU_0, BIT(0)); /* user_cpu_man_de_rst */
202+
203+ msleep(2000);
204+
205+ wil_dbg(wil, "Reset completed\n");
206+
207+#undef W
208+#undef S
209+}
210+
211+void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r)
212+{
213+ le32_to_cpus(&r->base);
214+ le16_to_cpus(&r->entry_size);
215+ le16_to_cpus(&r->size);
216+ le32_to_cpus(&r->tail);
217+ le32_to_cpus(&r->head);
218+}
219+
220+static int wil_wait_for_fw_ready(struct wil6210_priv *wil)
221+{
222+ ulong to = msecs_to_jiffies(1000);
223+ ulong left = wait_for_completion_timeout(&wil->wmi_ready, to);
224+ if (0 == left) {
225+ wil_err(wil, "Firmware not ready\n");
226+ return -ETIME;
227+ } else {
228+ wil_dbg(wil, "FW ready after %d ms\n",
229+ jiffies_to_msecs(to-left));
230+ }
231+ return 0;
232+}
233+
234+/*
235+ * We reset all the structures, and we reset the UMAC.
236+ * After calling this routine, you're expected to reload
237+ * the firmware.
238+ */
239+int wil_reset(struct wil6210_priv *wil)
240+{
241+ int rc;
242+
243+ cancel_work_sync(&wil->disconnect_worker);
244+ wil6210_disconnect(wil, NULL);
245+
246+ wmi_event_flush(wil);
247+
248+ flush_workqueue(wil->wmi_wq);
249+ flush_workqueue(wil->wmi_wq_conn);
250+
251+ wil6210_disable_irq(wil);
252+ wil->status = 0;
253+
254+ /* TODO: put MAC in reset */
255+ wil_target_reset(wil);
256+
257+ /* init after reset */
258+ wil->pending_connect_cid = -1;
259+ INIT_COMPLETION(wil->wmi_ready);
260+
261+ /* make shadow copy of registers that should not change on run time */
262+ wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
263+ sizeof(struct wil6210_mbox_ctl));
264+ wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx);
265+ wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
266+
267+ /* TODO: release MAC reset */
268+ wil6210_enable_irq(wil);
269+
270+ /* we just started MAC, wait for FW ready */
271+ rc = wil_wait_for_fw_ready(wil);
272+
273+ return rc;
274+}
275+
276+
277+void wil_link_on(struct wil6210_priv *wil)
278+{
279+ struct net_device *ndev = wil_to_ndev(wil);
280+
281+ wil_dbg(wil, "%s()\n", __func__);
282+
283+ netif_carrier_on(ndev);
284+ netif_tx_wake_all_queues(ndev);
285+}
286+
287+void wil_link_off(struct wil6210_priv *wil)
288+{
289+ struct net_device *ndev = wil_to_ndev(wil);
290+
291+ wil_dbg(wil, "%s()\n", __func__);
292+
293+ netif_tx_stop_all_queues(ndev);
294+ netif_carrier_off(ndev);
295+}
296+
297+static int __wil_up(struct wil6210_priv *wil)
298+{
299+ struct net_device *ndev = wil_to_ndev(wil);
300+ struct wireless_dev *wdev = wil->wdev;
301+ struct ieee80211_channel *channel = wdev->preset_chandef.chan;
302+ int rc;
303+ int bi;
304+ u16 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);
305+
306+ rc = wil_reset(wil);
307+ if (rc)
308+ return rc;
309+
310+ /* FIXME Firmware works now in PBSS mode(ToDS=0, FromDS=0) */
311+ wmi_nettype = wil_iftype_nl2wmi(NL80211_IFTYPE_ADHOC);
312+ switch (wdev->iftype) {
313+ case NL80211_IFTYPE_STATION:
314+ wil_dbg(wil, "type: STATION\n");
315+ bi = 0;
316+ ndev->type = ARPHRD_ETHER;
317+ break;
318+ case NL80211_IFTYPE_AP:
319+ wil_dbg(wil, "type: AP\n");
320+ bi = 100;
321+ ndev->type = ARPHRD_ETHER;
322+ break;
323+ case NL80211_IFTYPE_P2P_CLIENT:
324+ wil_dbg(wil, "type: P2P_CLIENT\n");
325+ bi = 0;
326+ ndev->type = ARPHRD_ETHER;
327+ break;
328+ case NL80211_IFTYPE_P2P_GO:
329+ wil_dbg(wil, "type: P2P_GO\n");
330+ bi = 100;
331+ ndev->type = ARPHRD_ETHER;
332+ break;
333+ case NL80211_IFTYPE_MONITOR:
334+ wil_dbg(wil, "type: Monitor\n");
335+ bi = 0;
336+ ndev->type = ARPHRD_IEEE80211_RADIOTAP;
337+ /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_RADIOTAP ? */
338+ break;
339+ default:
340+ return -EOPNOTSUPP;
341+ }
342+
343+ /* Apply profile in the following order: */
344+ /* SSID and channel for the AP */
345+ switch (wdev->iftype) {
346+ case NL80211_IFTYPE_AP:
347+ case NL80211_IFTYPE_P2P_GO:
348+ if (wdev->ssid_len == 0) {
349+ wil_err(wil, "SSID not set\n");
350+ return -EINVAL;
351+ }
352+ wmi_set_ssid(wil, wdev->ssid_len, wdev->ssid);
353+ if (channel)
354+ wmi_set_channel(wil, channel->hw_value);
355+ break;
356+ default:
357+ ;
358+ }
359+
360+ /* MAC address - pre-requisite for other commands */
361+ wmi_set_mac_address(wil, ndev->dev_addr);
362+
363+ /* Set up beaconing if required. */
364+ rc = wmi_set_bcon(wil, bi, wmi_nettype);
365+ if (rc)
366+ return rc;
367+
368+ /* Rx VRING. After MAC and beacon */
369+ wil_rx_init(wil);
370+
371+ return 0;
372+}
373+
374+int wil_up(struct wil6210_priv *wil)
375+{
376+ int rc;
377+
378+ mutex_lock(&wil->mutex);
379+ rc = __wil_up(wil);
380+ mutex_unlock(&wil->mutex);
381+
382+ return rc;
383+}
384+
385+static int __wil_down(struct wil6210_priv *wil)
386+{
387+ if (wil->scan_request) {
388+ cfg80211_scan_done(wil->scan_request, true);
389+ wil->scan_request = NULL;
390+ }
391+
392+ wil6210_disconnect(wil, NULL);
393+ wil_rx_fini(wil);
394+
395+ return 0;
396+}
397+
398+int wil_down(struct wil6210_priv *wil)
399+{
400+ int rc;
401+
402+ mutex_lock(&wil->mutex);
403+ rc = __wil_down(wil);
404+ mutex_unlock(&wil->mutex);
405+
406+ return rc;
407+}
drivers/net/wireless/ath/wil6210/netdev.c+157−0
@@ -0,0 +1,157 @@
1+/*
2+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
3+ *
4+ * Permission to use, copy, modify, and/or distribute this software for any
5+ * purpose with or without fee is hereby granted, provided that the above
6+ * copyright notice and this permission notice appear in all copies.
7+ *
8+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+ */
16+
17+#include <linux/module.h>
18+#include <linux/netdevice.h>
19+#include <linux/etherdevice.h>
20+#include <linux/slab.h>
21+
22+#include "wil6210.h"
23+
24+static int wil_open(struct net_device *ndev)
25+{
26+ struct wil6210_priv *wil = ndev_to_wil(ndev);
27+
28+ return wil_up(wil);
29+}
30+
31+static int wil_stop(struct net_device *ndev)
32+{
33+ struct wil6210_priv *wil = ndev_to_wil(ndev);
34+
35+ return wil_down(wil);
36+}
37+
38+/*
39+ * AC to queue mapping
40+ *
41+ * AC_VO -> queue 3
42+ * AC_VI -> queue 2
43+ * AC_BE -> queue 1
44+ * AC_BK -> queue 0
45+ */
46+static u16 wil_select_queue(struct net_device *ndev, struct sk_buff *skb)
47+{
48+ static const u16 wil_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
49+ struct wil6210_priv *wil = ndev_to_wil(ndev);
50+ u16 rc;
51+
52+ skb->priority = cfg80211_classify8021d(skb);
53+
54+ rc = wil_1d_to_queue[skb->priority];
55+
56+ wil_dbg_TXRX(wil, "%s() %d -> %d\n", __func__, (int)skb->priority,
57+ (int)rc);
58+
59+ return rc;
60+}
61+
62+static const struct net_device_ops wil_netdev_ops = {
63+ .ndo_open = wil_open,
64+ .ndo_stop = wil_stop,
65+ .ndo_start_xmit = wil_start_xmit,
66+ .ndo_select_queue = wil_select_queue,
67+ .ndo_set_mac_address = eth_mac_addr,
68+ .ndo_validate_addr = eth_validate_addr,
69+};
70+
71+void *wil_if_alloc(struct device *dev, void __iomem *csr)
72+{
73+ struct net_device *ndev;
74+ struct wireless_dev *wdev;
75+ struct wil6210_priv *wil;
76+ struct ieee80211_channel *ch;
77+ int rc = 0;
78+
79+ wdev = wil_cfg80211_init(dev);
80+ if (IS_ERR(wdev)) {
81+ dev_err(dev, "wil_cfg80211_init failed\n");
82+ return wdev;
83+ }
84+
85+ wil = wdev_to_wil(wdev);
86+ wil->csr = csr;
87+ wil->wdev = wdev;
88+
89+ rc = wil_priv_init(wil);
90+ if (rc) {
91+ dev_err(dev, "wil_priv_init failed\n");
92+ goto out_wdev;
93+ }
94+
95+ wdev->iftype = NL80211_IFTYPE_STATION; /* TODO */
96+ /* default monitor channel */
97+ ch = wdev->wiphy->bands[IEEE80211_BAND_60GHZ]->channels;
98+ cfg80211_chandef_create(&wdev->preset_chandef, ch, NL80211_CHAN_NO_HT);
99+
100+ ndev = alloc_netdev_mqs(0, "wlan%d", ether_setup, WIL6210_TX_QUEUES, 1);
101+ if (!ndev) {
102+ dev_err(dev, "alloc_netdev_mqs failed\n");
103+ rc = -ENOMEM;
104+ goto out_priv;
105+ }
106+
107+ ndev->netdev_ops = &wil_netdev_ops;
108+ ndev->ieee80211_ptr = wdev;
109+ SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
110+ wdev->netdev = ndev;
111+
112+ wil_link_off(wil);
113+
114+ return wil;
115+
116+ out_priv:
117+ wil_priv_deinit(wil);
118+
119+ out_wdev:
120+ wil_wdev_free(wil);
121+
122+ return ERR_PTR(rc);
123+}
124+
125+void wil_if_free(struct wil6210_priv *wil)
126+{
127+ struct net_device *ndev = wil_to_ndev(wil);
128+ if (!ndev)
129+ return;
130+
131+ free_netdev(ndev);
132+ wil_priv_deinit(wil);
133+ wil_wdev_free(wil);
134+}
135+
136+int wil_if_add(struct wil6210_priv *wil)
137+{
138+ struct net_device *ndev = wil_to_ndev(wil);
139+ int rc;
140+
141+ rc = register_netdev(ndev);
142+ if (rc < 0) {
143+ dev_err(&ndev->dev, "Failed to register netdev: %d\n", rc);
144+ return rc;
145+ }
146+
147+ wil_link_off(wil);
148+
149+ return 0;
150+}
151+
152+void wil_if_remove(struct wil6210_priv *wil)
153+{
154+ struct net_device *ndev = wil_to_ndev(wil);
155+
156+ unregister_netdev(ndev);
157+}
drivers/net/wireless/ath/wil6210/pcie_bus.c+223−0
@@ -0,0 +1,223 @@
1+/*
2+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
3+ *
4+ * Permission to use, copy, modify, and/or distribute this software for any
5+ * purpose with or without fee is hereby granted, provided that the above
6+ * copyright notice and this permission notice appear in all copies.
7+ *
8+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+ */
16+
17+#include <linux/kernel.h>
18+#include <linux/module.h>
19+#include <linux/slab.h>
20+#include <linux/netdevice.h>
21+#include <linux/debugfs.h>
22+#include <linux/pci.h>
23+#include <linux/moduleparam.h>
24+
25+#include "wil6210.h"
26+
27+static int use_msi = 1;
28+module_param(use_msi, int, S_IRUGO);
29+MODULE_PARM_DESC(use_msi,
30+ " Use MSI interrupt: "
31+ "0 - don't, 1 - (default) - single, or 3");
32+
33+/* Bus ops */
34+static int wil_if_pcie_enable(struct wil6210_priv *wil)
35+{
36+ struct pci_dev *pdev = wil->pdev;
37+ int rc;
38+
39+ pci_set_master(pdev);
40+
41+ /*
42+ * how many MSI interrupts to request?
43+ */
44+ switch (use_msi) {
45+ case 3:
46+ case 1:
47+ case 0:
48+ break;
49+ default:
50+ wil_err(wil, "Invalid use_msi=%d, default to 1\n",
51+ use_msi);
52+ use_msi = 1;
53+ }
54+ wil->n_msi = use_msi;
55+ if (wil->n_msi) {
56+ wil_dbg(wil, "Setup %d MSI interrupts\n", use_msi);
57+ rc = pci_enable_msi_block(pdev, wil->n_msi);
58+ if (rc && (wil->n_msi == 3)) {
59+ wil_err(wil, "3 MSI mode failed, try 1 MSI\n");
60+ wil->n_msi = 1;
61+ rc = pci_enable_msi_block(pdev, wil->n_msi);
62+ }
63+ if (rc) {
64+ wil_err(wil, "pci_enable_msi failed, use INTx\n");
65+ wil->n_msi = 0;
66+ }
67+ } else {
68+ wil_dbg(wil, "MSI interrupts disabled, use INTx\n");
69+ }
70+
71+ rc = wil6210_init_irq(wil, pdev->irq);
72+ if (rc)
73+ goto stop_master;
74+
75+ /* need reset here to obtain MAC */
76+ rc = wil_reset(wil);
77+ if (rc)
78+ goto release_irq;
79+
80+ return 0;
81+
82+ release_irq:
83+ wil6210_fini_irq(wil, pdev->irq);
84+ /* safe to call if no MSI */
85+ pci_disable_msi(pdev);
86+ stop_master:
87+ pci_clear_master(pdev);
88+ return rc;
89+}
90+
91+static int wil_if_pcie_disable(struct wil6210_priv *wil)
92+{
93+ struct pci_dev *pdev = wil->pdev;
94+
95+ pci_clear_master(pdev);
96+ /* disable and release IRQ */
97+ wil6210_fini_irq(wil, pdev->irq);
98+ /* safe to call if no MSI */
99+ pci_disable_msi(pdev);
100+ /* TODO: disable HW */
101+
102+ return 0;
103+}
104+
105+static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
106+{
107+ struct wil6210_priv *wil;
108+ struct device *dev = &pdev->dev;
109+ void __iomem *csr;
110+ int rc;
111+
112+ /* check HW */
113+ dev_info(&pdev->dev, WIL_NAME " device found [%04x:%04x] (rev %x)\n",
114+ (int)pdev->vendor, (int)pdev->device, (int)pdev->revision);
115+
116+ if (pci_resource_len(pdev, 0) != WIL6210_MEM_SIZE) {
117+ dev_err(&pdev->dev, "Not " WIL_NAME "? "
118+ "BAR0 size is %lu while expecting %lu\n",
119+ (ulong)pci_resource_len(pdev, 0), WIL6210_MEM_SIZE);
120+ return -ENODEV;
121+ }
122+
123+ rc = pci_enable_device(pdev);
124+ if (rc) {
125+ dev_err(&pdev->dev, "pci_enable_device failed\n");
126+ return -ENODEV;
127+ }
128+ /* rollback to err_disable_pdev */
129+
130+ rc = pci_request_region(pdev, 0, WIL_NAME);
131+ if (rc) {
132+ dev_err(&pdev->dev, "pci_request_region failed\n");
133+ goto err_disable_pdev;
134+ }
135+ /* rollback to err_release_reg */
136+
137+ csr = pci_ioremap_bar(pdev, 0);
138+ if (!csr) {
139+ dev_err(&pdev->dev, "pci_ioremap_bar failed\n");
140+ rc = -ENODEV;
141+ goto err_release_reg;
142+ }
143+ /* rollback to err_iounmap */
144+ dev_info(&pdev->dev, "CSR at %pR -> %p\n", &pdev->resource[0], csr);
145+
146+ wil = wil_if_alloc(dev, csr);
147+ if (IS_ERR(wil)) {
148+ rc = (int)PTR_ERR(wil);
149+ dev_err(dev, "wil_if_alloc failed: %d\n", rc);
150+ goto err_iounmap;
151+ }
152+ /* rollback to if_free */
153+
154+ pci_set_drvdata(pdev, wil);
155+ wil->pdev = pdev;
156+
157+ /* FW should raise IRQ when ready */
158+ rc = wil_if_pcie_enable(wil);
159+ if (rc) {
160+ wil_err(wil, "Enable device failed\n");
161+ goto if_free;
162+ }
163+ /* rollback to bus_disable */
164+
165+ rc = wil_if_add(wil);
166+ if (rc) {
167+ wil_err(wil, "wil_if_add failed: %d\n", rc);
168+ goto bus_disable;
169+ }
170+
171+ wil6210_debugfs_init(wil);
172+
173+ /* check FW is alive */
174+ wmi_echo(wil);
175+
176+ return 0;
177+
178+ bus_disable:
179+ wil_if_pcie_disable(wil);
180+ if_free:
181+ wil_if_free(wil);
182+ err_iounmap:
183+ pci_iounmap(pdev, csr);
184+ err_release_reg:
185+ pci_release_region(pdev, 0);
186+ err_disable_pdev:
187+ pci_disable_device(pdev);
188+
189+ return rc;
190+}
191+
192+static void wil_pcie_remove(struct pci_dev *pdev)
193+{
194+ struct wil6210_priv *wil = pci_get_drvdata(pdev);
195+
196+ wil6210_debugfs_remove(wil);
197+ wil_if_pcie_disable(wil);
198+ wil_if_remove(wil);
199+ wil_if_free(wil);
200+ pci_iounmap(pdev, wil->csr);
201+ pci_release_region(pdev, 0);
202+ pci_disable_device(pdev);
203+ pci_set_drvdata(pdev, NULL);
204+}
205+
206+static DEFINE_PCI_DEVICE_TABLE(wil6210_pcie_ids) = {
207+ { PCI_DEVICE(0x1ae9, 0x0301) },
208+ { /* end: all zeroes */ },
209+};
210+MODULE_DEVICE_TABLE(pci, wil6210_pcie_ids);
211+
212+static struct pci_driver wil6210_driver = {
213+ .probe = wil_pcie_probe,
214+ .remove = wil_pcie_remove,
215+ .id_table = wil6210_pcie_ids,
216+ .name = WIL_NAME,
217+};
218+
219+module_pci_driver(wil6210_driver);
220+
221+MODULE_LICENSE("Dual BSD/GPL");
222+MODULE_AUTHOR("Qualcomm Atheros <wil6210@qca.qualcomm.com>");
223+MODULE_DESCRIPTION("Driver for 60g WiFi WIL6210 card");
drivers/net/wireless/ath/wil6210/txrx.c+871−0
@@ -0,0 +1,871 @@
1+/*
2+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
3+ *
4+ * Permission to use, copy, modify, and/or distribute this software for any
5+ * purpose with or without fee is hereby granted, provided that the above
6+ * copyright notice and this permission notice appear in all copies.
7+ *
8+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+ */
16+
17+#include <linux/kernel.h>
18+#include <linux/netdevice.h>
19+#include <linux/etherdevice.h>
20+#include <linux/hardirq.h>
21+#include <net/ieee80211_radiotap.h>
22+#include <linux/if_arp.h>
23+#include <linux/moduleparam.h>
24+
25+#include "wil6210.h"
26+#include "wmi.h"
27+#include "txrx.h"
28+
29+static bool rtap_include_phy_info;
30+module_param(rtap_include_phy_info, bool, S_IRUGO);
31+MODULE_PARM_DESC(rtap_include_phy_info,
32+ " Include PHY info in the radiotap header, default - no");
33+
34+static inline int wil_vring_is_empty(struct vring *vring)
35+{
36+ return vring->swhead == vring->swtail;
37+}
38+
39+static inline u32 wil_vring_next_tail(struct vring *vring)
40+{
41+ return (vring->swtail + 1) % vring->size;
42+}
43+
44+static inline void wil_vring_advance_head(struct vring *vring, int n)
45+{
46+ vring->swhead = (vring->swhead + n) % vring->size;
47+}
48+
49+static inline int wil_vring_is_full(struct vring *vring)
50+{
51+ return wil_vring_next_tail(vring) == vring->swhead;
52+}
53+/*
54+ * Available space in Tx Vring
55+ */
56+static inline int wil_vring_avail_tx(struct vring *vring)
57+{
58+ u32 swhead = vring->swhead;
59+ u32 swtail = vring->swtail;
60+ int used = (vring->size + swhead - swtail) % vring->size;
61+
62+ return vring->size - used - 1;
63+}
64+
65+static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
66+{
67+ struct device *dev = wil_to_dev(wil);
68+ size_t sz = vring->size * sizeof(vring->va[0]);
69+ uint i;
70+
71+ BUILD_BUG_ON(sizeof(vring->va[0]) != 32);
72+
73+ vring->swhead = 0;
74+ vring->swtail = 0;
75+ vring->ctx = kzalloc(vring->size * sizeof(vring->ctx[0]), GFP_KERNEL);
76+ if (!vring->ctx) {
77+ wil_err(wil, "vring_alloc [%d] failed to alloc ctx mem\n",
78+ vring->size);
79+ vring->va = NULL;
80+ return -ENOMEM;
81+ }
82+ /*
83+ * vring->va should be aligned on its size rounded up to power of 2
84+ * This is granted by the dma_alloc_coherent
85+ */
86+ vring->va = dma_alloc_coherent(dev, sz, &vring->pa, GFP_KERNEL);
87+ if (!vring->va) {
88+ wil_err(wil, "vring_alloc [%d] failed to alloc DMA mem\n",
89+ vring->size);
90+ kfree(vring->ctx);
91+ vring->ctx = NULL;
92+ return -ENOMEM;
93+ }
94+ /* initially, all descriptors are SW owned
95+ * For Tx and Rx, ownership bit is at the same location, thus
96+ * we can use any
97+ */
98+ for (i = 0; i < vring->size; i++) {
99+ volatile struct vring_tx_desc *d = &(vring->va[i].tx);
100+ d->dma.status = TX_DMA_STATUS_DU;
101+ }
102+
103+ wil_dbg(wil, "vring[%d] 0x%p:0x%016llx 0x%p\n", vring->size,
104+ vring->va, (unsigned long long)vring->pa, vring->ctx);
105+
106+ return 0;
107+}
108+
109+static void wil_vring_free(struct wil6210_priv *wil, struct vring *vring,
110+ int tx)
111+{
112+ struct device *dev = wil_to_dev(wil);
113+ size_t sz = vring->size * sizeof(vring->va[0]);
114+
115+ while (!wil_vring_is_empty(vring)) {
116+ if (tx) {
117+ volatile struct vring_tx_desc *d =
118+ &vring->va[vring->swtail].tx;
119+ dma_addr_t pa = d->dma.addr_low |
120+ ((u64)d->dma.addr_high << 32);
121+ struct sk_buff *skb = vring->ctx[vring->swtail];
122+ if (skb) {
123+ dma_unmap_single(dev, pa, d->dma.length,
124+ DMA_TO_DEVICE);
125+ dev_kfree_skb_any(skb);
126+ vring->ctx[vring->swtail] = NULL;
127+ } else {
128+ dma_unmap_page(dev, pa, d->dma.length,
129+ DMA_TO_DEVICE);
130+ }
131+ vring->swtail = wil_vring_next_tail(vring);
132+ } else { /* rx */
133+ volatile struct vring_rx_desc *d =
134+ &vring->va[vring->swtail].rx;
135+ dma_addr_t pa = d->dma.addr_low |
136+ ((u64)d->dma.addr_high << 32);
137+ struct sk_buff *skb = vring->ctx[vring->swhead];
138+ dma_unmap_single(dev, pa, d->dma.length,
139+ DMA_FROM_DEVICE);
140+ kfree_skb(skb);
141+ wil_vring_advance_head(vring, 1);
142+ }
143+ }
144+ dma_free_coherent(dev, sz, (void *)vring->va, vring->pa);
145+ kfree(vring->ctx);
146+ vring->pa = 0;
147+ vring->va = NULL;
148+ vring->ctx = NULL;
149+}
150+
151+/**
152+ * Allocate one skb for Rx VRING
153+ *
154+ * Safe to call from IRQ
155+ */
156+static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring,
157+ u32 i, int headroom)
158+{
159+ struct device *dev = wil_to_dev(wil);
160+ unsigned int sz = RX_BUF_LEN;
161+ volatile struct vring_rx_desc *d = &(vring->va[i].rx);
162+ dma_addr_t pa;
163+
164+ /* TODO align */
165+ struct sk_buff *skb = dev_alloc_skb(sz + headroom);
166+ if (unlikely(!skb))
167+ return -ENOMEM;
168+
169+ skb_reserve(skb, headroom);
170+ skb_put(skb, sz);
171+
172+ pa = dma_map_single(dev, skb->data, skb->len, DMA_FROM_DEVICE);
173+ if (unlikely(dma_mapping_error(dev, pa))) {
174+ kfree_skb(skb);
175+ return -ENOMEM;
176+ }
177+
178+ d->dma.d0 = BIT(9) | RX_DMA_D0_CMD_DMA_IT;
179+ d->dma.addr_low = lower_32_bits(pa);
180+ d->dma.addr_high = (u16)upper_32_bits(pa);
181+ /* ip_length don't care */
182+ /* b11 don't care */
183+ /* error don't care */
184+ d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */
185+ d->dma.length = sz;
186+ vring->ctx[i] = skb;
187+
188+ return 0;
189+}
190+
191+/**
192+ * Adds radiotap header
193+ *
194+ * Any error indicated as "Bad FCS"
195+ *
196+ * Vendor data for 04:ce:14-1 (Wilocity-1) consists of:
197+ * - Rx descriptor: 32 bytes
198+ * - Phy info
199+ */
200+static void wil_rx_add_radiotap_header(struct wil6210_priv *wil,
201+ struct sk_buff *skb,
202+ volatile struct vring_rx_desc *d)
203+{
204+ struct wireless_dev *wdev = wil->wdev;
205+ struct wil6210_rtap {
206+ struct ieee80211_radiotap_header rthdr;
207+ /* fields should be in the order of bits in rthdr.it_present */
208+ /* flags */
209+ u8 flags;
210+ /* channel */
211+ __le16 chnl_freq __aligned(2);
212+ __le16 chnl_flags;
213+ /* MCS */
214+ u8 mcs_present;
215+ u8 mcs_flags;
216+ u8 mcs_index;
217+ } __packed;
218+ struct wil6210_rtap_vendor {
219+ struct wil6210_rtap rtap;
220+ /* vendor */
221+ u8 vendor_oui[3] __aligned(2);
222+ u8 vendor_ns;
223+ __le16 vendor_skip;
224+ u8 vendor_data[0];
225+ } __packed;
226+ struct wil6210_rtap_vendor *rtap_vendor;
227+ int rtap_len = sizeof(struct wil6210_rtap);
228+ int phy_length = 0; /* phy info header size, bytes */
229+ static char phy_data[128];
230+ struct ieee80211_channel *ch = wdev->preset_chandef.chan;
231+
232+ if (rtap_include_phy_info) {
233+ rtap_len = sizeof(*rtap_vendor) + sizeof(*d);
234+ /* calculate additional length */
235+ if (d->dma.status & RX_DMA_STATUS_PHY_INFO) {
236+ /**
237+ * PHY info starts from 8-byte boundary
238+ * there are 8-byte lines, last line may be partially
239+ * written (HW bug), thus FW configures for last line
240+ * to be excessive. Driver skips this last line.
241+ */
242+ int len = min_t(int, 8 + sizeof(phy_data),
243+ wil_rxdesc_phy_length(d));
244+ if (len > 8) {
245+ void *p = skb_tail_pointer(skb);
246+ void *pa = PTR_ALIGN(p, 8);
247+ if (skb_tailroom(skb) >= len + (pa - p)) {
248+ phy_length = len - 8;
249+ memcpy(phy_data, pa, phy_length);
250+ }
251+ }
252+ }
253+ rtap_len += phy_length;
254+ }
255+
256+ if (skb_headroom(skb) < rtap_len &&
257+ pskb_expand_head(skb, rtap_len, 0, GFP_ATOMIC)) {
258+ wil_err(wil, "Unable to expand headrom to %d\n", rtap_len);
259+ return;
260+ }
261+
262+ rtap_vendor = (void *)skb_push(skb, rtap_len);
263+ memset(rtap_vendor, 0, rtap_len);
264+
265+ rtap_vendor->rtap.rthdr.it_version = PKTHDR_RADIOTAP_VERSION;
266+ rtap_vendor->rtap.rthdr.it_len = cpu_to_le16(rtap_len);
267+ rtap_vendor->rtap.rthdr.it_present = cpu_to_le32(
268+ (1 << IEEE80211_RADIOTAP_FLAGS) |
269+ (1 << IEEE80211_RADIOTAP_CHANNEL) |
270+ (1 << IEEE80211_RADIOTAP_MCS));
271+ if (d->dma.status & RX_DMA_STATUS_ERROR)
272+ rtap_vendor->rtap.flags |= IEEE80211_RADIOTAP_F_BADFCS;
273+
274+ rtap_vendor->rtap.chnl_freq = cpu_to_le16(ch ? ch->center_freq : 58320);
275+ rtap_vendor->rtap.chnl_flags = cpu_to_le16(0);
276+
277+ rtap_vendor->rtap.mcs_present = IEEE80211_RADIOTAP_MCS_HAVE_MCS;
278+ rtap_vendor->rtap.mcs_flags = 0;
279+ rtap_vendor->rtap.mcs_index = wil_rxdesc_mcs(d);
280+
281+ if (rtap_include_phy_info) {
282+ rtap_vendor->rtap.rthdr.it_present |= cpu_to_le32(1 <<
283+ IEEE80211_RADIOTAP_VENDOR_NAMESPACE);
284+ /* OUI for Wilocity 04:ce:14 */
285+ rtap_vendor->vendor_oui[0] = 0x04;
286+ rtap_vendor->vendor_oui[1] = 0xce;
287+ rtap_vendor->vendor_oui[2] = 0x14;
288+ rtap_vendor->vendor_ns = 1;
289+ /* Rx descriptor + PHY data */
290+ rtap_vendor->vendor_skip = cpu_to_le16(sizeof(*d) +
291+ phy_length);
292+ memcpy(rtap_vendor->vendor_data, (void *)d, sizeof(*d));
293+ memcpy(rtap_vendor->vendor_data + sizeof(*d), phy_data,
294+ phy_length);
295+ }
296+}
297+
298+/*
299+ * Fast swap in place between 2 registers
300+ */
301+static void wil_swap_u16(u16 *a, u16 *b)
302+{
303+ *a ^= *b;
304+ *b ^= *a;
305+ *a ^= *b;
306+}
307+
308+static void wil_swap_ethaddr(void *data)
309+{
310+ struct ethhdr *eth = data;
311+ u16 *s = (u16 *)eth->h_source;
312+ u16 *d = (u16 *)eth->h_dest;
313+
314+ wil_swap_u16(s++, d++);
315+ wil_swap_u16(s++, d++);
316+ wil_swap_u16(s, d);
317+}
318+
319+/**
320+ * reap 1 frame from @swhead
321+ *
322+ * Safe to call from IRQ
323+ */
324+static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
325+ struct vring *vring)
326+{
327+ struct device *dev = wil_to_dev(wil);
328+ struct net_device *ndev = wil_to_ndev(wil);
329+ volatile struct vring_rx_desc *d;
330+ struct sk_buff *skb;
331+ dma_addr_t pa;
332+ unsigned int sz = RX_BUF_LEN;
333+ u8 ftype;
334+ u8 ds_bits;
335+
336+ if (wil_vring_is_empty(vring))
337+ return NULL;
338+
339+ d = &(vring->va[vring->swhead].rx);
340+ if (!(d->dma.status & RX_DMA_STATUS_DU)) {
341+ /* it is not error, we just reached end of Rx done area */
342+ return NULL;
343+ }
344+
345+ pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32);
346+ skb = vring->ctx[vring->swhead];
347+ dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE);
348+ skb_trim(skb, d->dma.length);
349+
350+ wil->stats.last_mcs_rx = wil_rxdesc_mcs(d);
351+
352+ /* use radiotap header only if required */
353+ if (ndev->type == ARPHRD_IEEE80211_RADIOTAP)
354+ wil_rx_add_radiotap_header(wil, skb, d);
355+
356+ wil_dbg_TXRX(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length);
357+ wil_hex_dump_TXRX("Rx ", DUMP_PREFIX_NONE, 32, 4,
358+ (const void *)d, sizeof(*d), false);
359+
360+ wil_vring_advance_head(vring, 1);
361+
362+ /* no extra checks if in sniffer mode */
363+ if (ndev->type != ARPHRD_ETHER)
364+ return skb;
365+ /*
366+ * Non-data frames may be delivered through Rx DMA channel (ex: BAR)
367+ * Driver should recognize it by frame type, that is found
368+ * in Rx descriptor. If type is not data, it is 802.11 frame as is
369+ */
370+ ftype = wil_rxdesc_ftype(d) << 2;
371+ if (ftype != IEEE80211_FTYPE_DATA) {
372+ wil_dbg_TXRX(wil, "Non-data frame ftype 0x%08x\n", ftype);
373+ /* TODO: process it */
374+ kfree_skb(skb);
375+ return NULL;
376+ }
377+
378+ if (skb->len < ETH_HLEN) {
379+ wil_err(wil, "Short frame, len = %d\n", skb->len);
380+ /* TODO: process it (i.e. BAR) */
381+ kfree_skb(skb);
382+ return NULL;
383+ }
384+
385+ ds_bits = wil_rxdesc_ds_bits(d);
386+ if (ds_bits == 1) {
387+ /*
388+ * HW bug - in ToDS mode, i.e. Rx on AP side,
389+ * addresses get swapped
390+ */
391+ wil_swap_ethaddr(skb->data);
392+ }
393+
394+ return skb;
395+}
396+
397+/**
398+ * allocate and fill up to @count buffers in rx ring
399+ * buffers posted at @swtail
400+ */
401+static int wil_rx_refill(struct wil6210_priv *wil, int count)
402+{
403+ struct net_device *ndev = wil_to_ndev(wil);
404+ struct vring *v = &wil->vring_rx;
405+ u32 next_tail;
406+ int rc = 0;
407+ int headroom = ndev->type == ARPHRD_IEEE80211_RADIOTAP ?
408+ WIL6210_RTAP_SIZE : 0;
409+
410+ for (; next_tail = wil_vring_next_tail(v),
411+ (next_tail != v->swhead) && (count-- > 0);
412+ v->swtail = next_tail) {
413+ rc = wil_vring_alloc_skb(wil, v, v->swtail, headroom);
414+ if (rc) {
415+ wil_err(wil, "Error %d in wil_rx_refill[%d]\n",
416+ rc, v->swtail);
417+ break;
418+ }
419+ }
420+ iowrite32(v->swtail, wil->csr + HOSTADDR(v->hwtail));
421+
422+ return rc;
423+}
424+
425+/*
426+ * Pass Rx packet to the netif. Update statistics.
427+ */
428+static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
429+{
430+ int rc;
431+ unsigned int len = skb->len;
432+
433+ if (in_interrupt())
434+ rc = netif_rx(skb);
435+ else
436+ rc = netif_rx_ni(skb);
437+
438+ if (likely(rc == NET_RX_SUCCESS)) {
439+ ndev->stats.rx_packets++;
440+ ndev->stats.rx_bytes += len;
441+
442+ } else {
443+ ndev->stats.rx_dropped++;
444+ }
445+}
446+
447+/**
448+ * Proceed all completed skb's from Rx VRING
449+ *
450+ * Safe to call from IRQ
451+ */
452+void wil_rx_handle(struct wil6210_priv *wil)
453+{
454+ struct net_device *ndev = wil_to_ndev(wil);
455+ struct vring *v = &wil->vring_rx;
456+ struct sk_buff *skb;
457+
458+ if (!v->va) {
459+ wil_err(wil, "Rx IRQ while Rx not yet initialized\n");
460+ return;
461+ }
462+ wil_dbg_TXRX(wil, "%s()\n", __func__);
463+ while (NULL != (skb = wil_vring_reap_rx(wil, v))) {
464+ wil_hex_dump_TXRX("Rx ", DUMP_PREFIX_OFFSET, 16, 1,
465+ skb->data, skb_headlen(skb), false);
466+
467+ skb_orphan(skb);
468+
469+ if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) {
470+ skb->dev = ndev;
471+ skb_reset_mac_header(skb);
472+ skb->ip_summed = CHECKSUM_UNNECESSARY;
473+ skb->pkt_type = PACKET_OTHERHOST;
474+ skb->protocol = htons(ETH_P_802_2);
475+
476+ } else {
477+ skb->protocol = eth_type_trans(skb, ndev);
478+ }
479+
480+ wil_netif_rx_any(skb, ndev);
481+ }
482+ wil_rx_refill(wil, v->size);
483+}
484+
485+int wil_rx_init(struct wil6210_priv *wil)
486+{
487+ struct net_device *ndev = wil_to_ndev(wil);
488+ struct wireless_dev *wdev = wil->wdev;
489+ struct vring *vring = &wil->vring_rx;
490+ int rc;
491+ struct wmi_cfg_rx_chain_cmd cmd = {
492+ .action = WMI_RX_CHAIN_ADD,
493+ .rx_sw_ring = {
494+ .max_mpdu_size = cpu_to_le16(RX_BUF_LEN),
495+ },
496+ .mid = 0, /* TODO - what is it? */
497+ .decap_trans_type = WMI_DECAP_TYPE_802_3,
498+ };
499+ struct {
500+ struct wil6210_mbox_hdr_wmi wmi;
501+ struct wmi_cfg_rx_chain_done_event evt;
502+ } __packed evt;
503+
504+ vring->size = WIL6210_RX_RING_SIZE;
505+ rc = wil_vring_alloc(wil, vring);
506+ if (rc)
507+ return rc;
508+
509+ cmd.rx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa);
510+ cmd.rx_sw_ring.ring_size = cpu_to_le16(vring->size);
511+ if (wdev->iftype == NL80211_IFTYPE_MONITOR) {
512+ struct ieee80211_channel *ch = wdev->preset_chandef.chan;
513+
514+ cmd.sniffer_cfg.mode = cpu_to_le32(WMI_SNIFFER_ON);
515+ if (ch)
516+ cmd.sniffer_cfg.channel = ch->hw_value - 1;
517+ cmd.sniffer_cfg.phy_info_mode =
518+ cpu_to_le32(ndev->type == ARPHRD_IEEE80211_RADIOTAP);
519+ cmd.sniffer_cfg.phy_support =
520+ cpu_to_le32((wil->monitor_flags & MONITOR_FLAG_CONTROL)
521+ ? WMI_SNIFFER_CP : WMI_SNIFFER_DP);
522+ }
523+ /* typical time for secure PCP is 840ms */
524+ rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd),
525+ WMI_CFG_RX_CHAIN_DONE_EVENTID, &evt, sizeof(evt), 2000);
526+ if (rc)
527+ goto err_free;
528+
529+ vring->hwtail = le32_to_cpu(evt.evt.rx_ring_tail_ptr);
530+
531+ wil_dbg(wil, "Rx init: status %d tail 0x%08x\n",
532+ le32_to_cpu(evt.evt.status), vring->hwtail);
533+
534+ rc = wil_rx_refill(wil, vring->size);
535+ if (rc)
536+ goto err_free;
537+
538+ return 0;
539+ err_free:
540+ wil_vring_free(wil, vring, 0);
541+
542+ return rc;
543+}
544+
545+void wil_rx_fini(struct wil6210_priv *wil)
546+{
547+ struct vring *vring = &wil->vring_rx;
548+
549+ if (vring->va) {
550+ int rc;
551+ struct wmi_cfg_rx_chain_cmd cmd = {
552+ .action = cpu_to_le32(WMI_RX_CHAIN_DEL),
553+ .rx_sw_ring = {
554+ .max_mpdu_size = cpu_to_le16(RX_BUF_LEN),
555+ },
556+ };
557+ struct {
558+ struct wil6210_mbox_hdr_wmi wmi;
559+ struct wmi_cfg_rx_chain_done_event cfg;
560+ } __packed wmi_rx_cfg_reply;
561+
562+ rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd),
563+ WMI_CFG_RX_CHAIN_DONE_EVENTID,
564+ &wmi_rx_cfg_reply, sizeof(wmi_rx_cfg_reply),
565+ 100);
566+ wil_vring_free(wil, vring, 0);
567+ }
568+}
569+
570+int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
571+ int cid, int tid)
572+{
573+ int rc;
574+ struct wmi_vring_cfg_cmd cmd = {
575+ .action = cpu_to_le32(WMI_VRING_CMD_ADD),
576+ .vring_cfg = {
577+ .tx_sw_ring = {
578+ .max_mpdu_size = cpu_to_le16(TX_BUF_LEN),
579+ },
580+ .ringid = id,
581+ .cidxtid = (cid & 0xf) | ((tid & 0xf) << 4),
582+ .encap_trans_type = WMI_VRING_ENC_TYPE_802_3,
583+ .mac_ctrl = 0,
584+ .to_resolution = 0,
585+ .agg_max_wsize = 16,
586+ .schd_params = {
587+ .priority = cpu_to_le16(0),
588+ .timeslot_us = cpu_to_le16(0xfff),
589+ },
590+ },
591+ };
592+ struct {
593+ struct wil6210_mbox_hdr_wmi wmi;
594+ struct wmi_vring_cfg_done_event cmd;
595+ } __packed reply;
596+ struct vring *vring = &wil->vring_tx[id];
597+
598+ if (vring->va) {
599+ wil_err(wil, "Tx ring [%d] already allocated\n", id);
600+ rc = -EINVAL;
601+ goto out;
602+ }
603+
604+ vring->size = size;
605+ rc = wil_vring_alloc(wil, vring);
606+ if (rc)
607+ goto out;
608+
609+ cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa);
610+ cmd.vring_cfg.tx_sw_ring.ring_size = cpu_to_le16(vring->size);
611+
612+ rc = wmi_call(wil, WMI_VRING_CFG_CMDID, &cmd, sizeof(cmd),
613+ WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100);
614+ if (rc)
615+ goto out_free;
616+
617+ if (reply.cmd.status != WMI_VRING_CFG_SUCCESS) {
618+ wil_err(wil, "Tx config failed, status 0x%02x\n",
619+ reply.cmd.status);
620+ goto out_free;
621+ }
622+ vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr);
623+
624+ return 0;
625+ out_free:
626+ wil_vring_free(wil, vring, 1);
627+ out:
628+
629+ return rc;
630+}
631+
632+void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
633+{
634+ struct vring *vring = &wil->vring_tx[id];
635+
636+ if (!vring->va)
637+ return;
638+
639+ wil_vring_free(wil, vring, 1);
640+}
641+
642+static struct vring *wil_find_tx_vring(struct wil6210_priv *wil,
643+ struct sk_buff *skb)
644+{
645+ struct vring *v = &wil->vring_tx[0];
646+
647+ if (v->va)
648+ return v;
649+
650+ return NULL;
651+}
652+
653+static int wil_tx_desc_map(volatile struct vring_tx_desc *d,
654+ dma_addr_t pa, u32 len)
655+{
656+ d->dma.addr_low = lower_32_bits(pa);
657+ d->dma.addr_high = (u16)upper_32_bits(pa);
658+ d->dma.ip_length = 0;
659+ /* 0..6: mac_length; 7:ip_version 0-IP6 1-IP4*/
660+ d->dma.b11 = 0/*14 | BIT(7)*/;
661+ d->dma.error = 0;
662+ d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */
663+ d->dma.length = len;
664+ d->dma.d0 = 0;
665+ d->mac.d[0] = 0;
666+ d->mac.d[1] = 0;
667+ d->mac.d[2] = 0;
668+ d->mac.ucode_cmd = 0;
669+ /* use dst index 0 */
670+ d->mac.d[1] |= BIT(MAC_CFG_DESC_TX_1_DST_INDEX_EN_POS) |
671+ (0 << MAC_CFG_DESC_TX_1_DST_INDEX_POS);
672+ /* translation type: 0 - bypass; 1 - 802.3; 2 - native wifi */
673+ d->mac.d[2] = BIT(MAC_CFG_DESC_TX_2_SNAP_HDR_INSERTION_EN_POS) |
674+ (1 << MAC_CFG_DESC_TX_2_L2_TRANSLATION_TYPE_POS);
675+
676+ return 0;
677+}
678+
679+static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
680+ struct sk_buff *skb)
681+{
682+ struct device *dev = wil_to_dev(wil);
683+ volatile struct vring_tx_desc *d;
684+ u32 swhead = vring->swhead;
685+ int avail = wil_vring_avail_tx(vring);
686+ int nr_frags = skb_shinfo(skb)->nr_frags;
687+ uint f;
688+ int vring_index = vring - wil->vring_tx;
689+ uint i = swhead;
690+ dma_addr_t pa;
691+
692+ wil_dbg_TXRX(wil, "%s()\n", __func__);
693+
694+ if (avail < vring->size/8)
695+ netif_tx_stop_all_queues(wil_to_ndev(wil));
696+ if (avail < 1 + nr_frags) {
697+ wil_err(wil, "Tx ring full. No space for %d fragments\n",
698+ 1 + nr_frags);
699+ return -ENOMEM;
700+ }
701+ d = &(vring->va[i].tx);
702+
703+ /* FIXME FW can accept only unicast frames for the peer */
704+ memcpy(skb->data, wil->dst_addr[vring_index], ETH_ALEN);
705+
706+ pa = dma_map_single(dev, skb->data,
707+ skb_headlen(skb), DMA_TO_DEVICE);
708+
709+ wil_dbg_TXRX(wil, "Tx skb %d bytes %p -> %#08llx\n", skb_headlen(skb),
710+ skb->data, (unsigned long long)pa);
711+ wil_hex_dump_TXRX("Tx ", DUMP_PREFIX_OFFSET, 16, 1,
712+ skb->data, skb_headlen(skb), false);
713+
714+ if (unlikely(dma_mapping_error(dev, pa)))
715+ return -EINVAL;
716+ /* 1-st segment */
717+ wil_tx_desc_map(d, pa, skb_headlen(skb));
718+ d->mac.d[2] |= ((nr_frags + 1) <<
719+ MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS);
720+ /* middle segments */
721+ for (f = 0; f < nr_frags; f++) {
722+ const struct skb_frag_struct *frag =
723+ &skb_shinfo(skb)->frags[f];
724+ int len = skb_frag_size(frag);
725+ i = (swhead + f + 1) % vring->size;
726+ d = &(vring->va[i].tx);
727+ pa = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag),
728+ DMA_TO_DEVICE);
729+ if (unlikely(dma_mapping_error(dev, pa)))
730+ goto dma_error;
731+ wil_tx_desc_map(d, pa, len);
732+ vring->ctx[i] = NULL;
733+ }
734+ /* for the last seg only */
735+ d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_EOP_POS);
736+ d->dma.d0 |= BIT(9); /* BUG: undocumented bit */
737+ d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS);
738+ d->dma.d0 |= (vring_index << DMA_CFG_DESC_TX_0_QID_POS);
739+
740+ wil_hex_dump_TXRX("Tx ", DUMP_PREFIX_NONE, 32, 4,
741+ (const void *)d, sizeof(*d), false);
742+
743+ /* advance swhead */
744+ wil_vring_advance_head(vring, nr_frags + 1);
745+ wil_dbg_TXRX(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead);
746+ iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail));
747+ /* hold reference to skb
748+ * to prevent skb release before accounting
749+ * in case of immediate "tx done"
750+ */
751+ vring->ctx[i] = skb_get(skb);
752+
753+ return 0;
754+ dma_error:
755+ /* unmap what we have mapped */
756+ /* Note: increment @f to operate with positive index */
757+ for (f++; f > 0; f--) {
758+ i = (swhead + f) % vring->size;
759+ d = &(vring->va[i].tx);
760+ d->dma.status = TX_DMA_STATUS_DU;
761+ pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32);
762+ if (vring->ctx[i])
763+ dma_unmap_single(dev, pa, d->dma.length, DMA_TO_DEVICE);
764+ else
765+ dma_unmap_page(dev, pa, d->dma.length, DMA_TO_DEVICE);
766+ }
767+
768+ return -EINVAL;
769+}
770+
771+
772+netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
773+{
774+ struct wil6210_priv *wil = ndev_to_wil(ndev);
775+ struct vring *vring;
776+ int rc;
777+
778+ wil_dbg_TXRX(wil, "%s()\n", __func__);
779+ if (!test_bit(wil_status_fwready, &wil->status)) {
780+ wil_err(wil, "FW not ready\n");
781+ goto drop;
782+ }
783+ if (!test_bit(wil_status_fwconnected, &wil->status)) {
784+ wil_err(wil, "FW not connected\n");
785+ goto drop;
786+ }
787+ if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) {
788+ wil_err(wil, "Xmit in monitor mode not supported\n");
789+ goto drop;
790+ }
791+ if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
792+ rc = wmi_tx_eapol(wil, skb);
793+ } else {
794+ /* find vring */
795+ vring = wil_find_tx_vring(wil, skb);
796+ if (!vring) {
797+ wil_err(wil, "No Tx VRING available\n");
798+ goto drop;
799+ }
800+ /* set up vring entry */
801+ rc = wil_tx_vring(wil, vring, skb);
802+ }
803+ switch (rc) {
804+ case 0:
805+ ndev->stats.tx_packets++;
806+ ndev->stats.tx_bytes += skb->len;
807+ dev_kfree_skb_any(skb);
808+ return NETDEV_TX_OK;
809+ case -ENOMEM:
810+ return NETDEV_TX_BUSY;
811+ default:
812+ ; /* goto drop; */
813+ break;
814+ }
815+ drop:
816+ netif_tx_stop_all_queues(ndev);
817+ ndev->stats.tx_dropped++;
818+ dev_kfree_skb_any(skb);
819+
820+ return NET_XMIT_DROP;
821+}
822+
823+/**
824+ * Clean up transmitted skb's from the Tx VRING
825+ *
826+ * Safe to call from IRQ
827+ */
828+void wil_tx_complete(struct wil6210_priv *wil, int ringid)
829+{
830+ struct device *dev = wil_to_dev(wil);
831+ struct vring *vring = &wil->vring_tx[ringid];
832+
833+ if (!vring->va) {
834+ wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid);
835+ return;
836+ }
837+
838+ wil_dbg_TXRX(wil, "%s(%d)\n", __func__, ringid);
839+
840+ while (!wil_vring_is_empty(vring)) {
841+ volatile struct vring_tx_desc *d = &vring->va[vring->swtail].tx;
842+ dma_addr_t pa;
843+ struct sk_buff *skb;
844+ if (!(d->dma.status & TX_DMA_STATUS_DU))
845+ break;
846+
847+ wil_dbg_TXRX(wil,
848+ "Tx[%3d] : %d bytes, status 0x%02x err 0x%02x\n",
849+ vring->swtail, d->dma.length, d->dma.status,
850+ d->dma.error);
851+ wil_hex_dump_TXRX("TxC ", DUMP_PREFIX_NONE, 32, 4,
852+ (const void *)d, sizeof(*d), false);
853+
854+ pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32);
855+ skb = vring->ctx[vring->swtail];
856+ if (skb) {
857+ dma_unmap_single(dev, pa, d->dma.length, DMA_TO_DEVICE);
858+ dev_kfree_skb_any(skb);
859+ vring->ctx[vring->swtail] = NULL;
860+ } else {
861+ dma_unmap_page(dev, pa, d->dma.length, DMA_TO_DEVICE);
862+ }
863+ d->dma.addr_low = 0;
864+ d->dma.addr_high = 0;
865+ d->dma.length = 0;
866+ d->dma.status = TX_DMA_STATUS_DU;
867+ vring->swtail = wil_vring_next_tail(vring);
868+ }
869+ if (wil_vring_avail_tx(vring) > vring->size/4)
870+ netif_tx_wake_all_queues(wil_to_ndev(wil));
871+}
drivers/net/wireless/ath/wil6210/txrx.h+362−0
@@ -0,0 +1,362 @@
1+/*
2+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
3+ *
4+ * Permission to use, copy, modify, and/or distribute this software for any
5+ * purpose with or without fee is hereby granted, provided that the above
6+ * copyright notice and this permission notice appear in all copies.
7+ *
8+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+ */
16+
17+#ifndef WIL6210_TXRX_H
18+#define WIL6210_TXRX_H
19+
20+#define BUF_SW_OWNED (1)
21+#define BUF_HW_OWNED (0)
22+
23+/* size of max. Rx packet */
24+#define RX_BUF_LEN (2048)
25+#define TX_BUF_LEN (2048)
26+/* how many bytes to reserve for rtap header? */
27+#define WIL6210_RTAP_SIZE (128)
28+
29+/* Tx/Rx path */
30+/*
31+ * Tx descriptor - MAC part
32+ * [dword 0]
33+ * bit 0.. 9 : lifetime_expiry_value:10
34+ * bit 10 : interrup_en:1
35+ * bit 11 : status_en:1
36+ * bit 12..13 : txss_override:2
37+ * bit 14 : timestamp_insertion:1
38+ * bit 15 : duration_preserve:1
39+ * bit 16..21 : reserved0:6
40+ * bit 22..26 : mcs_index:5
41+ * bit 27 : mcs_en:1
42+ * bit 28..29 : reserved1:2
43+ * bit 30 : reserved2:1
44+ * bit 31 : sn_preserved:1
45+ * [dword 1]
46+ * bit 0.. 3 : pkt_mode:4
47+ * bit 4 : pkt_mode_en:1
48+ * bit 5.. 7 : reserved0:3
49+ * bit 8..13 : reserved1:6
50+ * bit 14 : reserved2:1
51+ * bit 15 : ack_policy_en:1
52+ * bit 16..19 : dst_index:4
53+ * bit 20 : dst_index_en:1
54+ * bit 21..22 : ack_policy:2
55+ * bit 23 : lifetime_en:1
56+ * bit 24..30 : max_retry:7
57+ * bit 31 : max_retry_en:1
58+ * [dword 2]
59+ * bit 0.. 7 : num_of_descriptors:8
60+ * bit 8..17 : reserved:10
61+ * bit 18..19 : l2_translation_type:2
62+ * bit 20 : snap_hdr_insertion_en:1
63+ * bit 21 : vlan_removal_en:1
64+ * bit 22..31 : reserved0:10
65+ * [dword 3]
66+ * bit 0.. 31: ucode_cmd:32
67+ */
68+struct vring_tx_mac {
69+ u32 d[3];
70+ u32 ucode_cmd;
71+} __packed;
72+
73+/* TX MAC Dword 0 */
74+#define MAC_CFG_DESC_TX_0_LIFETIME_EXPIRY_VALUE_POS 0
75+#define MAC_CFG_DESC_TX_0_LIFETIME_EXPIRY_VALUE_LEN 10
76+#define MAC_CFG_DESC_TX_0_LIFETIME_EXPIRY_VALUE_MSK 0x3FF
77+
78+#define MAC_CFG_DESC_TX_0_INTERRUP_EN_POS 10
79+#define MAC_CFG_DESC_TX_0_INTERRUP_EN_LEN 1
80+#define MAC_CFG_DESC_TX_0_INTERRUP_EN_MSK 0x400
81+
82+#define MAC_CFG_DESC_TX_0_STATUS_EN_POS 11
83+#define MAC_CFG_DESC_TX_0_STATUS_EN_LEN 1
84+#define MAC_CFG_DESC_TX_0_STATUS_EN_MSK 0x800
85+
86+#define MAC_CFG_DESC_TX_0_TXSS_OVERRIDE_POS 12
87+#define MAC_CFG_DESC_TX_0_TXSS_OVERRIDE_LEN 2
88+#define MAC_CFG_DESC_TX_0_TXSS_OVERRIDE_MSK 0x3000
89+
90+#define MAC_CFG_DESC_TX_0_TIMESTAMP_INSERTION_POS 14
91+#define MAC_CFG_DESC_TX_0_TIMESTAMP_INSERTION_LEN 1
92+#define MAC_CFG_DESC_TX_0_TIMESTAMP_INSERTION_MSK 0x4000
93+
94+#define MAC_CFG_DESC_TX_0_DURATION_PRESERVE_POS 15
95+#define MAC_CFG_DESC_TX_0_DURATION_PRESERVE_LEN 1
96+#define MAC_CFG_DESC_TX_0_DURATION_PRESERVE_MSK 0x8000
97+
98+#define MAC_CFG_DESC_TX_0_MCS_INDEX_POS 22
99+#define MAC_CFG_DESC_TX_0_MCS_INDEX_LEN 5
100+#define MAC_CFG_DESC_TX_0_MCS_INDEX_MSK 0x7C00000
101+
102+#define MAC_CFG_DESC_TX_0_MCS_EN_POS 27
103+#define MAC_CFG_DESC_TX_0_MCS_EN_LEN 1
104+#define MAC_CFG_DESC_TX_0_MCS_EN_MSK 0x8000000
105+
106+#define MAC_CFG_DESC_TX_0_SN_PRESERVED_POS 31
107+#define MAC_CFG_DESC_TX_0_SN_PRESERVED_LEN 1
108+#define MAC_CFG_DESC_TX_0_SN_PRESERVED_MSK 0x80000000
109+
110+/* TX MAC Dword 1 */
111+#define MAC_CFG_DESC_TX_1_PKT_MODE_POS 0
112+#define MAC_CFG_DESC_TX_1_PKT_MODE_LEN 4
113+#define MAC_CFG_DESC_TX_1_PKT_MODE_MSK 0xF
114+
115+#define MAC_CFG_DESC_TX_1_PKT_MODE_EN_POS 4
116+#define MAC_CFG_DESC_TX_1_PKT_MODE_EN_LEN 1
117+#define MAC_CFG_DESC_TX_1_PKT_MODE_EN_MSK 0x10
118+
119+#define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_POS 15
120+#define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_LEN 1
121+#define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_MSK 0x8000
122+
123+#define MAC_CFG_DESC_TX_1_DST_INDEX_POS 16
124+#define MAC_CFG_DESC_TX_1_DST_INDEX_LEN 4
125+#define MAC_CFG_DESC_TX_1_DST_INDEX_MSK 0xF0000
126+
127+#define MAC_CFG_DESC_TX_1_DST_INDEX_EN_POS 20
128+#define MAC_CFG_DESC_TX_1_DST_INDEX_EN_LEN 1
129+#define MAC_CFG_DESC_TX_1_DST_INDEX_EN_MSK 0x100000
130+
131+#define MAC_CFG_DESC_TX_1_ACK_POLICY_POS 21
132+#define MAC_CFG_DESC_TX_1_ACK_POLICY_LEN 2
133+#define MAC_CFG_DESC_TX_1_ACK_POLICY_MSK 0x600000
134+
135+#define MAC_CFG_DESC_TX_1_LIFETIME_EN_POS 23
136+#define MAC_CFG_DESC_TX_1_LIFETIME_EN_LEN 1
137+#define MAC_CFG_DESC_TX_1_LIFETIME_EN_MSK 0x800000
138+
139+#define MAC_CFG_DESC_TX_1_MAX_RETRY_POS 24
140+#define MAC_CFG_DESC_TX_1_MAX_RETRY_LEN 7
141+#define MAC_CFG_DESC_TX_1_MAX_RETRY_MSK 0x7F000000
142+
143+#define MAC_CFG_DESC_TX_1_MAX_RETRY_EN_POS 31
144+#define MAC_CFG_DESC_TX_1_MAX_RETRY_EN_LEN 1
145+#define MAC_CFG_DESC_TX_1_MAX_RETRY_EN_MSK 0x80000000
146+
147+/* TX MAC Dword 2 */
148+#define MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS 0
149+#define MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_LEN 8
150+#define MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_MSK 0xFF
151+
152+#define MAC_CFG_DESC_TX_2_RESERVED_POS 8
153+#define MAC_CFG_DESC_TX_2_RESERVED_LEN 10
154+#define MAC_CFG_DESC_TX_2_RESERVED_MSK 0x3FF00
155+
156+#define MAC_CFG_DESC_TX_2_L2_TRANSLATION_TYPE_POS 18
157+#define MAC_CFG_DESC_TX_2_L2_TRANSLATION_TYPE_LEN 2
158+#define MAC_CFG_DESC_TX_2_L2_TRANSLATION_TYPE_MSK 0xC0000
159+
160+#define MAC_CFG_DESC_TX_2_SNAP_HDR_INSERTION_EN_POS 20
161+#define MAC_CFG_DESC_TX_2_SNAP_HDR_INSERTION_EN_LEN 1
162+#define MAC_CFG_DESC_TX_2_SNAP_HDR_INSERTION_EN_MSK 0x100000
163+
164+#define MAC_CFG_DESC_TX_2_VLAN_REMOVAL_EN_POS 21
165+#define MAC_CFG_DESC_TX_2_VLAN_REMOVAL_EN_LEN 1
166+#define MAC_CFG_DESC_TX_2_VLAN_REMOVAL_EN_MSK 0x200000
167+
168+/* TX MAC Dword 3 */
169+#define MAC_CFG_DESC_TX_3_UCODE_CMD_POS 0
170+#define MAC_CFG_DESC_TX_3_UCODE_CMD_LEN 32
171+#define MAC_CFG_DESC_TX_3_UCODE_CMD_MSK 0xFFFFFFFF
172+
173+/* TX DMA Dword 0 */
174+#define DMA_CFG_DESC_TX_0_L4_LENGTH_POS 0
175+#define DMA_CFG_DESC_TX_0_L4_LENGTH_LEN 8
176+#define DMA_CFG_DESC_TX_0_L4_LENGTH_MSK 0xFF
177+
178+#define DMA_CFG_DESC_TX_0_CMD_EOP_POS 8
179+#define DMA_CFG_DESC_TX_0_CMD_EOP_LEN 1
180+#define DMA_CFG_DESC_TX_0_CMD_EOP_MSK 0x100
181+
182+#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS 10
183+#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_LEN 1
184+#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_MSK 0x400
185+
186+#define DMA_CFG_DESC_TX_0_SEGMENT_BUF_DETAILS_POS 11
187+#define DMA_CFG_DESC_TX_0_SEGMENT_BUF_DETAILS_LEN 2
188+#define DMA_CFG_DESC_TX_0_SEGMENT_BUF_DETAILS_MSK 0x1800
189+
190+#define DMA_CFG_DESC_TX_0_TCP_SEG_EN_POS 13
191+#define DMA_CFG_DESC_TX_0_TCP_SEG_EN_LEN 1
192+#define DMA_CFG_DESC_TX_0_TCP_SEG_EN_MSK 0x2000
193+
194+#define DMA_CFG_DESC_TX_0_IPV4_CHECKSUM_EN_POS 14
195+#define DMA_CFG_DESC_TX_0_IPV4_CHECKSUM_EN_LEN 1
196+#define DMA_CFG_DESC_TX_0_IPV4_CHECKSUM_EN_MSK 0x4000
197+
198+#define DMA_CFG_DESC_TX_0_TCP_UDP_CHECKSUM_EN_POS 15
199+#define DMA_CFG_DESC_TX_0_TCP_UDP_CHECKSUM_EN_LEN 1
200+#define DMA_CFG_DESC_TX_0_TCP_UDP_CHECKSUM_EN_MSK 0x8000
201+
202+#define DMA_CFG_DESC_TX_0_QID_POS 16
203+#define DMA_CFG_DESC_TX_0_QID_LEN 5
204+#define DMA_CFG_DESC_TX_0_QID_MSK 0x1F0000
205+
206+#define DMA_CFG_DESC_TX_0_PSEUDO_HEADER_CALC_EN_POS 21
207+#define DMA_CFG_DESC_TX_0_PSEUDO_HEADER_CALC_EN_LEN 1
208+#define DMA_CFG_DESC_TX_0_PSEUDO_HEADER_CALC_EN_MSK 0x200000
209+
210+#define DMA_CFG_DESC_TX_0_L4_TYPE_POS 30
211+#define DMA_CFG_DESC_TX_0_L4_TYPE_LEN 2
212+#define DMA_CFG_DESC_TX_0_L4_TYPE_MSK 0xC0000000
213+
214+
215+#define TX_DMA_STATUS_DU BIT(0)
216+
217+struct vring_tx_dma {
218+ u32 d0;
219+ u32 addr_low;
220+ u16 addr_high;
221+ u8 ip_length;
222+ u8 b11; /* 0..6: mac_length; 7:ip_version */
223+ u8 error; /* 0..2: err; 3..7: reserved; */
224+ u8 status; /* 0: used; 1..7; reserved */
225+ u16 length;
226+} __packed;
227+
228+/*
229+ * Rx descriptor - MAC part
230+ * [dword 0]
231+ * bit 0.. 3 : tid:4 The QoS (b3-0) TID Field
232+ * bit 4.. 6 : connection_id:3 :The Source index that was found during
233+ * Parsing the TA. This field is used to define the source of the packet
234+ * bit 7 : reserved:1
235+ * bit 8.. 9 : mac_id:2 : The MAC virtual Ring number (always zero)
236+ * bit 10..11 : frame_type:2 : The FC Control (b3-2) - MPDU Type
237+ * (management, data, control and extension)
238+ * bit 12..15 : frame_subtype:4 : The FC Control (b7-4) - Frame Subtype
239+ * bit 16..27 : seq_number:12 The received Sequence number field
240+ * bit 28..31 : extended:4 extended subtype
241+ * [dword 1]
242+ * bit 0.. 3 : reserved
243+ * bit 4.. 5 : key_id:2
244+ * bit 6 : decrypt_bypass:1
245+ * bit 7 : security:1
246+ * bit 8.. 9 : ds_bits:2
247+ * bit 10 : a_msdu_present:1 from qos header
248+ * bit 11 : a_msdu_type:1 from qos header
249+ * bit 12 : a_mpdu:1 part of AMPDU aggregation
250+ * bit 13 : broadcast:1
251+ * bit 14 : mutlicast:1
252+ * bit 15 : reserved:1
253+ * bit 16..20 : rx_mac_qid:5 The Queue Identifier that the packet
254+ * is received from
255+ * bit 21..24 : mcs:4
256+ * bit 25..28 : mic_icr:4
257+ * bit 29..31 : reserved:3
258+ * [dword 2]
259+ * bit 0.. 2 : time_slot:3 The timeslot that the MPDU is received
260+ * bit 3 : fc_protocol_ver:1 The FC Control (b0) - Protocol Version
261+ * bit 4 : fc_order:1 The FC Control (b15) -Order
262+ * bit 5.. 7 : qos_ack_policy:3 The QoS (b6-5) ack policy Field
263+ * bit 8 : esop:1 The QoS (b4) ESOP field
264+ * bit 9 : qos_rdg_more_ppdu:1 The QoS (b9) RDG field
265+ * bit 10..14 : qos_reserved:5 The QoS (b14-10) Reserved field
266+ * bit 15 : qos_ac_constraint:1
267+ * bit 16..31 : pn_15_0:16 low 2 bytes of PN
268+ * [dword 3]
269+ * bit 0..31 : pn_47_16:32 high 4 bytes of PN
270+ */
271+struct vring_rx_mac {
272+ u32 d0;
273+ u32 d1;
274+ u16 w4;
275+ u16 pn_15_0;
276+ u32 pn_47_16;
277+} __packed;
278+
279+/*
280+ * Rx descriptor - DMA part
281+ * [dword 0]
282+ * bit 0.. 7 : l4_length:8 layer 4 length
283+ * bit 8.. 9 : reserved:2
284+ * bit 10 : cmd_dma_it:1
285+ * bit 11..15 : reserved:5
286+ * bit 16..29 : phy_info_length:14
287+ * bit 30..31 : l4_type:2 valid if the L4I bit is set in the status field
288+ * [dword 1]
289+ * bit 0..31 : addr_low:32 The payload buffer low address
290+ * [dword 2]
291+ * bit 0..15 : addr_high:16 The payload buffer high address
292+ * bit 16..23 : ip_length:8
293+ * bit 24..30 : mac_length:7
294+ * bit 31 : ip_version:1
295+ * [dword 3]
296+ * [byte 12] error
297+ * [byte 13] status
298+ * bit 0 : du:1
299+ * bit 1 : eop:1
300+ * bit 2 : error:1
301+ * bit 3 : mi:1
302+ * bit 4 : l3_identified:1
303+ * bit 5 : l4_identified:1
304+ * bit 6 : phy_info_included:1
305+ * bit 7 : reserved:1
306+ * [word 7] length
307+ *
308+ */
309+
310+#define RX_DMA_D0_CMD_DMA_IT BIT(10)
311+
312+#define RX_DMA_STATUS_DU BIT(0)
313+#define RX_DMA_STATUS_ERROR BIT(2)
314+#define RX_DMA_STATUS_PHY_INFO BIT(6)
315+
316+struct vring_rx_dma {
317+ u32 d0;
318+ u32 addr_low;
319+ u16 addr_high;
320+ u8 ip_length;
321+ u8 b11;
322+ u8 error;
323+ u8 status;
324+ u16 length;
325+} __packed;
326+
327+struct vring_tx_desc {
328+ struct vring_tx_mac mac;
329+ struct vring_tx_dma dma;
330+} __packed;
331+
332+struct vring_rx_desc {
333+ struct vring_rx_mac mac;
334+ struct vring_rx_dma dma;
335+} __packed;
336+
337+union vring_desc {
338+ struct vring_tx_desc tx;
339+ struct vring_rx_desc rx;
340+} __packed;
341+
342+static inline int wil_rxdesc_phy_length(volatile struct vring_rx_desc *d)
343+{
344+ return WIL_GET_BITS(d->dma.d0, 16, 29);
345+}
346+
347+static inline int wil_rxdesc_mcs(volatile struct vring_rx_desc *d)
348+{
349+ return WIL_GET_BITS(d->mac.d1, 21, 24);
350+}
351+
352+static inline int wil_rxdesc_ds_bits(volatile struct vring_rx_desc *d)
353+{
354+ return WIL_GET_BITS(d->mac.d1, 8, 9);
355+}
356+
357+static inline int wil_rxdesc_ftype(volatile struct vring_rx_desc *d)
358+{
359+ return WIL_GET_BITS(d->mac.d0, 10, 11);
360+}
361+
362+#endif /* WIL6210_TXRX_H */
drivers/net/wireless/ath/wil6210/wil6210.h+363−0
@@ -0,0 +1,363 @@
1+/*
2+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
3+ *
4+ * Permission to use, copy, modify, and/or distribute this software for any
5+ * purpose with or without fee is hereby granted, provided that the above
6+ * copyright notice and this permission notice appear in all copies.
7+ *
8+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+ */
16+
17+#ifndef __WIL6210_H__
18+#define __WIL6210_H__
19+
20+#include <linux/netdevice.h>
21+#include <linux/wireless.h>
22+#include <net/cfg80211.h>
23+
24+#include "dbg_hexdump.h"
25+
26+#define WIL_NAME "wil6210"
27+
28+/**
29+ * extract bits [@b0:@b1] (inclusive) from the value @x
30+ * it should be @b0 <= @b1, or result is incorrect
31+ */
32+static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
33+{
34+ return (x >> b0) & ((1 << (b1 - b0 + 1)) - 1);
35+}
36+
37+#define WIL6210_MEM_SIZE (2*1024*1024UL)
38+
39+#define WIL6210_TX_QUEUES (4)
40+
41+#define WIL6210_RX_RING_SIZE (128)
42+#define WIL6210_TX_RING_SIZE (128)
43+#define WIL6210_MAX_TX_RINGS (24)
44+
45+/* Hardware definitions begin */
46+
47+/*
48+ * Mapping
49+ * RGF File | Host addr | FW addr
50+ * | |
51+ * user_rgf | 0x000000 | 0x880000
52+ * dma_rgf | 0x001000 | 0x881000
53+ * pcie_rgf | 0x002000 | 0x882000
54+ * | |
55+ */
56+
57+/* Where various structures placed in host address space */
58+#define WIL6210_FW_HOST_OFF (0x880000UL)
59+
60+#define HOSTADDR(fwaddr) (fwaddr - WIL6210_FW_HOST_OFF)
61+
62+/*
63+ * Interrupt control registers block
64+ *
65+ * each interrupt controlled by the same bit in all registers
66+ */
67+struct RGF_ICR {
68+ u32 ICC; /* Cause Control, RW: 0 - W1C, 1 - COR */
69+ u32 ICR; /* Cause, W1C/COR depending on ICC */
70+ u32 ICM; /* Cause masked (ICR & ~IMV), W1C/COR depending on ICC */
71+ u32 ICS; /* Cause Set, WO */
72+ u32 IMV; /* Mask, RW+S/C */
73+ u32 IMS; /* Mask Set, write 1 to set */
74+ u32 IMC; /* Mask Clear, write 1 to clear */
75+} __packed;
76+
77+/* registers - FW addresses */
78+#define RGF_USER_USER_SCRATCH_PAD (0x8802bc)
79+#define RGF_USER_USER_ICR (0x880b4c) /* struct RGF_ICR */
80+ #define BIT_USER_USER_ICR_SW_INT_2 BIT(18)
81+#define RGF_USER_CLKS_CTL_SW_RST_MASK_0 (0x880b14)
82+#define RGF_USER_MAC_CPU_0 (0x8801fc)
83+#define RGF_USER_USER_CPU_0 (0x8801e0)
84+#define RGF_USER_CLKS_CTL_SW_RST_VEC_0 (0x880b04)
85+#define RGF_USER_CLKS_CTL_SW_RST_VEC_1 (0x880b08)
86+#define RGF_USER_CLKS_CTL_SW_RST_VEC_2 (0x880b0c)
87+#define RGF_USER_CLKS_CTL_SW_RST_VEC_3 (0x880b10)
88+
89+#define RGF_DMA_PSEUDO_CAUSE (0x881c68)
90+#define RGF_DMA_PSEUDO_CAUSE_MASK_SW (0x881c6c)
91+#define RGF_DMA_PSEUDO_CAUSE_MASK_FW (0x881c70)
92+ #define BIT_DMA_PSEUDO_CAUSE_RX BIT(0)
93+ #define BIT_DMA_PSEUDO_CAUSE_TX BIT(1)
94+ #define BIT_DMA_PSEUDO_CAUSE_MISC BIT(2)
95+
96+#define RGF_DMA_EP_TX_ICR (0x881bb4) /* struct RGF_ICR */
97+ #define BIT_DMA_EP_TX_ICR_TX_DONE BIT(0)
98+ #define BIT_DMA_EP_TX_ICR_TX_DONE_N(n) BIT(n+1) /* n = [0..23] */
99+#define RGF_DMA_EP_RX_ICR (0x881bd0) /* struct RGF_ICR */
100+ #define BIT_DMA_EP_RX_ICR_RX_DONE BIT(0)
101+#define RGF_DMA_EP_MISC_ICR (0x881bec) /* struct RGF_ICR */
102+ #define BIT_DMA_EP_MISC_ICR_RX_HTRSH BIT(0)
103+ #define BIT_DMA_EP_MISC_ICR_TX_NO_ACT BIT(1)
104+ #define BIT_DMA_EP_MISC_ICR_FW_INT0 BIT(28)
105+ #define BIT_DMA_EP_MISC_ICR_FW_INT1 BIT(29)
106+
107+/* Interrupt moderation control */
108+#define RGF_DMA_ITR_CNT_TRSH (0x881c5c)
109+#define RGF_DMA_ITR_CNT_DATA (0x881c60)
110+#define RGF_DMA_ITR_CNT_CRL (0x881C64)
111+ #define BIT_DMA_ITR_CNT_CRL_EN BIT(0)
112+ #define BIT_DMA_ITR_CNT_CRL_EXT_TICK BIT(1)
113+ #define BIT_DMA_ITR_CNT_CRL_FOREVER BIT(2)
114+ #define BIT_DMA_ITR_CNT_CRL_CLR BIT(3)
115+ #define BIT_DMA_ITR_CNT_CRL_REACH_TRSH BIT(4)
116+
117+/* popular locations */
118+#define HOST_MBOX HOSTADDR(RGF_USER_USER_SCRATCH_PAD)
119+#define HOST_SW_INT (HOSTADDR(RGF_USER_USER_ICR) + \
120+ offsetof(struct RGF_ICR, ICS))
121+#define SW_INT_MBOX BIT_USER_USER_ICR_SW_INT_2
122+
123+/* ISR register bits */
124+#define ISR_MISC_FW_READY BIT_DMA_EP_MISC_ICR_FW_INT0
125+#define ISR_MISC_MBOX_EVT BIT_DMA_EP_MISC_ICR_FW_INT1
126+
127+/* Hardware definitions end */
128+
129+struct wil6210_mbox_ring {
130+ u32 base;
131+ u16 entry_size; /* max. size of mbox entry, incl. all headers */
132+ u16 size;
133+ u32 tail;
134+ u32 head;
135+} __packed;
136+
137+struct wil6210_mbox_ring_desc {
138+ __le32 sync;
139+ __le32 addr;
140+} __packed;
141+
142+/* at HOST_OFF_WIL6210_MBOX_CTL */
143+struct wil6210_mbox_ctl {
144+ struct wil6210_mbox_ring tx;
145+ struct wil6210_mbox_ring rx;
146+} __packed;
147+
148+struct wil6210_mbox_hdr {
149+ __le16 seq;
150+ __le16 len; /* payload, bytes after this header */
151+ __le16 type;
152+ u8 flags;
153+ u8 reserved;
154+} __packed;
155+
156+#define WIL_MBOX_HDR_TYPE_WMI (0)
157+
158+/* max. value for wil6210_mbox_hdr.len */
159+#define MAX_MBOXITEM_SIZE (240)
160+
161+struct wil6210_mbox_hdr_wmi {
162+ u8 reserved0[2];
163+ __le16 id;
164+ __le16 info1; /* bits [0..3] - device_id, rest - unused */
165+ u8 reserved1[2];
166+} __packed;
167+
168+struct pending_wmi_event {
169+ struct list_head list;
170+ struct {
171+ struct wil6210_mbox_hdr hdr;
172+ struct wil6210_mbox_hdr_wmi wmi;
173+ u8 data[0];
174+ } __packed event;
175+};
176+
177+union vring_desc;
178+
179+struct vring {
180+ dma_addr_t pa;
181+ volatile union vring_desc *va; /* vring_desc[size], WriteBack by DMA */
182+ u16 size; /* number of vring_desc elements */
183+ u32 swtail;
184+ u32 swhead;
185+ u32 hwtail; /* write here to inform hw */
186+ void **ctx; /* void *ctx[size] - software context */
187+};
188+
189+enum { /* for wil6210_priv.status */
190+ wil_status_fwready = 0,
191+ wil_status_fwconnected,
192+ wil_status_dontscan,
193+ wil_status_irqen, /* FIXME: interrupts enabled - for debug */
194+};
195+
196+struct pci_dev;
197+
198+struct wil6210_stats {
199+ u64 tsf;
200+ u32 snr;
201+ u16 last_mcs_rx;
202+ u16 bf_mcs; /* last BF, used for Tx */
203+ u16 my_rx_sector;
204+ u16 my_tx_sector;
205+ u16 peer_rx_sector;
206+ u16 peer_tx_sector;
207+};
208+
209+struct wil6210_priv {
210+ struct pci_dev *pdev;
211+ int n_msi;
212+ struct wireless_dev *wdev;
213+ void __iomem *csr;
214+ ulong status;
215+ /* profile */
216+ u32 monitor_flags;
217+ u32 secure_pcp; /* create secure PCP? */
218+ int sinfo_gen;
219+ /* cached ISR registers */
220+ u32 isr_misc;
221+ /* mailbox related */
222+ struct mutex wmi_mutex;
223+ struct wil6210_mbox_ctl mbox_ctl;
224+ struct completion wmi_ready;
225+ u16 wmi_seq;
226+ u16 reply_id; /**< wait for this WMI event */
227+ void *reply_buf;
228+ u16 reply_size;
229+ struct workqueue_struct *wmi_wq; /* for deferred calls */
230+ struct work_struct wmi_event_worker;
231+ struct workqueue_struct *wmi_wq_conn; /* for connect worker */
232+ struct work_struct wmi_connect_worker;
233+ struct work_struct disconnect_worker;
234+ struct timer_list connect_timer;
235+ int pending_connect_cid;
236+ struct list_head pending_wmi_ev;
237+ /*
238+ * protect pending_wmi_ev
239+ * - fill in IRQ from wil6210_irq_misc,
240+ * - consumed in thread by wmi_event_worker
241+ */
242+ spinlock_t wmi_ev_lock;
243+ /* DMA related */
244+ struct vring vring_rx;
245+ struct vring vring_tx[WIL6210_MAX_TX_RINGS];
246+ u8 dst_addr[WIL6210_MAX_TX_RINGS][ETH_ALEN];
247+ /* scan */
248+ struct cfg80211_scan_request *scan_request;
249+
250+ struct mutex mutex; /* for wil6210_priv access in wil_{up|down} */
251+ /* statistics */
252+ struct wil6210_stats stats;
253+ /* debugfs */
254+ struct dentry *debug;
255+ struct debugfs_blob_wrapper fw_code_blob;
256+ struct debugfs_blob_wrapper fw_data_blob;
257+ struct debugfs_blob_wrapper fw_peri_blob;
258+ struct debugfs_blob_wrapper uc_code_blob;
259+ struct debugfs_blob_wrapper uc_data_blob;
260+ struct debugfs_blob_wrapper rgf_blob;
261+};
262+
263+#define wil_to_wiphy(i) (i->wdev->wiphy)
264+#define wil_to_dev(i) (wiphy_dev(wil_to_wiphy(i)))
265+#define wiphy_to_wil(w) (struct wil6210_priv *)(wiphy_priv(w))
266+#define wil_to_wdev(i) (i->wdev)
267+#define wdev_to_wil(w) (struct wil6210_priv *)(wdev_priv(w))
268+#define wil_to_ndev(i) (wil_to_wdev(i)->netdev)
269+#define ndev_to_wil(n) (wdev_to_wil(n->ieee80211_ptr))
270+
271+#define wil_dbg(wil, fmt, arg...) netdev_dbg(wil_to_ndev(wil), fmt, ##arg)
272+#define wil_info(wil, fmt, arg...) netdev_info(wil_to_ndev(wil), fmt, ##arg)
273+#define wil_err(wil, fmt, arg...) netdev_err(wil_to_ndev(wil), fmt, ##arg)
274+
275+#define wil_dbg_IRQ(wil, fmt, arg...) wil_dbg(wil, "DBG[ IRQ]" fmt, ##arg)
276+#define wil_dbg_TXRX(wil, fmt, arg...) wil_dbg(wil, "DBG[TXRX]" fmt, ##arg)
277+#define wil_dbg_WMI(wil, fmt, arg...) wil_dbg(wil, "DBG[ WMI]" fmt, ##arg)
278+
279+#define wil_hex_dump_TXRX(prefix_str, prefix_type, rowsize, \
280+ groupsize, buf, len, ascii) \
281+ wil_print_hex_dump_debug("DBG[TXRX]" prefix_str,\
282+ prefix_type, rowsize, \
283+ groupsize, buf, len, ascii)
284+
285+#define wil_hex_dump_WMI(prefix_str, prefix_type, rowsize, \
286+ groupsize, buf, len, ascii) \
287+ wil_print_hex_dump_debug("DBG[ WMI]" prefix_str,\
288+ prefix_type, rowsize, \
289+ groupsize, buf, len, ascii)
290+
291+void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src,
292+ size_t count);
293+void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
294+ size_t count);
295+
296+void *wil_if_alloc(struct device *dev, void __iomem *csr);
297+void wil_if_free(struct wil6210_priv *wil);
298+int wil_if_add(struct wil6210_priv *wil);
299+void wil_if_remove(struct wil6210_priv *wil);
300+int wil_priv_init(struct wil6210_priv *wil);
301+void wil_priv_deinit(struct wil6210_priv *wil);
302+int wil_reset(struct wil6210_priv *wil);
303+void wil_link_on(struct wil6210_priv *wil);
304+void wil_link_off(struct wil6210_priv *wil);
305+int wil_up(struct wil6210_priv *wil);
306+int wil_down(struct wil6210_priv *wil);
307+void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r);
308+
309+void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr);
310+void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr);
311+int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr,
312+ struct wil6210_mbox_hdr *hdr);
313+int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len);
314+void wmi_recv_cmd(struct wil6210_priv *wil);
315+int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
316+ u16 reply_id, void *reply, u8 reply_size, int to_msec);
317+void wmi_connect_worker(struct work_struct *work);
318+void wmi_event_worker(struct work_struct *work);
319+void wmi_event_flush(struct wil6210_priv *wil);
320+int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid);
321+int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid);
322+int wmi_set_channel(struct wil6210_priv *wil, int channel);
323+int wmi_get_channel(struct wil6210_priv *wil, int *channel);
324+int wmi_tx_eapol(struct wil6210_priv *wil, struct sk_buff *skb);
325+int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index,
326+ const void *mac_addr);
327+int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index,
328+ const void *mac_addr, int key_len, const void *key);
329+int wmi_echo(struct wil6210_priv *wil);
330+int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie);
331+
332+int wil6210_init_irq(struct wil6210_priv *wil, int irq);
333+void wil6210_fini_irq(struct wil6210_priv *wil, int irq);
334+void wil6210_disable_irq(struct wil6210_priv *wil);
335+void wil6210_enable_irq(struct wil6210_priv *wil);
336+
337+int wil6210_debugfs_init(struct wil6210_priv *wil);
338+void wil6210_debugfs_remove(struct wil6210_priv *wil);
339+
340+struct wireless_dev *wil_cfg80211_init(struct device *dev);
341+void wil_wdev_free(struct wil6210_priv *wil);
342+
343+int wmi_set_mac_address(struct wil6210_priv *wil, void *addr);
344+int wmi_set_bcon(struct wil6210_priv *wil, int bi, u8 wmi_nettype);
345+void wil6210_disconnect(struct wil6210_priv *wil, void *bssid);
346+
347+int wil_rx_init(struct wil6210_priv *wil);
348+void wil_rx_fini(struct wil6210_priv *wil);
349+
350+/* TX API */
351+int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
352+ int cid, int tid);
353+void wil_vring_fini_tx(struct wil6210_priv *wil, int id);
354+
355+netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev);
356+void wil_tx_complete(struct wil6210_priv *wil, int ringid);
357+
358+/* RX API */
359+void wil_rx_handle(struct wil6210_priv *wil);
360+
361+int wil_iftype_nl2wmi(enum nl80211_iftype type);
362+
363+#endif /* __WIL6210_H__ */
drivers/net/wireless/ath/wil6210/wmi.c+975−0
@@ -0,0 +1,975 @@
1+/*
2+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
3+ *
4+ * Permission to use, copy, modify, and/or distribute this software for any
5+ * purpose with or without fee is hereby granted, provided that the above
6+ * copyright notice and this permission notice appear in all copies.
7+ *
8+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+ */
16+
17+#include <linux/pci.h>
18+#include <linux/io.h>
19+#include <linux/list.h>
20+#include <linux/etherdevice.h>
21+
22+#include "wil6210.h"
23+#include "wmi.h"
24+
25+/**
26+ * WMI event receiving - theory of operations
27+ *
28+ * When firmware about to report WMI event, it fills memory area
29+ * in the mailbox and raises misc. IRQ. Thread interrupt handler invoked for
30+ * the misc IRQ, function @wmi_recv_cmd called by thread IRQ handler.
31+ *
32+ * @wmi_recv_cmd reads event, allocates memory chunk and attaches it to the
33+ * event list @wil->pending_wmi_ev. Then, work queue @wil->wmi_wq wakes up
34+ * and handles events within the @wmi_event_worker. Every event get detached
35+ * from list, processed and deleted.
36+ *
37+ * Purpose for this mechanism is to release IRQ thread; otherwise,
38+ * if WMI event handling involves another WMI command flow, this 2-nd flow
39+ * won't be completed because of blocked IRQ thread.
40+ */
41+
42+/**
43+ * Addressing - theory of operations
44+ *
45+ * There are several buses present on the WIL6210 card.
46+ * Same memory areas are visible at different address on
47+ * the different busses. There are 3 main bus masters:
48+ * - MAC CPU (ucode)
49+ * - User CPU (firmware)
50+ * - AHB (host)
51+ *
52+ * On the PCI bus, there is one BAR (BAR0) of 2Mb size, exposing
53+ * AHB addresses starting from 0x880000
54+ *
55+ * Internally, firmware uses addresses that allows faster access but
56+ * are invisible from the host. To read from these addresses, alternative
57+ * AHB address must be used.
58+ *
59+ * Memory mapping
60+ * Linker address PCI/Host address
61+ * 0x880000 .. 0xa80000 2Mb BAR0
62+ * 0x800000 .. 0x807000 0x900000 .. 0x907000 28k DCCM
63+ * 0x840000 .. 0x857000 0x908000 .. 0x91f000 92k PERIPH
64+ */
65+
66+/**
67+ * @fw_mapping provides memory remapping table
68+ */
69+static const struct {
70+ u32 from; /* linker address - from, inclusive */
71+ u32 to; /* linker address - to, exclusive */
72+ u32 host; /* PCI/Host address - BAR0 + 0x880000 */
73+} fw_mapping[] = {
74+ {0x000000, 0x040000, 0x8c0000}, /* FW code RAM 256k */
75+ {0x800000, 0x808000, 0x900000}, /* FW data RAM 32k */
76+ {0x840000, 0x860000, 0x908000}, /* peripheral data RAM 128k/96k used */
77+ {0x880000, 0x88a000, 0x880000}, /* various RGF */
78+ {0x8c0000, 0x932000, 0x8c0000}, /* trivial mapping for upper area */
79+ /*
80+ * 920000..930000 ucode code RAM
81+ * 930000..932000 ucode data RAM
82+ */
83+};
84+
85+/**
86+ * return AHB address for given firmware/ucode internal (linker) address
87+ * @x - internal address
88+ * If address have no valid AHB mapping, return 0
89+ */
90+static u32 wmi_addr_remap(u32 x)
91+{
92+ uint i;
93+
94+ for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) {
95+ if ((x >= fw_mapping[i].from) && (x < fw_mapping[i].to))
96+ return x + fw_mapping[i].host - fw_mapping[i].from;
97+ }
98+
99+ return 0;
100+}
101+
102+/**
103+ * Check address validity for WMI buffer; remap if needed
104+ * @ptr - internal (linker) fw/ucode address
105+ *
106+ * Valid buffer should be DWORD aligned
107+ *
108+ * return address for accessing buffer from the host;
109+ * if buffer is not valid, return NULL.
110+ */
111+void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_)
112+{
113+ u32 off;
114+ u32 ptr = le32_to_cpu(ptr_);
115+
116+ if (ptr % 4)
117+ return NULL;
118+
119+ ptr = wmi_addr_remap(ptr);
120+ if (ptr < WIL6210_FW_HOST_OFF)
121+ return NULL;
122+
123+ off = HOSTADDR(ptr);
124+ if (off > WIL6210_MEM_SIZE - 4)
125+ return NULL;
126+
127+ return wil->csr + off;
128+}
129+
130+/**
131+ * Check address validity
132+ */
133+void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr)
134+{
135+ u32 off;
136+
137+ if (ptr % 4)
138+ return NULL;
139+
140+ if (ptr < WIL6210_FW_HOST_OFF)
141+ return NULL;
142+
143+ off = HOSTADDR(ptr);
144+ if (off > WIL6210_MEM_SIZE - 4)
145+ return NULL;
146+
147+ return wil->csr + off;
148+}
149+
150+int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr,
151+ struct wil6210_mbox_hdr *hdr)
152+{
153+ void __iomem *src = wmi_buffer(wil, ptr);
154+ if (!src)
155+ return -EINVAL;
156+
157+ wil_memcpy_fromio_32(hdr, src, sizeof(*hdr));
158+
159+ return 0;
160+}
161+
162+static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
163+{
164+ struct {
165+ struct wil6210_mbox_hdr hdr;
166+ struct wil6210_mbox_hdr_wmi wmi;
167+ } __packed cmd = {
168+ .hdr = {
169+ .type = WIL_MBOX_HDR_TYPE_WMI,
170+ .flags = 0,
171+ .len = cpu_to_le16(sizeof(cmd.wmi) + len),
172+ },
173+ .wmi = {
174+ .id = cpu_to_le16(cmdid),
175+ .info1 = 0,
176+ },
177+ };
178+ struct wil6210_mbox_ring *r = &wil->mbox_ctl.tx;
179+ struct wil6210_mbox_ring_desc d_head;
180+ u32 next_head;
181+ void __iomem *dst;
182+ void __iomem *head = wmi_addr(wil, r->head);
183+ uint retry;
184+
185+ if (sizeof(cmd) + len > r->entry_size) {
186+ wil_err(wil, "WMI size too large: %d bytes, max is %d\n",
187+ (int)(sizeof(cmd) + len), r->entry_size);
188+ return -ERANGE;
189+
190+ }
191+
192+ might_sleep();
193+
194+ if (!test_bit(wil_status_fwready, &wil->status)) {
195+ wil_err(wil, "FW not ready\n");
196+ return -EAGAIN;
197+ }
198+
199+ if (!head) {
200+ wil_err(wil, "WMI head is garbage: 0x%08x\n", r->head);
201+ return -EINVAL;
202+ }
203+ /* read Tx head till it is not busy */
204+ for (retry = 5; retry > 0; retry--) {
205+ wil_memcpy_fromio_32(&d_head, head, sizeof(d_head));
206+ if (d_head.sync == 0)
207+ break;
208+ msleep(20);
209+ }
210+ if (d_head.sync != 0) {
211+ wil_err(wil, "WMI head busy\n");
212+ return -EBUSY;
213+ }
214+ /* next head */
215+ next_head = r->base + ((r->head - r->base + sizeof(d_head)) % r->size);
216+ wil_dbg_WMI(wil, "Head 0x%08x -> 0x%08x\n", r->head, next_head);
217+ /* wait till FW finish with previous command */
218+ for (retry = 5; retry > 0; retry--) {
219+ r->tail = ioread32(wil->csr + HOST_MBOX +
220+ offsetof(struct wil6210_mbox_ctl, tx.tail));
221+ if (next_head != r->tail)
222+ break;
223+ msleep(20);
224+ }
225+ if (next_head == r->tail) {
226+ wil_err(wil, "WMI ring full\n");
227+ return -EBUSY;
228+ }
229+ dst = wmi_buffer(wil, d_head.addr);
230+ if (!dst) {
231+ wil_err(wil, "invalid WMI buffer: 0x%08x\n",
232+ le32_to_cpu(d_head.addr));
233+ return -EINVAL;
234+ }
235+ cmd.hdr.seq = cpu_to_le16(++wil->wmi_seq);
236+ /* set command */
237+ wil_dbg_WMI(wil, "WMI command 0x%04x [%d]\n", cmdid, len);
238+ wil_hex_dump_WMI("Cmd ", DUMP_PREFIX_OFFSET, 16, 1, &cmd,
239+ sizeof(cmd), true);
240+ wil_hex_dump_WMI("cmd ", DUMP_PREFIX_OFFSET, 16, 1, buf,
241+ len, true);
242+ wil_memcpy_toio_32(dst, &cmd, sizeof(cmd));
243+ wil_memcpy_toio_32(dst + sizeof(cmd), buf, len);
244+ /* mark entry as full */
245+ iowrite32(1, wil->csr + HOSTADDR(r->head) +
246+ offsetof(struct wil6210_mbox_ring_desc, sync));
247+ /* advance next ptr */
248+ iowrite32(r->head = next_head, wil->csr + HOST_MBOX +
249+ offsetof(struct wil6210_mbox_ctl, tx.head));
250+
251+ /* interrupt to FW */
252+ iowrite32(SW_INT_MBOX, wil->csr + HOST_SW_INT);
253+
254+ return 0;
255+}
256+
257+int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
258+{
259+ int rc;
260+
261+ mutex_lock(&wil->wmi_mutex);
262+ rc = __wmi_send(wil, cmdid, buf, len);
263+ mutex_unlock(&wil->wmi_mutex);
264+
265+ return rc;
266+}
267+
268+/*=== Event handlers ===*/
269+static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
270+{
271+ struct net_device *ndev = wil_to_ndev(wil);
272+ struct wireless_dev *wdev = wil->wdev;
273+ struct wmi_ready_event *evt = d;
274+ u32 ver = le32_to_cpu(evt->sw_version);
275+
276+ wil_dbg_WMI(wil, "FW ver. %d; MAC %pM\n", ver, evt->mac);
277+
278+ if (!is_valid_ether_addr(ndev->dev_addr)) {
279+ memcpy(ndev->dev_addr, evt->mac, ETH_ALEN);
280+ memcpy(ndev->perm_addr, evt->mac, ETH_ALEN);
281+ }
282+ snprintf(wdev->wiphy->fw_version, sizeof(wdev->wiphy->fw_version),
283+ "%d", ver);
284+}
285+
286+static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id, void *d,
287+ int len)
288+{
289+ wil_dbg_WMI(wil, "WMI: FW ready\n");
290+
291+ set_bit(wil_status_fwready, &wil->status);
292+ /* reuse wmi_ready for the firmware ready indication */
293+ complete(&wil->wmi_ready);
294+}
295+
296+static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
297+{
298+ struct wmi_rx_mgmt_packet_event *data = d;
299+ struct wiphy *wiphy = wil_to_wiphy(wil);
300+ struct ieee80211_mgmt *rx_mgmt_frame =
301+ (struct ieee80211_mgmt *)data->payload;
302+ int ch_no = data->info.channel+1;
303+ u32 freq = ieee80211_channel_to_frequency(ch_no,
304+ IEEE80211_BAND_60GHZ);
305+ struct ieee80211_channel *channel = ieee80211_get_channel(wiphy, freq);
306+ /* TODO convert LE to CPU */
307+ s32 signal = 0; /* TODO */
308+ __le16 fc = rx_mgmt_frame->frame_control;
309+ u32 d_len = le32_to_cpu(data->info.len);
310+ u16 d_status = le16_to_cpu(data->info.status);
311+
312+ wil_dbg_WMI(wil, "MGMT: channel %d MCS %d SNR %d\n",
313+ data->info.channel, data->info.mcs, data->info.snr);
314+ wil_dbg_WMI(wil, "status 0x%04x len %d stype %04x\n", d_status, d_len,
315+ le16_to_cpu(data->info.stype));
316+ wil_dbg_WMI(wil, "qid %d mid %d cid %d\n",
317+ data->info.qid, data->info.mid, data->info.cid);
318+
319+ if (!channel) {
320+ wil_err(wil, "Frame on unsupported channel\n");
321+ return;
322+ }
323+
324+ if (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc)) {
325+ struct cfg80211_bss *bss;
326+ u64 tsf = le64_to_cpu(rx_mgmt_frame->u.beacon.timestamp);
327+ u16 cap = le16_to_cpu(rx_mgmt_frame->u.beacon.capab_info);
328+ u16 bi = le16_to_cpu(rx_mgmt_frame->u.beacon.beacon_int);
329+ const u8 *ie_buf = rx_mgmt_frame->u.beacon.variable;
330+ size_t ie_len = d_len - offsetof(struct ieee80211_mgmt,
331+ u.beacon.variable);
332+ wil_dbg_WMI(wil, "Capability info : 0x%04x\n", cap);
333+
334+ bss = cfg80211_inform_bss(wiphy, channel, rx_mgmt_frame->bssid,
335+ tsf, cap, bi, ie_buf, ie_len,
336+ signal, GFP_KERNEL);
337+ if (bss) {
338+ wil_dbg_WMI(wil, "Added BSS %pM\n",
339+ rx_mgmt_frame->bssid);
340+ cfg80211_put_bss(bss);
341+ } else {
342+ wil_err(wil, "cfg80211_inform_bss() failed\n");
343+ }
344+ }
345+}
346+
347+static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id,
348+ void *d, int len)
349+{
350+ if (wil->scan_request) {
351+ struct wmi_scan_complete_event *data = d;
352+ bool aborted = (data->status != 0);
353+
354+ wil_dbg_WMI(wil, "SCAN_COMPLETE(0x%08x)\n", data->status);
355+ cfg80211_scan_done(wil->scan_request, aborted);
356+ wil->scan_request = NULL;
357+ } else {
358+ wil_err(wil, "SCAN_COMPLETE while not scanning\n");
359+ }
360+}
361+
362+static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
363+{
364+ struct net_device *ndev = wil_to_ndev(wil);
365+ struct wireless_dev *wdev = wil->wdev;
366+ struct wmi_connect_event *evt = d;
367+ int ch; /* channel number */
368+ struct station_info sinfo;
369+ u8 *assoc_req_ie, *assoc_resp_ie;
370+ size_t assoc_req_ielen, assoc_resp_ielen;
371+ /* capinfo(u16) + listen_interval(u16) + IEs */
372+ const size_t assoc_req_ie_offset = sizeof(u16) * 2;
373+ /* capinfo(u16) + status_code(u16) + associd(u16) + IEs */
374+ const size_t assoc_resp_ie_offset = sizeof(u16) * 3;
375+
376+ if (len < sizeof(*evt)) {
377+ wil_err(wil, "Connect event too short : %d bytes\n", len);
378+ return;
379+ }
380+ if (len != sizeof(*evt) + evt->beacon_ie_len + evt->assoc_req_len +
381+ evt->assoc_resp_len) {
382+ wil_err(wil,
383+ "Connect event corrupted : %d != %d + %d + %d + %d\n",
384+ len, (int)sizeof(*evt), evt->beacon_ie_len,
385+ evt->assoc_req_len, evt->assoc_resp_len);
386+ return;
387+ }
388+ ch = evt->channel + 1;
389+ wil_dbg_WMI(wil, "Connect %pM channel [%d] cid %d\n",
390+ evt->bssid, ch, evt->cid);
391+ wil_hex_dump_WMI("connect AI : ", DUMP_PREFIX_OFFSET, 16, 1,
392+ evt->assoc_info, len - sizeof(*evt), true);
393+
394+ /* figure out IE's */
395+ assoc_req_ie = &evt->assoc_info[evt->beacon_ie_len +
396+ assoc_req_ie_offset];
397+ assoc_req_ielen = evt->assoc_req_len - assoc_req_ie_offset;
398+ if (evt->assoc_req_len <= assoc_req_ie_offset) {
399+ assoc_req_ie = NULL;
400+ assoc_req_ielen = 0;
401+ }
402+
403+ assoc_resp_ie = &evt->assoc_info[evt->beacon_ie_len +
404+ evt->assoc_req_len +
405+ assoc_resp_ie_offset];
406+ assoc_resp_ielen = evt->assoc_resp_len - assoc_resp_ie_offset;
407+ if (evt->assoc_resp_len <= assoc_resp_ie_offset) {
408+ assoc_resp_ie = NULL;
409+ assoc_resp_ielen = 0;
410+ }
411+
412+ if ((wdev->iftype == NL80211_IFTYPE_STATION) ||
413+ (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
414+ if (wdev->sme_state != CFG80211_SME_CONNECTING) {
415+ wil_err(wil, "Not in connecting state\n");
416+ return;
417+ }
418+ del_timer_sync(&wil->connect_timer);
419+ cfg80211_connect_result(ndev, evt->bssid,
420+ assoc_req_ie, assoc_req_ielen,
421+ assoc_resp_ie, assoc_resp_ielen,
422+ WLAN_STATUS_SUCCESS, GFP_KERNEL);
423+
424+ } else if ((wdev->iftype == NL80211_IFTYPE_AP) ||
425+ (wdev->iftype == NL80211_IFTYPE_P2P_GO)) {
426+ memset(&sinfo, 0, sizeof(sinfo));
427+
428+ sinfo.generation = wil->sinfo_gen++;
429+
430+ if (assoc_req_ie) {
431+ sinfo.assoc_req_ies = assoc_req_ie;
432+ sinfo.assoc_req_ies_len = assoc_req_ielen;
433+ sinfo.filled |= STATION_INFO_ASSOC_REQ_IES;
434+ }
435+
436+ cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL);
437+ }
438+ set_bit(wil_status_fwconnected, &wil->status);
439+
440+ /* FIXME FW can transmit only ucast frames to peer */
441+ /* FIXME real ring_id instead of hard coded 0 */
442+ memcpy(wil->dst_addr[0], evt->bssid, ETH_ALEN);
443+
444+ wil->pending_connect_cid = evt->cid;
445+ queue_work(wil->wmi_wq_conn, &wil->wmi_connect_worker);
446+}
447+
448+static void wmi_evt_disconnect(struct wil6210_priv *wil, int id,
449+ void *d, int len)
450+{
451+ struct wmi_disconnect_event *evt = d;
452+
453+ wil_dbg_WMI(wil, "Disconnect %pM reason %d proto %d wmi\n",
454+ evt->bssid,
455+ evt->protocol_reason_status, evt->disconnect_reason);
456+
457+ wil->sinfo_gen++;
458+
459+ wil6210_disconnect(wil, evt->bssid);
460+ clear_bit(wil_status_dontscan, &wil->status);
461+}
462+
463+static void wmi_evt_notify(struct wil6210_priv *wil, int id, void *d, int len)
464+{
465+ struct wmi_notify_req_done_event *evt = d;
466+
467+ if (len < sizeof(*evt)) {
468+ wil_err(wil, "Short NOTIFY event\n");
469+ return;
470+ }
471+
472+ wil->stats.tsf = le64_to_cpu(evt->tsf);
473+ wil->stats.snr = le32_to_cpu(evt->snr_val);
474+ wil->stats.bf_mcs = le16_to_cpu(evt->bf_mcs);
475+ wil->stats.my_rx_sector = le16_to_cpu(evt->my_rx_sector);
476+ wil->stats.my_tx_sector = le16_to_cpu(evt->my_tx_sector);
477+ wil->stats.peer_rx_sector = le16_to_cpu(evt->other_rx_sector);
478+ wil->stats.peer_tx_sector = le16_to_cpu(evt->other_tx_sector);
479+ wil_dbg_WMI(wil, "Link status, MCS %d TSF 0x%016llx\n"
480+ "BF status 0x%08x SNR 0x%08x\n"
481+ "Tx Tpt %d goodput %d Rx goodput %d\n"
482+ "Sectors(rx:tx) my %d:%d peer %d:%d\n",
483+ wil->stats.bf_mcs, wil->stats.tsf, evt->status,
484+ wil->stats.snr, le32_to_cpu(evt->tx_tpt),
485+ le32_to_cpu(evt->tx_goodput), le32_to_cpu(evt->rx_goodput),
486+ wil->stats.my_rx_sector, wil->stats.my_tx_sector,
487+ wil->stats.peer_rx_sector, wil->stats.peer_tx_sector);
488+}
489+
490+/*
491+ * Firmware reports EAPOL frame using WME event.
492+ * Reconstruct Ethernet frame and deliver it via normal Rx
493+ */
494+static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id,
495+ void *d, int len)
496+{
497+ struct net_device *ndev = wil_to_ndev(wil);
498+ struct wmi_eapol_rx_event *evt = d;
499+ u16 eapol_len = le16_to_cpu(evt->eapol_len);
500+ int sz = eapol_len + ETH_HLEN;
501+ struct sk_buff *skb;
502+ struct ethhdr *eth;
503+
504+ wil_dbg_WMI(wil, "EAPOL len %d from %pM\n", eapol_len,
505+ evt->src_mac);
506+
507+ if (eapol_len > 196) { /* TODO: revisit size limit */
508+ wil_err(wil, "EAPOL too large\n");
509+ return;
510+ }
511+
512+ skb = alloc_skb(sz, GFP_KERNEL);
513+ if (!skb) {
514+ wil_err(wil, "Failed to allocate skb\n");
515+ return;
516+ }
517+ eth = (struct ethhdr *)skb_put(skb, ETH_HLEN);
518+ memcpy(eth->h_dest, ndev->dev_addr, ETH_ALEN);
519+ memcpy(eth->h_source, evt->src_mac, ETH_ALEN);
520+ eth->h_proto = cpu_to_be16(ETH_P_PAE);
521+ memcpy(skb_put(skb, eapol_len), evt->eapol, eapol_len);
522+ skb->protocol = eth_type_trans(skb, ndev);
523+ if (likely(netif_rx_ni(skb) == NET_RX_SUCCESS)) {
524+ ndev->stats.rx_packets++;
525+ ndev->stats.rx_bytes += skb->len;
526+ } else {
527+ ndev->stats.rx_dropped++;
528+ }
529+}
530+
531+static const struct {
532+ int eventid;
533+ void (*handler)(struct wil6210_priv *wil, int eventid,
534+ void *data, int data_len);
535+} wmi_evt_handlers[] = {
536+ {WMI_READY_EVENTID, wmi_evt_ready},
537+ {WMI_FW_READY_EVENTID, wmi_evt_fw_ready},
538+ {WMI_RX_MGMT_PACKET_EVENTID, wmi_evt_rx_mgmt},
539+ {WMI_SCAN_COMPLETE_EVENTID, wmi_evt_scan_complete},
540+ {WMI_CONNECT_EVENTID, wmi_evt_connect},
541+ {WMI_DISCONNECT_EVENTID, wmi_evt_disconnect},
542+ {WMI_NOTIFY_REQ_DONE_EVENTID, wmi_evt_notify},
543+ {WMI_EAPOL_RX_EVENTID, wmi_evt_eapol_rx},
544+};
545+
546+/*
547+ * Run in IRQ context
548+ * Extract WMI command from mailbox. Queue it to the @wil->pending_wmi_ev
549+ * that will be eventually handled by the @wmi_event_worker in the thread
550+ * context of thread "wil6210_wmi"
551+ */
552+void wmi_recv_cmd(struct wil6210_priv *wil)
553+{
554+ struct wil6210_mbox_ring_desc d_tail;
555+ struct wil6210_mbox_hdr hdr;
556+ struct wil6210_mbox_ring *r = &wil->mbox_ctl.rx;
557+ struct pending_wmi_event *evt;
558+ u8 *cmd;
559+ void __iomem *src;
560+ ulong flags;
561+
562+ for (;;) {
563+ u16 len;
564+
565+ r->head = ioread32(wil->csr + HOST_MBOX +
566+ offsetof(struct wil6210_mbox_ctl, rx.head));
567+ if (r->tail == r->head)
568+ return;
569+
570+ /* read cmd from tail */
571+ wil_memcpy_fromio_32(&d_tail, wil->csr + HOSTADDR(r->tail),
572+ sizeof(struct wil6210_mbox_ring_desc));
573+ if (d_tail.sync == 0) {
574+ wil_err(wil, "Mbox evt not owned by FW?\n");
575+ return;
576+ }
577+
578+ if (0 != wmi_read_hdr(wil, d_tail.addr, &hdr)) {
579+ wil_err(wil, "Mbox evt at 0x%08x?\n",
580+ le32_to_cpu(d_tail.addr));
581+ return;
582+ }
583+
584+ len = le16_to_cpu(hdr.len);
585+ src = wmi_buffer(wil, d_tail.addr) +
586+ sizeof(struct wil6210_mbox_hdr);
587+ evt = kmalloc(ALIGN(offsetof(struct pending_wmi_event,
588+ event.wmi) + len, 4),
589+ GFP_KERNEL);
590+ if (!evt) {
591+ wil_err(wil, "kmalloc for WMI event (%d) failed\n",
592+ len);
593+ return;
594+ }
595+ evt->event.hdr = hdr;
596+ cmd = (void *)&evt->event.wmi;
597+ wil_memcpy_fromio_32(cmd, src, len);
598+ /* mark entry as empty */
599+ iowrite32(0, wil->csr + HOSTADDR(r->tail) +
600+ offsetof(struct wil6210_mbox_ring_desc, sync));
601+ /* indicate */
602+ wil_dbg_WMI(wil, "Mbox evt %04x %04x %04x %02x\n",
603+ le16_to_cpu(hdr.seq), len, le16_to_cpu(hdr.type),
604+ hdr.flags);
605+ if ((hdr.type == WIL_MBOX_HDR_TYPE_WMI) &&
606+ (len >= sizeof(struct wil6210_mbox_hdr_wmi))) {
607+ wil_dbg_WMI(wil, "WMI event 0x%04x\n",
608+ evt->event.wmi.id);
609+ }
610+ wil_hex_dump_WMI("evt ", DUMP_PREFIX_OFFSET, 16, 1,
611+ &evt->event.hdr, sizeof(hdr) + len, true);
612+
613+ /* advance tail */
614+ r->tail = r->base + ((r->tail - r->base +
615+ sizeof(struct wil6210_mbox_ring_desc)) % r->size);
616+ iowrite32(r->tail, wil->csr + HOST_MBOX +
617+ offsetof(struct wil6210_mbox_ctl, rx.tail));
618+
619+ /* add to the pending list */
620+ spin_lock_irqsave(&wil->wmi_ev_lock, flags);
621+ list_add_tail(&evt->list, &wil->pending_wmi_ev);
622+ spin_unlock_irqrestore(&wil->wmi_ev_lock, flags);
623+ {
624+ int q = queue_work(wil->wmi_wq,
625+ &wil->wmi_event_worker);
626+ wil_dbg_WMI(wil, "queue_work -> %d\n", q);
627+ }
628+ }
629+}
630+
631+int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
632+ u16 reply_id, void *reply, u8 reply_size, int to_msec)
633+{
634+ int rc;
635+ int remain;
636+
637+ mutex_lock(&wil->wmi_mutex);
638+
639+ rc = __wmi_send(wil, cmdid, buf, len);
640+ if (rc)
641+ goto out;
642+
643+ wil->reply_id = reply_id;
644+ wil->reply_buf = reply;
645+ wil->reply_size = reply_size;
646+ remain = wait_for_completion_timeout(&wil->wmi_ready,
647+ msecs_to_jiffies(to_msec));
648+ if (0 == remain) {
649+ wil_err(wil, "wmi_call(0x%04x->0x%04x) timeout %d msec\n",
650+ cmdid, reply_id, to_msec);
651+ rc = -ETIME;
652+ } else {
653+ wil_dbg_WMI(wil,
654+ "wmi_call(0x%04x->0x%04x) completed in %d msec\n",
655+ cmdid, reply_id,
656+ to_msec - jiffies_to_msecs(remain));
657+ }
658+ wil->reply_id = 0;
659+ wil->reply_buf = NULL;
660+ wil->reply_size = 0;
661+ out:
662+ mutex_unlock(&wil->wmi_mutex);
663+
664+ return rc;
665+}
666+
667+int wmi_echo(struct wil6210_priv *wil)
668+{
669+ struct wmi_echo_cmd cmd = {
670+ .value = cpu_to_le32(0x12345678),
671+ };
672+
673+ return wmi_call(wil, WMI_ECHO_CMDID, &cmd, sizeof(cmd),
674+ WMI_ECHO_RSP_EVENTID, NULL, 0, 20);
675+}
676+
677+int wmi_set_mac_address(struct wil6210_priv *wil, void *addr)
678+{
679+ struct wmi_set_mac_address_cmd cmd;
680+
681+ memcpy(cmd.mac, addr, ETH_ALEN);
682+
683+ wil_dbg_WMI(wil, "Set MAC %pM\n", addr);
684+
685+ return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, &cmd, sizeof(cmd));
686+}
687+
688+int wmi_set_bcon(struct wil6210_priv *wil, int bi, u8 wmi_nettype)
689+{
690+ struct wmi_bcon_ctrl_cmd cmd = {
691+ .bcon_interval = cpu_to_le16(bi),
692+ .network_type = wmi_nettype,
693+ .disable_sec_offload = 1,
694+ };
695+
696+ if (!wil->secure_pcp)
697+ cmd.disable_sec = 1;
698+
699+ return wmi_send(wil, WMI_BCON_CTRL_CMDID, &cmd, sizeof(cmd));
700+}
701+
702+int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid)
703+{
704+ struct wmi_set_ssid_cmd cmd = {
705+ .ssid_len = cpu_to_le32(ssid_len),
706+ };
707+
708+ if (ssid_len > sizeof(cmd.ssid))
709+ return -EINVAL;
710+
711+ memcpy(cmd.ssid, ssid, ssid_len);
712+
713+ return wmi_send(wil, WMI_SET_SSID_CMDID, &cmd, sizeof(cmd));
714+}
715+
716+int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid)
717+{
718+ int rc;
719+ struct {
720+ struct wil6210_mbox_hdr_wmi wmi;
721+ struct wmi_set_ssid_cmd cmd;
722+ } __packed reply;
723+ int len; /* reply.cmd.ssid_len in CPU order */
724+
725+ rc = wmi_call(wil, WMI_GET_SSID_CMDID, NULL, 0, WMI_GET_SSID_EVENTID,
726+ &reply, sizeof(reply), 20);
727+ if (rc)
728+ return rc;
729+
730+ len = le32_to_cpu(reply.cmd.ssid_len);
731+ if (len > sizeof(reply.cmd.ssid))
732+ return -EINVAL;
733+
734+ *ssid_len = len;
735+ memcpy(ssid, reply.cmd.ssid, len);
736+
737+ return 0;
738+}
739+
740+int wmi_set_channel(struct wil6210_priv *wil, int channel)
741+{
742+ struct wmi_set_pcp_channel_cmd cmd = {
743+ .channel = channel - 1,
744+ };
745+
746+ return wmi_send(wil, WMI_SET_PCP_CHANNEL_CMDID, &cmd, sizeof(cmd));
747+}
748+
749+int wmi_get_channel(struct wil6210_priv *wil, int *channel)
750+{
751+ int rc;
752+ struct {
753+ struct wil6210_mbox_hdr_wmi wmi;
754+ struct wmi_set_pcp_channel_cmd cmd;
755+ } __packed reply;
756+
757+ rc = wmi_call(wil, WMI_GET_PCP_CHANNEL_CMDID, NULL, 0,
758+ WMI_GET_PCP_CHANNEL_EVENTID, &reply, sizeof(reply), 20);
759+ if (rc)
760+ return rc;
761+
762+ if (reply.cmd.channel > 3)
763+ return -EINVAL;
764+
765+ *channel = reply.cmd.channel + 1;
766+
767+ return 0;
768+}
769+
770+int wmi_tx_eapol(struct wil6210_priv *wil, struct sk_buff *skb)
771+{
772+ struct wmi_eapol_tx_cmd *cmd;
773+ struct ethhdr *eth;
774+ u16 eapol_len = skb->len - ETH_HLEN;
775+ void *eapol = skb->data + ETH_HLEN;
776+ uint i;
777+ int rc;
778+
779+ skb_set_mac_header(skb, 0);
780+ eth = eth_hdr(skb);
781+ wil_dbg_WMI(wil, "EAPOL %d bytes to %pM\n", eapol_len, eth->h_dest);
782+ for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
783+ if (memcmp(wil->dst_addr[i], eth->h_dest, ETH_ALEN) == 0)
784+ goto found_dest;
785+ }
786+
787+ return -EINVAL;
788+
789+ found_dest:
790+ /* find out eapol data & len */
791+ cmd = kzalloc(sizeof(*cmd) + eapol_len, GFP_KERNEL);
792+ if (!cmd)
793+ return -EINVAL;
794+
795+ memcpy(cmd->dst_mac, eth->h_dest, ETH_ALEN);
796+ cmd->eapol_len = cpu_to_le16(eapol_len);
797+ memcpy(cmd->eapol, eapol, eapol_len);
798+ rc = wmi_send(wil, WMI_EAPOL_TX_CMDID, cmd, sizeof(*cmd) + eapol_len);
799+ kfree(cmd);
800+
801+ return rc;
802+}
803+
804+int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index,
805+ const void *mac_addr)
806+{
807+ struct wmi_delete_cipher_key_cmd cmd = {
808+ .key_index = key_index,
809+ };
810+
811+ if (mac_addr)
812+ memcpy(cmd.mac, mac_addr, WMI_MAC_LEN);
813+
814+ return wmi_send(wil, WMI_DELETE_CIPHER_KEY_CMDID, &cmd, sizeof(cmd));
815+}
816+
817+int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index,
818+ const void *mac_addr, int key_len, const void *key)
819+{
820+ struct wmi_add_cipher_key_cmd cmd = {
821+ .key_index = key_index,
822+ .key_usage = WMI_KEY_USE_PAIRWISE,
823+ .key_len = key_len,
824+ };
825+
826+ if (!key || (key_len > sizeof(cmd.key)))
827+ return -EINVAL;
828+
829+ memcpy(cmd.key, key, key_len);
830+ if (mac_addr)
831+ memcpy(cmd.mac, mac_addr, WMI_MAC_LEN);
832+
833+ return wmi_send(wil, WMI_ADD_CIPHER_KEY_CMDID, &cmd, sizeof(cmd));
834+}
835+
836+int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie)
837+{
838+ int rc;
839+ u16 len = sizeof(struct wmi_set_appie_cmd) + ie_len;
840+ struct wmi_set_appie_cmd *cmd = kzalloc(len, GFP_KERNEL);
841+ if (!cmd) {
842+ wil_err(wil, "kmalloc(%d) failed\n", len);
843+ return -ENOMEM;
844+ }
845+
846+ cmd->mgmt_frm_type = type;
847+ /* BUG: FW API define ieLen as u8. Will fix FW */
848+ cmd->ie_len = cpu_to_le16(ie_len);
849+ memcpy(cmd->ie_info, ie, ie_len);
850+ rc = wmi_send(wil, WMI_SET_APPIE_CMDID, &cmd, len);
851+ kfree(cmd);
852+
853+ return rc;
854+}
855+
856+void wmi_event_flush(struct wil6210_priv *wil)
857+{
858+ struct pending_wmi_event *evt, *t;
859+
860+ wil_dbg_WMI(wil, "%s()\n", __func__);
861+
862+ list_for_each_entry_safe(evt, t, &wil->pending_wmi_ev, list) {
863+ list_del(&evt->list);
864+ kfree(evt);
865+ }
866+}
867+
868+static bool wmi_evt_call_handler(struct wil6210_priv *wil, int id,
869+ void *d, int len)
870+{
871+ uint i;
872+
873+ for (i = 0; i < ARRAY_SIZE(wmi_evt_handlers); i++) {
874+ if (wmi_evt_handlers[i].eventid == id) {
875+ wmi_evt_handlers[i].handler(wil, id, d, len);
876+ return true;
877+ }
878+ }
879+
880+ return false;
881+}
882+
883+static void wmi_event_handle(struct wil6210_priv *wil,
884+ struct wil6210_mbox_hdr *hdr)
885+{
886+ u16 len = le16_to_cpu(hdr->len);
887+
888+ if ((hdr->type == WIL_MBOX_HDR_TYPE_WMI) &&
889+ (len >= sizeof(struct wil6210_mbox_hdr_wmi))) {
890+ struct wil6210_mbox_hdr_wmi *wmi = (void *)(&hdr[1]);
891+ void *evt_data = (void *)(&wmi[1]);
892+ u16 id = le16_to_cpu(wmi->id);
893+ /* check if someone waits for this event */
894+ if (wil->reply_id && wil->reply_id == id) {
895+ if (wil->reply_buf) {
896+ memcpy(wil->reply_buf, wmi,
897+ min(len, wil->reply_size));
898+ } else {
899+ wmi_evt_call_handler(wil, id, evt_data,
900+ len - sizeof(*wmi));
901+ }
902+ wil_dbg_WMI(wil, "Complete WMI 0x%04x\n", id);
903+ complete(&wil->wmi_ready);
904+ return;
905+ }
906+ /* unsolicited event */
907+ /* search for handler */
908+ if (!wmi_evt_call_handler(wil, id, evt_data,
909+ len - sizeof(*wmi))) {
910+ wil_err(wil, "Unhandled event 0x%04x\n", id);
911+ }
912+ } else {
913+ wil_err(wil, "Unknown event type\n");
914+ print_hex_dump(KERN_ERR, "evt?? ", DUMP_PREFIX_OFFSET, 16, 1,
915+ hdr, sizeof(*hdr) + len, true);
916+ }
917+}
918+
919+/*
920+ * Retrieve next WMI event from the pending list
921+ */
922+static struct list_head *next_wmi_ev(struct wil6210_priv *wil)
923+{
924+ ulong flags;
925+ struct list_head *ret = NULL;
926+
927+ spin_lock_irqsave(&wil->wmi_ev_lock, flags);
928+
929+ if (!list_empty(&wil->pending_wmi_ev)) {
930+ ret = wil->pending_wmi_ev.next;
931+ list_del(ret);
932+ }
933+
934+ spin_unlock_irqrestore(&wil->wmi_ev_lock, flags);
935+
936+ return ret;
937+}
938+
939+/*
940+ * Handler for the WMI events
941+ */
942+void wmi_event_worker(struct work_struct *work)
943+{
944+ struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
945+ wmi_event_worker);
946+ struct pending_wmi_event *evt;
947+ struct list_head *lh;
948+
949+ while ((lh = next_wmi_ev(wil)) != NULL) {
950+ evt = list_entry(lh, struct pending_wmi_event, list);
951+ wmi_event_handle(wil, &evt->event.hdr);
952+ kfree(evt);
953+ }
954+}
955+
956+void wmi_connect_worker(struct work_struct *work)
957+{
958+ int rc;
959+ struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
960+ wmi_connect_worker);
961+
962+ if (wil->pending_connect_cid < 0) {
963+ wil_err(wil, "No connection pending\n");
964+ return;
965+ }
966+
967+ wil_dbg_WMI(wil, "Configure for connection CID %d\n",
968+ wil->pending_connect_cid);
969+
970+ rc = wil_vring_init_tx(wil, 0, WIL6210_TX_RING_SIZE,
971+ wil->pending_connect_cid, 0);
972+ wil->pending_connect_cid = -1;
973+ if (rc == 0)
974+ wil_link_on(wil);
975+}
drivers/net/wireless/ath/wil6210/wmi.h+1116−0
@@ -0,0 +1,1116 @@
1+/*
2+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
3+ * Copyright (c) 2006-2012 Wilocity .
4+ *
5+ * Permission to use, copy, modify, and/or distribute this software for any
6+ * purpose with or without fee is hereby granted, provided that the above
7+ * copyright notice and this permission notice appear in all copies.
8+ *
9+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16+ */
17+
18+/*
19+ * This file contains the definitions of the WMI protocol specified in the
20+ * Wireless Module Interface (WMI) for the Wilocity
21+ * MARLON 60 Gigabit wireless solution.
22+ * It includes definitions of all the commands and events.
23+ * Commands are messages from the host to the WM.
24+ * Events are messages from the WM to the host.
25+ */
26+
27+#ifndef __WILOCITY_WMI_H__
28+#define __WILOCITY_WMI_H__
29+
30+/* General */
31+
32+#define WMI_MAC_LEN (6)
33+#define WMI_PROX_RANGE_NUM (3)
34+
35+/* List of Commands */
36+enum wmi_command_id {
37+ WMI_CONNECT_CMDID = 0x0001,
38+ WMI_DISCONNECT_CMDID = 0x0003,
39+ WMI_START_SCAN_CMDID = 0x0007,
40+ WMI_SET_BSS_FILTER_CMDID = 0x0009,
41+ WMI_SET_PROBED_SSID_CMDID = 0x000a,
42+ WMI_SET_LISTEN_INT_CMDID = 0x000b,
43+ WMI_BCON_CTRL_CMDID = 0x000f,
44+ WMI_ADD_CIPHER_KEY_CMDID = 0x0016,
45+ WMI_DELETE_CIPHER_KEY_CMDID = 0x0017,
46+ WMI_SET_APPIE_CMDID = 0x003f,
47+ WMI_GET_APPIE_CMDID = 0x0040,
48+ WMI_SET_WSC_STATUS_CMDID = 0x0041,
49+ WMI_PXMT_RANGE_CFG_CMDID = 0x0042,
50+ WMI_PXMT_SNR2_RANGE_CFG_CMDID = 0x0043,
51+ WMI_FAST_MEM_ACC_MODE_CMDID = 0x0300,
52+ WMI_MEM_READ_CMDID = 0x0800,
53+ WMI_MEM_WR_CMDID = 0x0801,
54+ WMI_ECHO_CMDID = 0x0803,
55+ WMI_DEEP_ECHO_CMDID = 0x0804,
56+ WMI_CONFIG_MAC_CMDID = 0x0805,
57+ WMI_CONFIG_PHY_DEBUG_CMDID = 0x0806,
58+ WMI_ADD_STATION_CMDID = 0x0807,
59+ WMI_ADD_DEBUG_TX_PCKT_CMDID = 0x0808,
60+ WMI_PHY_GET_STATISTICS_CMDID = 0x0809,
61+ WMI_FS_TUNE_CMDID = 0x080a,
62+ WMI_CORR_MEASURE_CMDID = 0x080b,
63+ WMI_TEMP_SENSE_CMDID = 0x080e,
64+ WMI_DC_CALIB_CMDID = 0x080f,
65+ WMI_SEND_TONE_CMDID = 0x0810,
66+ WMI_IQ_TX_CALIB_CMDID = 0x0811,
67+ WMI_IQ_RX_CALIB_CMDID = 0x0812,
68+ WMI_SET_UCODE_IDLE_CMDID = 0x0813,
69+ WMI_SET_WORK_MODE_CMDID = 0x0815,
70+ WMI_LO_LEAKAGE_CALIB_CMDID = 0x0816,
71+ WMI_MARLON_R_ACTIVATE_CMDID = 0x0817,
72+ WMI_MARLON_R_READ_CMDID = 0x0818,
73+ WMI_MARLON_R_WRITE_CMDID = 0x0819,
74+ WMI_MARLON_R_TXRX_SEL_CMDID = 0x081a,
75+ MAC_IO_STATIC_PARAMS_CMDID = 0x081b,
76+ MAC_IO_DYNAMIC_PARAMS_CMDID = 0x081c,
77+ WMI_SILENT_RSSI_CALIB_CMDID = 0x081d,
78+ WMI_CFG_RX_CHAIN_CMDID = 0x0820,
79+ WMI_VRING_CFG_CMDID = 0x0821,
80+ WMI_RX_ON_CMDID = 0x0822,
81+ WMI_VRING_BA_EN_CMDID = 0x0823,
82+ WMI_VRING_BA_DIS_CMDID = 0x0824,
83+ WMI_RCP_ADDBA_RESP_CMDID = 0x0825,
84+ WMI_RCP_DELBA_CMDID = 0x0826,
85+ WMI_SET_SSID_CMDID = 0x0827,
86+ WMI_GET_SSID_CMDID = 0x0828,
87+ WMI_SET_PCP_CHANNEL_CMDID = 0x0829,
88+ WMI_GET_PCP_CHANNEL_CMDID = 0x082a,
89+ WMI_SW_TX_REQ_CMDID = 0x082b,
90+ WMI_RX_OFF_CMDID = 0x082c,
91+ WMI_READ_MAC_RXQ_CMDID = 0x0830,
92+ WMI_READ_MAC_TXQ_CMDID = 0x0831,
93+ WMI_WRITE_MAC_RXQ_CMDID = 0x0832,
94+ WMI_WRITE_MAC_TXQ_CMDID = 0x0833,
95+ WMI_WRITE_MAC_XQ_FIELD_CMDID = 0x0834,
96+ WMI_MLME_PUSH_CMDID = 0x0835,
97+ WMI_BEAMFORMING_MGMT_CMDID = 0x0836,
98+ WMI_BF_TXSS_MGMT_CMDID = 0x0837,
99+ WMI_BF_SM_MGMT_CMDID = 0x0838,
100+ WMI_BF_RXSS_MGMT_CMDID = 0x0839,
101+ WMI_SET_SECTORS_CMDID = 0x0849,
102+ WMI_MAINTAIN_PAUSE_CMDID = 0x0850,
103+ WMI_MAINTAIN_RESUME_CMDID = 0x0851,
104+ WMI_RS_MGMT_CMDID = 0x0852,
105+ WMI_RF_MGMT_CMDID = 0x0853,
106+ /* Performance monitoring commands */
107+ WMI_BF_CTRL_CMDID = 0x0862,
108+ WMI_NOTIFY_REQ_CMDID = 0x0863,
109+ WMI_GET_STATUS_CMDID = 0x0864,
110+ WMI_UNIT_TEST_CMDID = 0x0900,
111+ WMI_HICCUP_CMDID = 0x0901,
112+ WMI_FLASH_READ_CMDID = 0x0902,
113+ WMI_FLASH_WRITE_CMDID = 0x0903,
114+ WMI_SECURITY_UNIT_TEST_CMDID = 0x0904,
115+
116+ WMI_SET_MAC_ADDRESS_CMDID = 0xf003,
117+ WMI_ABORT_SCAN_CMDID = 0xf007,
118+ WMI_SET_PMK_CMDID = 0xf028,
119+
120+ WMI_SET_PROMISCUOUS_MODE_CMDID = 0xf041,
121+ WMI_GET_PMK_CMDID = 0xf048,
122+ WMI_SET_PASSPHRASE_CMDID = 0xf049,
123+ WMI_SEND_ASSOC_RES_CMDID = 0xf04a,
124+ WMI_SET_ASSOC_REQ_RELAY_CMDID = 0xf04b,
125+ WMI_EAPOL_TX_CMDID = 0xf04c,
126+ WMI_MAC_ADDR_REQ_CMDID = 0xf04d,
127+ WMI_FW_VER_CMDID = 0xf04e,
128+};
129+
130+/*
131+ * Commands data structures
132+ */
133+
134+/*
135+ * Frame Types
136+ */
137+enum wmi_mgmt_frame_type {
138+ WMI_FRAME_BEACON = 0,
139+ WMI_FRAME_PROBE_REQ = 1,
140+ WMI_FRAME_PROBE_RESP = 2,
141+ WMI_FRAME_ASSOC_REQ = 3,
142+ WMI_FRAME_ASSOC_RESP = 4,
143+ WMI_NUM_MGMT_FRAME,
144+};
145+
146+/*
147+ * WMI_CONNECT_CMDID
148+ */
149+enum wmi_network_type {
150+ WMI_NETTYPE_INFRA = 0x01,
151+ WMI_NETTYPE_ADHOC = 0x02,
152+ WMI_NETTYPE_ADHOC_CREATOR = 0x04,
153+ WMI_NETTYPE_AP = 0x10,
154+ WMI_NETTYPE_P2P = 0x20,
155+ WMI_NETTYPE_WBE = 0x40, /* PCIE over 60g */
156+};
157+
158+enum wmi_dot11_auth_mode {
159+ WMI_AUTH11_OPEN = 0x01,
160+ WMI_AUTH11_SHARED = 0x02,
161+ WMI_AUTH11_LEAP = 0x04,
162+ WMI_AUTH11_WSC = 0x08,
163+};
164+
165+enum wmi_auth_mode {
166+ WMI_AUTH_NONE = 0x01,
167+ WMI_AUTH_WPA = 0x02,
168+ WMI_AUTH_WPA2 = 0x04,
169+ WMI_AUTH_WPA_PSK = 0x08,
170+ WMI_AUTH_WPA2_PSK = 0x10,
171+ WMI_AUTH_WPA_CCKM = 0x20,
172+ WMI_AUTH_WPA2_CCKM = 0x40,
173+};
174+
175+enum wmi_crypto_type {
176+ WMI_CRYPT_NONE = 0x01,
177+ WMI_CRYPT_WEP = 0x02,
178+ WMI_CRYPT_TKIP = 0x04,
179+ WMI_CRYPT_AES = 0x08,
180+ WMI_CRYPT_AES_GCMP = 0x20,
181+};
182+
183+
184+enum wmi_connect_ctrl_flag_bits {
185+ WMI_CONNECT_ASSOC_POLICY_USER = 0x0001,
186+ WMI_CONNECT_SEND_REASSOC = 0x0002,
187+ WMI_CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004,
188+ WMI_CONNECT_PROFILE_MATCH_DONE = 0x0008,
189+ WMI_CONNECT_IGNORE_AAC_BEACON = 0x0010,
190+ WMI_CONNECT_CSA_FOLLOW_BSS = 0x0020,
191+ WMI_CONNECT_DO_WPA_OFFLOAD = 0x0040,
192+ WMI_CONNECT_DO_NOT_DEAUTH = 0x0080,
193+};
194+
195+#define WMI_MAX_SSID_LEN (32)
196+
197+struct wmi_connect_cmd {
198+ u8 network_type;
199+ u8 dot11_auth_mode;
200+ u8 auth_mode;
201+ u8 pairwise_crypto_type;
202+ u8 pairwise_crypto_len;
203+ u8 group_crypto_type;
204+ u8 group_crypto_len;
205+ u8 ssid_len;
206+ u8 ssid[WMI_MAX_SSID_LEN];
207+ u8 channel;
208+ u8 reserved0;
209+ u8 bssid[WMI_MAC_LEN];
210+ __le32 ctrl_flags;
211+ u8 dst_mac[WMI_MAC_LEN];
212+ u8 reserved1[2];
213+} __packed;
214+
215+
216+/*
217+ * WMI_RECONNECT_CMDID
218+ */
219+struct wmi_reconnect_cmd {
220+ u8 channel; /* hint */
221+ u8 reserved;
222+ u8 bssid[WMI_MAC_LEN]; /* mandatory if set */
223+} __packed;
224+
225+
226+/*
227+ * WMI_SET_PMK_CMDID
228+ */
229+
230+#define WMI_MIN_KEY_INDEX (0)
231+#define WMI_MAX_KEY_INDEX (3)
232+#define WMI_MAX_KEY_LEN (32)
233+#define WMI_PASSPHRASE_LEN (64)
234+#define WMI_PMK_LEN (32)
235+
236+struct wmi_set_pmk_cmd {
237+ u8 pmk[WMI_PMK_LEN];
238+} __packed;
239+
240+
241+/*
242+ * WMI_SET_PASSPHRASE_CMDID
243+ */
244+struct wmi_set_passphrase_cmd {
245+ u8 ssid[WMI_MAX_SSID_LEN];
246+ u8 passphrase[WMI_PASSPHRASE_LEN];
247+ u8 ssid_len;
248+ u8 passphrase_len;
249+} __packed;
250+
251+/*
252+ * WMI_ADD_CIPHER_KEY_CMDID
253+ */
254+enum wmi_key_usage {
255+ WMI_KEY_USE_PAIRWISE = 0,
256+ WMI_KEY_USE_GROUP = 1,
257+ WMI_KEY_USE_TX = 2, /* default Tx Key - Static WEP only */
258+};
259+
260+struct wmi_add_cipher_key_cmd {
261+ u8 key_index;
262+ u8 key_type;
263+ u8 key_usage; /* enum wmi_key_usage */
264+ u8 key_len;
265+ u8 key_rsc[8]; /* key replay sequence counter */
266+ u8 key[WMI_MAX_KEY_LEN];
267+ u8 key_op_ctrl; /* Additional Key Control information */
268+ u8 mac[WMI_MAC_LEN];
269+} __packed;
270+
271+/*
272+ * WMI_DELETE_CIPHER_KEY_CMDID
273+ */
274+struct wmi_delete_cipher_key_cmd {
275+ u8 key_index;
276+ u8 mac[WMI_MAC_LEN];
277+} __packed;
278+
279+
280+/*
281+ * WMI_START_SCAN_CMDID
282+ *
283+ * Start L1 scan operation
284+ *
285+ * Returned events:
286+ * - WMI_RX_MGMT_PACKET_EVENTID - for every probe resp.
287+ * - WMI_SCAN_COMPLETE_EVENTID
288+ */
289+enum wmi_scan_type {
290+ WMI_LONG_SCAN = 0,
291+ WMI_SHORT_SCAN = 1,
292+};
293+
294+struct wmi_start_scan_cmd {
295+ u8 reserved[8];
296+ __le32 home_dwell_time; /* Max duration in the home channel(ms) */
297+ __le32 force_scan_interval; /* Time interval between scans (ms)*/
298+ u8 scan_type; /* wmi_scan_type */
299+ u8 num_channels; /* how many channels follow */
300+ struct {
301+ u8 channel;
302+ u8 reserved;
303+ } channel_list[0]; /* channels ID's */
304+ /* 0 - 58320 MHz */
305+ /* 1 - 60480 MHz */
306+ /* 2 - 62640 MHz */
307+} __packed;
308+
309+/*
310+ * WMI_SET_PROBED_SSID_CMDID
311+ */
312+#define MAX_PROBED_SSID_INDEX (15)
313+
314+enum wmi_ssid_flag {
315+ WMI_SSID_FLAG_DISABLE = 0, /* disables entry */
316+ WMI_SSID_FLAG_SPECIFIC = 1, /* probes specified ssid */
317+ WMI_SSID_FLAG_ANY = 2, /* probes for any ssid */
318+};
319+
320+struct wmi_probed_ssid_cmd {
321+ u8 entry_index; /* 0 to MAX_PROBED_SSID_INDEX */
322+ u8 flag; /* enum wmi_ssid_flag */
323+ u8 ssid_len;
324+ u8 ssid[WMI_MAX_SSID_LEN];
325+} __packed;
326+
327+/*
328+ * WMI_SET_APPIE_CMDID
329+ * Add Application specified IE to a management frame
330+ */
331+struct wmi_set_appie_cmd {
332+ u8 mgmt_frm_type; /* enum wmi_mgmt_frame_type */
333+ u8 reserved;
334+ __le16 ie_len; /* Length of the IE to be added to MGMT frame */
335+ u8 ie_info[0];
336+} __packed;
337+
338+#define WMI_MAX_IE_LEN (1024)
339+
340+struct wmi_pxmt_range_cfg_cmd {
341+ u8 dst_mac[WMI_MAC_LEN];
342+ __le16 range;
343+} __packed;
344+
345+struct wmi_pxmt_snr2_range_cfg_cmd {
346+ s8 snr2range_arr[WMI_PROX_RANGE_NUM-1];
347+} __packed;
348+
349+/*
350+ * WMI_RF_MGMT_CMDID
351+ */
352+enum wmi_rf_mgmt_type {
353+ WMI_RF_MGMT_W_DISABLE = 0,
354+ WMI_RF_MGMT_W_ENABLE = 1,
355+ WMI_RF_MGMT_GET_STATUS = 2,
356+};
357+
358+struct wmi_rf_mgmt_cmd {
359+ __le32 rf_mgmt_type;
360+} __packed;
361+
362+/*
363+ * WMI_SET_SSID_CMDID
364+ */
365+struct wmi_set_ssid_cmd {
366+ __le32 ssid_len;
367+ u8 ssid[WMI_MAX_SSID_LEN];
368+} __packed;
369+
370+/*
371+ * WMI_SET_PCP_CHANNEL_CMDID
372+ */
373+struct wmi_set_pcp_channel_cmd {
374+ u8 channel;
375+ u8 reserved[3];
376+} __packed;
377+
378+/*
379+ * WMI_BCON_CTRL_CMDID
380+ */
381+struct wmi_bcon_ctrl_cmd {
382+ __le16 bcon_interval;
383+ __le16 frag_num;
384+ __le64 ss_mask;
385+ u8 network_type;
386+ u8 reserved;
387+ u8 disable_sec_offload;
388+ u8 disable_sec;
389+} __packed;
390+
391+/*
392+ * WMI_SW_TX_REQ_CMDID
393+ */
394+struct wmi_sw_tx_req_cmd {
395+ u8 dst_mac[WMI_MAC_LEN];
396+ __le16 len;
397+ u8 payload[0];
398+} __packed;
399+
400+/*
401+ * WMI_VRING_CFG_CMDID
402+ */
403+
404+struct wmi_sw_ring_cfg {
405+ __le64 ring_mem_base;
406+ __le16 ring_size;
407+ __le16 max_mpdu_size;
408+} __packed;
409+
410+struct wmi_vring_cfg_schd {
411+ __le16 priority;
412+ __le16 timeslot_us;
413+} __packed;
414+
415+enum wmi_vring_cfg_encap_trans_type {
416+ WMI_VRING_ENC_TYPE_802_3 = 0,
417+ WMI_VRING_ENC_TYPE_NATIVE_WIFI = 1,
418+};
419+
420+enum wmi_vring_cfg_ds_cfg {
421+ WMI_VRING_DS_PBSS = 0,
422+ WMI_VRING_DS_STATION = 1,
423+ WMI_VRING_DS_AP = 2,
424+ WMI_VRING_DS_ADDR4 = 3,
425+};
426+
427+enum wmi_vring_cfg_nwifi_ds_trans_type {
428+ WMI_NWIFI_TX_TRANS_MODE_NO = 0,
429+ WMI_NWIFI_TX_TRANS_MODE_AP2PBSS = 1,
430+ WMI_NWIFI_TX_TRANS_MODE_STA2PBSS = 2,
431+};
432+
433+enum wmi_vring_cfg_schd_params_priority {
434+ WMI_SCH_PRIO_REGULAR = 0,
435+ WMI_SCH_PRIO_HIGH = 1,
436+};
437+
438+struct wmi_vring_cfg {
439+ struct wmi_sw_ring_cfg tx_sw_ring;
440+ u8 ringid; /* 0-23 vrings */
441+
442+ #define CIDXTID_CID_POS (0)
443+ #define CIDXTID_CID_LEN (4)
444+ #define CIDXTID_CID_MSK (0xF)
445+ #define CIDXTID_TID_POS (4)
446+ #define CIDXTID_TID_LEN (4)
447+ #define CIDXTID_TID_MSK (0xF0)
448+ u8 cidxtid;
449+
450+ u8 encap_trans_type;
451+ u8 ds_cfg; /* 802.3 DS cfg */
452+ u8 nwifi_ds_trans_type;
453+
454+ #define VRING_CFG_MAC_CTRL_LIFETIME_EN_POS (0)
455+ #define VRING_CFG_MAC_CTRL_LIFETIME_EN_LEN (1)
456+ #define VRING_CFG_MAC_CTRL_LIFETIME_EN_MSK (0x1)
457+ #define VRING_CFG_MAC_CTRL_AGGR_EN_POS (1)
458+ #define VRING_CFG_MAC_CTRL_AGGR_EN_LEN (1)
459+ #define VRING_CFG_MAC_CTRL_AGGR_EN_MSK (0x2)
460+ u8 mac_ctrl;
461+
462+ #define VRING_CFG_TO_RESOLUTION_VALUE_POS (0)
463+ #define VRING_CFG_TO_RESOLUTION_VALUE_LEN (6)
464+ #define VRING_CFG_TO_RESOLUTION_VALUE_MSK (0x3F)
465+ u8 to_resolution;
466+ u8 agg_max_wsize;
467+ struct wmi_vring_cfg_schd schd_params;
468+} __packed;
469+
470+enum wmi_vring_cfg_cmd_action {
471+ WMI_VRING_CMD_ADD = 0,
472+ WMI_VRING_CMD_MODIFY = 1,
473+ WMI_VRING_CMD_DELETE = 2,
474+};
475+
476+struct wmi_vring_cfg_cmd {
477+ __le32 action;
478+ struct wmi_vring_cfg vring_cfg;
479+} __packed;
480+
481+/*
482+ * WMI_VRING_BA_EN_CMDID
483+ */
484+struct wmi_vring_ba_en_cmd {
485+ u8 ringid;
486+ u8 agg_max_wsize;
487+ __le16 ba_timeout;
488+} __packed;
489+
490+/*
491+ * WMI_VRING_BA_DIS_CMDID
492+ */
493+struct wmi_vring_ba_dis_cmd {
494+ u8 ringid;
495+ u8 reserved;
496+ __le16 reason;
497+} __packed;
498+
499+/*
500+ * WMI_NOTIFY_REQ_CMDID
501+ */
502+struct wmi_notify_req_cmd {
503+ u8 cid;
504+ u8 reserved[3];
505+ __le32 interval_usec;
506+} __packed;
507+
508+/*
509+ * WMI_CFG_RX_CHAIN_CMDID
510+ */
511+enum wmi_sniffer_cfg_mode {
512+ WMI_SNIFFER_OFF = 0,
513+ WMI_SNIFFER_ON = 1,
514+};
515+
516+enum wmi_sniffer_cfg_phy_info_mode {
517+ WMI_SNIFFER_PHY_INFO_DISABLED = 0,
518+ WMI_SNIFFER_PHY_INFO_ENABLED = 1,
519+};
520+
521+enum wmi_sniffer_cfg_phy_support {
522+ WMI_SNIFFER_CP = 0,
523+ WMI_SNIFFER_DP = 1,
524+ WMI_SNIFFER_BOTH_PHYS = 2,
525+};
526+
527+struct wmi_sniffer_cfg {
528+ __le32 mode; /* enum wmi_sniffer_cfg_mode */
529+ __le32 phy_info_mode; /* enum wmi_sniffer_cfg_phy_info_mode */
530+ __le32 phy_support; /* enum wmi_sniffer_cfg_phy_support */
531+ u8 channel;
532+ u8 reserved[3];
533+} __packed;
534+
535+enum wmi_cfg_rx_chain_cmd_action {
536+ WMI_RX_CHAIN_ADD = 0,
537+ WMI_RX_CHAIN_DEL = 1,
538+};
539+
540+enum wmi_cfg_rx_chain_cmd_decap_trans_type {
541+ WMI_DECAP_TYPE_802_3 = 0,
542+ WMI_DECAP_TYPE_NATIVE_WIFI = 1,
543+};
544+
545+enum wmi_cfg_rx_chain_cmd_nwifi_ds_trans_type {
546+ WMI_NWIFI_RX_TRANS_MODE_NO = 0,
547+ WMI_NWIFI_RX_TRANS_MODE_PBSS2AP = 1,
548+ WMI_NWIFI_RX_TRANS_MODE_PBSS2STA = 2,
549+};
550+
551+struct wmi_cfg_rx_chain_cmd {
552+ __le32 action;
553+ struct wmi_sw_ring_cfg rx_sw_ring;
554+ u8 mid;
555+ u8 decap_trans_type;
556+
557+ #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_POS (0)
558+ #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_LEN (1)
559+ #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_MSK (0x1)
560+ u8 l2_802_3_offload_ctrl;
561+
562+ #define L2_NWIFI_OFFLOAD_CTRL_REMOVE_QOS_POS (0)
563+ #define L2_NWIFI_OFFLOAD_CTRL_REMOVE_QOS_LEN (1)
564+ #define L2_NWIFI_OFFLOAD_CTRL_REMOVE_QOS_MSK (0x1)
565+ #define L2_NWIFI_OFFLOAD_CTRL_REMOVE_PN_POS (1)
566+ #define L2_NWIFI_OFFLOAD_CTRL_REMOVE_PN_LEN (1)
567+ #define L2_NWIFI_OFFLOAD_CTRL_REMOVE_PN_MSK (0x2)
568+ u8 l2_nwifi_offload_ctrl;
569+
570+ u8 vlan_id;
571+ u8 nwifi_ds_trans_type;
572+
573+ #define L3_L4_CTRL_IPV4_CHECKSUM_EN_POS (0)
574+ #define L3_L4_CTRL_IPV4_CHECKSUM_EN_LEN (1)
575+ #define L3_L4_CTRL_IPV4_CHECKSUM_EN_MSK (0x1)
576+ #define L3_L4_CTRL_TCPIP_CHECKSUM_EN_POS (1)
577+ #define L3_L4_CTRL_TCPIP_CHECKSUM_EN_LEN (1)
578+ #define L3_L4_CTRL_TCPIP_CHECKSUM_EN_MSK (0x2)
579+ u8 l3_l4_ctrl;
580+
581+ #define RING_CTRL_OVERRIDE_PREFETCH_THRSH_POS (0)
582+ #define RING_CTRL_OVERRIDE_PREFETCH_THRSH_LEN (1)
583+ #define RING_CTRL_OVERRIDE_PREFETCH_THRSH_MSK (0x1)
584+ #define RING_CTRL_OVERRIDE_WB_THRSH_POS (1)
585+ #define RING_CTRL_OVERRIDE_WB_THRSH_LEN (1)
586+ #define RING_CTRL_OVERRIDE_WB_THRSH_MSK (0x2)
587+ #define RING_CTRL_OVERRIDE_ITR_THRSH_POS (2)
588+ #define RING_CTRL_OVERRIDE_ITR_THRSH_LEN (1)
589+ #define RING_CTRL_OVERRIDE_ITR_THRSH_MSK (0x4)
590+ #define RING_CTRL_OVERRIDE_HOST_THRSH_POS (3)
591+ #define RING_CTRL_OVERRIDE_HOST_THRSH_LEN (1)
592+ #define RING_CTRL_OVERRIDE_HOST_THRSH_MSK (0x8)
593+ u8 ring_ctrl;
594+
595+ __le16 prefetch_thrsh;
596+ __le16 wb_thrsh;
597+ __le32 itr_value;
598+ __le16 host_thrsh;
599+ u8 reserved[2];
600+ struct wmi_sniffer_cfg sniffer_cfg;
601+} __packed;
602+
603+/*
604+ * WMI_RCP_ADDBA_RESP_CMDID
605+ */
606+struct wmi_rcp_addba_resp_cmd {
607+
608+ #define CIDXTID_CID_POS (0)
609+ #define CIDXTID_CID_LEN (4)
610+ #define CIDXTID_CID_MSK (0xF)
611+ #define CIDXTID_TID_POS (4)
612+ #define CIDXTID_TID_LEN (4)
613+ #define CIDXTID_TID_MSK (0xF0)
614+ u8 cidxtid;
615+
616+ u8 dialog_token;
617+ __le16 status_code;
618+ __le16 ba_param_set; /* ieee80211_ba_parameterset field to send */
619+ __le16 ba_timeout;
620+} __packed;
621+
622+/*
623+ * WMI_RCP_DELBA_CMDID
624+ */
625+struct wmi_rcp_delba_cmd {
626+
627+ #define CIDXTID_CID_POS (0)
628+ #define CIDXTID_CID_LEN (4)
629+ #define CIDXTID_CID_MSK (0xF)
630+ #define CIDXTID_TID_POS (4)
631+ #define CIDXTID_TID_LEN (4)
632+ #define CIDXTID_TID_MSK (0xF0)
633+ u8 cidxtid;
634+
635+ u8 reserved;
636+ __le16 reason;
637+} __packed;
638+
639+/*
640+ * WMI_RCP_ADDBA_REQ_CMDID
641+ */
642+struct wmi_rcp_addba_req_cmd {
643+
644+ #define CIDXTID_CID_POS (0)
645+ #define CIDXTID_CID_LEN (4)
646+ #define CIDXTID_CID_MSK (0xF)
647+ #define CIDXTID_TID_POS (4)
648+ #define CIDXTID_TID_LEN (4)
649+ #define CIDXTID_TID_MSK (0xF0)
650+ u8 cidxtid;
651+
652+ u8 dialog_token;
653+ /* ieee80211_ba_parameterset field as it received */
654+ __le16 ba_param_set;
655+ __le16 ba_timeout;
656+ /* ieee80211_ba_seqstrl field as it received */
657+ __le16 ba_seq_ctrl;
658+} __packed;
659+
660+/*
661+ * WMI_SET_MAC_ADDRESS_CMDID
662+ */
663+struct wmi_set_mac_address_cmd {
664+ u8 mac[WMI_MAC_LEN];
665+ u8 reserved[2];
666+} __packed;
667+
668+
669+/*
670+* WMI_EAPOL_TX_CMDID
671+*/
672+struct wmi_eapol_tx_cmd {
673+ u8 dst_mac[WMI_MAC_LEN];
674+ __le16 eapol_len;
675+ u8 eapol[0];
676+} __packed;
677+
678+/*
679+ * WMI_ECHO_CMDID
680+ *
681+ * Check FW is alive
682+ *
683+ * WMI_DEEP_ECHO_CMDID
684+ *
685+ * Check FW and ucode are alive
686+ *
687+ * Returned event: WMI_ECHO_RSP_EVENTID
688+ * same event for both commands
689+ */
690+struct wmi_echo_cmd {
691+ __le32 value;
692+} __packed;
693+
694+/*
695+ * WMI Events
696+ */
697+
698+/*
699+ * List of Events (target to host)
700+ */
701+enum wmi_event_id {
702+ WMI_IMM_RSP_EVENTID = 0x0000,
703+ WMI_READY_EVENTID = 0x1001,
704+ WMI_CONNECT_EVENTID = 0x1002,
705+ WMI_DISCONNECT_EVENTID = 0x1003,
706+ WMI_SCAN_COMPLETE_EVENTID = 0x100a,
707+ WMI_REPORT_STATISTICS_EVENTID = 0x100b,
708+ WMI_RD_MEM_RSP_EVENTID = 0x1800,
709+ WMI_FW_READY_EVENTID = 0x1801,
710+ WMI_EXIT_FAST_MEM_ACC_MODE_EVENTID = 0x0200,
711+ WMI_ECHO_RSP_EVENTID = 0x1803,
712+ WMI_CONFIG_MAC_DONE_EVENTID = 0x1805,
713+ WMI_CONFIG_PHY_DEBUG_DONE_EVENTID = 0x1806,
714+ WMI_ADD_STATION_DONE_EVENTID = 0x1807,
715+ WMI_ADD_DEBUG_TX_PCKT_DONE_EVENTID = 0x1808,
716+ WMI_PHY_GET_STATISTICS_EVENTID = 0x1809,
717+ WMI_FS_TUNE_DONE_EVENTID = 0x180a,
718+ WMI_CORR_MEASURE_DONE_EVENTID = 0x180b,
719+ WMI_TEMP_SENSE_DONE_EVENTID = 0x180e,
720+ WMI_DC_CALIB_DONE_EVENTID = 0x180f,
721+ WMI_IQ_TX_CALIB_DONE_EVENTID = 0x1811,
722+ WMI_IQ_RX_CALIB_DONE_EVENTID = 0x1812,
723+ WMI_SET_WORK_MODE_DONE_EVENTID = 0x1815,
724+ WMI_LO_LEAKAGE_CALIB_DONE_EVENTID = 0x1816,
725+ WMI_MARLON_R_ACTIVATE_DONE_EVENTID = 0x1817,
726+ WMI_MARLON_R_READ_DONE_EVENTID = 0x1818,
727+ WMI_MARLON_R_WRITE_DONE_EVENTID = 0x1819,
728+ WMI_MARLON_R_TXRX_SEL_DONE_EVENTID = 0x181a,
729+ WMI_SILENT_RSSI_CALIB_DONE_EVENTID = 0x181d,
730+
731+ WMI_CFG_RX_CHAIN_DONE_EVENTID = 0x1820,
732+ WMI_VRING_CFG_DONE_EVENTID = 0x1821,
733+ WMI_RX_ON_DONE_EVENTID = 0x1822,
734+ WMI_BA_STATUS_EVENTID = 0x1823,
735+ WMI_RCP_ADDBA_REQ_EVENTID = 0x1824,
736+ WMI_ADDBA_RESP_SENT_EVENTID = 0x1825,
737+ WMI_DELBA_EVENTID = 0x1826,
738+ WMI_GET_SSID_EVENTID = 0x1828,
739+ WMI_GET_PCP_CHANNEL_EVENTID = 0x182a,
740+ WMI_SW_TX_COMPLETE_EVENTID = 0x182b,
741+ WMI_RX_OFF_DONE_EVENTID = 0x182c,
742+
743+ WMI_READ_MAC_RXQ_EVENTID = 0x1830,
744+ WMI_READ_MAC_TXQ_EVENTID = 0x1831,
745+ WMI_WRITE_MAC_RXQ_EVENTID = 0x1832,
746+ WMI_WRITE_MAC_TXQ_EVENTID = 0x1833,
747+ WMI_WRITE_MAC_XQ_FIELD_EVENTID = 0x1834,
748+
749+ WMI_BEAFORMING_MGMT_DONE_EVENTID = 0x1836,
750+ WMI_BF_TXSS_MGMT_DONE_EVENTID = 0x1837,
751+ WMI_BF_RXSS_MGMT_DONE_EVENTID = 0x1839,
752+ WMI_RS_MGMT_DONE_EVENTID = 0x1852,
753+ WMI_RF_MGMT_STATUS_EVENTID = 0x1853,
754+ WMI_BF_SM_MGMT_DONE_EVENTID = 0x1838,
755+ WMI_RX_MGMT_PACKET_EVENTID = 0x1840,
756+
757+ /* Performance monitoring events */
758+ WMI_DATA_PORT_OPEN_EVENTID = 0x1860,
759+ WMI_WBE_LINKDOWN_EVENTID = 0x1861,
760+
761+ WMI_BF_CTRL_DONE_EVENTID = 0x1862,
762+ WMI_NOTIFY_REQ_DONE_EVENTID = 0x1863,
763+ WMI_GET_STATUS_DONE_EVENTID = 0x1864,
764+
765+ WMI_UNIT_TEST_EVENTID = 0x1900,
766+ WMI_FLASH_READ_DONE_EVENTID = 0x1902,
767+ WMI_FLASH_WRITE_DONE_EVENTID = 0x1903,
768+
769+ WMI_SET_CHANNEL_EVENTID = 0x9000,
770+ WMI_ASSOC_REQ_EVENTID = 0x9001,
771+ WMI_EAPOL_RX_EVENTID = 0x9002,
772+ WMI_MAC_ADDR_RESP_EVENTID = 0x9003,
773+ WMI_FW_VER_EVENTID = 0x9004,
774+};
775+
776+/*
777+ * Events data structures
778+ */
779+
780+/*
781+ * WMI_RF_MGMT_STATUS_EVENTID
782+ */
783+enum wmi_rf_status {
784+ WMI_RF_ENABLED = 0,
785+ WMI_RF_DISABLED_HW = 1,
786+ WMI_RF_DISABLED_SW = 2,
787+ WMI_RF_DISABLED_HW_SW = 3,
788+};
789+
790+struct wmi_rf_mgmt_status_event {
791+ __le32 rf_status;
792+} __packed;
793+
794+/*
795+ * WMI_GET_STATUS_DONE_EVENTID
796+ */
797+struct wmi_get_status_done_event {
798+ __le32 is_associated;
799+ u8 cid;
800+ u8 reserved0[3];
801+ u8 bssid[WMI_MAC_LEN];
802+ u8 channel;
803+ u8 reserved1;
804+ u8 network_type;
805+ u8 reserved2[3];
806+ __le32 ssid_len;
807+ u8 ssid[WMI_MAX_SSID_LEN];
808+ __le32 rf_status;
809+ __le32 is_secured;
810+} __packed;
811+
812+/*
813+ * WMI_FW_VER_EVENTID
814+ */
815+struct wmi_fw_ver_event {
816+ u8 major;
817+ u8 minor;
818+ __le16 subminor;
819+ __le16 build;
820+} __packed;
821+
822+/*
823+* WMI_MAC_ADDR_RESP_EVENTID
824+*/
825+struct wmi_mac_addr_resp_event {
826+ u8 mac[WMI_MAC_LEN];
827+ u8 auth_mode;
828+ u8 crypt_mode;
829+ __le32 offload_mode;
830+} __packed;
831+
832+/*
833+* WMI_EAPOL_RX_EVENTID
834+*/
835+struct wmi_eapol_rx_event {
836+ u8 src_mac[WMI_MAC_LEN];
837+ __le16 eapol_len;
838+ u8 eapol[0];
839+} __packed;
840+
841+/*
842+* WMI_READY_EVENTID
843+*/
844+enum wmi_phy_capability {
845+ WMI_11A_CAPABILITY = 1,
846+ WMI_11G_CAPABILITY = 2,
847+ WMI_11AG_CAPABILITY = 3,
848+ WMI_11NA_CAPABILITY = 4,
849+ WMI_11NG_CAPABILITY = 5,
850+ WMI_11NAG_CAPABILITY = 6,
851+ WMI_11AD_CAPABILITY = 7,
852+ WMI_11N_CAPABILITY_OFFSET = WMI_11NA_CAPABILITY - WMI_11A_CAPABILITY,
853+};
854+
855+struct wmi_ready_event {
856+ __le32 sw_version;
857+ __le32 abi_version;
858+ u8 mac[WMI_MAC_LEN];
859+ u8 phy_capability; /* enum wmi_phy_capability */
860+ u8 reserved;
861+} __packed;
862+
863+/*
864+ * WMI_NOTIFY_REQ_DONE_EVENTID
865+ */
866+struct wmi_notify_req_done_event {
867+ __le32 status;
868+ __le64 tsf;
869+ __le32 snr_val;
870+ __le32 tx_tpt;
871+ __le32 tx_goodput;
872+ __le32 rx_goodput;
873+ __le16 bf_mcs;
874+ __le16 my_rx_sector;
875+ __le16 my_tx_sector;
876+ __le16 other_rx_sector;
877+ __le16 other_tx_sector;
878+ __le16 range;
879+} __packed;
880+
881+/*
882+ * WMI_CONNECT_EVENTID
883+ */
884+struct wmi_connect_event {
885+ u8 channel;
886+ u8 reserved0;
887+ u8 bssid[WMI_MAC_LEN];
888+ __le16 listen_interval;
889+ __le16 beacon_interval;
890+ u8 network_type;
891+ u8 reserved1[3];
892+ u8 beacon_ie_len;
893+ u8 assoc_req_len;
894+ u8 assoc_resp_len;
895+ u8 cid;
896+ u8 reserved2[3];
897+ u8 assoc_info[0];
898+} __packed;
899+
900+/*
901+ * WMI_DISCONNECT_EVENTID
902+ */
903+enum wmi_disconnect_reason {
904+ WMI_DIS_REASON_NO_NETWORK_AVAIL = 1,
905+ WMI_DIS_REASON_LOST_LINK = 2, /* bmiss */
906+ WMI_DIS_REASON_DISCONNECT_CMD = 3,
907+ WMI_DIS_REASON_BSS_DISCONNECTED = 4,
908+ WMI_DIS_REASON_AUTH_FAILED = 5,
909+ WMI_DIS_REASON_ASSOC_FAILED = 6,
910+ WMI_DIS_REASON_NO_RESOURCES_AVAIL = 7,
911+ WMI_DIS_REASON_CSERV_DISCONNECT = 8,
912+ WMI_DIS_REASON_INVALID_PROFILE = 10,
913+ WMI_DIS_REASON_DOT11H_CHANNEL_SWITCH = 11,
914+ WMI_DIS_REASON_PROFILE_MISMATCH = 12,
915+ WMI_DIS_REASON_CONNECTION_EVICTED = 13,
916+ WMI_DIS_REASON_IBSS_MERGE = 14,
917+};
918+
919+struct wmi_disconnect_event {
920+ __le16 protocol_reason_status; /* reason code, see 802.11 spec. */
921+ u8 bssid[WMI_MAC_LEN]; /* set if known */
922+ u8 disconnect_reason; /* see wmi_disconnect_reason_e */
923+ u8 assoc_resp_len;
924+ u8 assoc_info[0];
925+} __packed;
926+
927+/*
928+ * WMI_SCAN_COMPLETE_EVENTID
929+ */
930+struct wmi_scan_complete_event {
931+ __le32 status;
932+} __packed;
933+
934+/*
935+ * WMI_BA_STATUS_EVENTID
936+ */
937+enum wmi_vring_ba_status {
938+ WMI_BA_AGREED = 0,
939+ WMI_BA_NON_AGREED = 1,
940+};
941+
942+struct wmi_vring_ba_status_event {
943+ __le16 status;
944+ u8 reserved[2];
945+ u8 ringid;
946+ u8 agg_wsize;
947+ __le16 ba_timeout;
948+} __packed;
949+
950+/*
951+ * WMI_DELBA_EVENTID
952+ */
953+struct wmi_delba_event {
954+
955+ #define CIDXTID_CID_POS (0)
956+ #define CIDXTID_CID_LEN (4)
957+ #define CIDXTID_CID_MSK (0xF)
958+ #define CIDXTID_TID_POS (4)
959+ #define CIDXTID_TID_LEN (4)
960+ #define CIDXTID_TID_MSK (0xF0)
961+ u8 cidxtid;
962+
963+ u8 from_initiator;
964+ __le16 reason;
965+} __packed;
966+
967+/*
968+ * WMI_VRING_CFG_DONE_EVENTID
969+ */
970+enum wmi_vring_cfg_done_event_status {
971+ WMI_VRING_CFG_SUCCESS = 0,
972+ WMI_VRING_CFG_FAILURE = 1,
973+};
974+
975+struct wmi_vring_cfg_done_event {
976+ u8 ringid;
977+ u8 status;
978+ u8 reserved[2];
979+ __le32 tx_vring_tail_ptr;
980+} __packed;
981+
982+/*
983+ * WMI_ADDBA_RESP_SENT_EVENTID
984+ */
985+enum wmi_rcp_addba_resp_sent_event_status {
986+ WMI_ADDBA_SUCCESS = 0,
987+ WMI_ADDBA_FAIL = 1,
988+};
989+
990+struct wmi_rcp_addba_resp_sent_event {
991+
992+ #define CIDXTID_CID_POS (0)
993+ #define CIDXTID_CID_LEN (4)
994+ #define CIDXTID_CID_MSK (0xF)
995+ #define CIDXTID_TID_POS (4)
996+ #define CIDXTID_TID_LEN (4)
997+ #define CIDXTID_TID_MSK (0xF0)
998+ u8 cidxtid;
999+
1000+ u8 reserved;
1001+ __le16 status;
1002+} __packed;
1003+
1004+/*
1005+ * WMI_RCP_ADDBA_REQ_EVENTID
1006+ */
1007+struct wmi_rcp_addba_req_event {
1008+
1009+ #define CIDXTID_CID_POS (0)
1010+ #define CIDXTID_CID_LEN (4)
1011+ #define CIDXTID_CID_MSK (0xF)
1012+ #define CIDXTID_TID_POS (4)
1013+ #define CIDXTID_TID_LEN (4)
1014+ #define CIDXTID_TID_MSK (0xF0)
1015+ u8 cidxtid;
1016+
1017+ u8 dialog_token;
1018+ __le16 ba_param_set; /* ieee80211_ba_parameterset as it received */
1019+ __le16 ba_timeout;
1020+ __le16 ba_seq_ctrl; /* ieee80211_ba_seqstrl field as it received */
1021+} __packed;
1022+
1023+/*
1024+ * WMI_CFG_RX_CHAIN_DONE_EVENTID
1025+ */
1026+enum wmi_cfg_rx_chain_done_event_status {
1027+ WMI_CFG_RX_CHAIN_SUCCESS = 1,
1028+};
1029+
1030+struct wmi_cfg_rx_chain_done_event {
1031+ __le32 rx_ring_tail_ptr; /* Rx V-Ring Tail pointer */
1032+ __le32 status;
1033+} __packed;
1034+
1035+/*
1036+ * WMI_WBE_LINKDOWN_EVENTID
1037+ */
1038+enum wmi_wbe_link_down_event_reason {
1039+ WMI_WBE_REASON_USER_REQUEST = 0,
1040+ WMI_WBE_REASON_RX_DISASSOC = 1,
1041+ WMI_WBE_REASON_BAD_PHY_LINK = 2,
1042+};
1043+
1044+struct wmi_wbe_link_down_event {
1045+ u8 cid;
1046+ u8 reserved[3];
1047+ __le32 reason;
1048+} __packed;
1049+
1050+/*
1051+ * WMI_DATA_PORT_OPEN_EVENTID
1052+ */
1053+struct wmi_data_port_open_event {
1054+ u8 cid;
1055+ u8 reserved[3];
1056+} __packed;
1057+
1058+/*
1059+ * WMI_GET_PCP_CHANNEL_EVENTID
1060+ */
1061+struct wmi_get_pcp_channel_event {
1062+ u8 channel;
1063+ u8 reserved[3];
1064+} __packed;
1065+
1066+/*
1067+ * WMI_SW_TX_COMPLETE_EVENTID
1068+ */
1069+enum wmi_sw_tx_status {
1070+ WMI_TX_SW_STATUS_SUCCESS = 0,
1071+ WMI_TX_SW_STATUS_FAILED_NO_RESOURCES = 1,
1072+ WMI_TX_SW_STATUS_FAILED_TX = 2,
1073+};
1074+
1075+struct wmi_sw_tx_complete_event {
1076+ u8 status; /* enum wmi_sw_tx_status */
1077+ u8 reserved[3];
1078+} __packed;
1079+
1080+/*
1081+ * WMI_GET_SSID_EVENTID
1082+ */
1083+struct wmi_get_ssid_event {
1084+ __le32 ssid_len;
1085+ u8 ssid[WMI_MAX_SSID_LEN];
1086+} __packed;
1087+
1088+/*
1089+ * WMI_RX_MGMT_PACKET_EVENTID
1090+ */
1091+struct wmi_rx_mgmt_info {
1092+ u8 mcs;
1093+ s8 snr;
1094+ __le16 range;
1095+ __le16 stype;
1096+ __le16 status;
1097+ __le32 len;
1098+ u8 qid;
1099+ u8 mid;
1100+ u8 cid;
1101+ u8 channel; /* From Radio MNGR */
1102+} __packed;
1103+
1104+struct wmi_rx_mgmt_packet_event {
1105+ struct wmi_rx_mgmt_info info;
1106+ u8 payload[0];
1107+} __packed;
1108+
1109+/*
1110+ * WMI_ECHO_RSP_EVENTID
1111+ */
1112+struct wmi_echo_event {
1113+ __le32 echoed_value;
1114+} __packed;
1115+
1116+#endif /* __WILOCITY_WMI_H__ */
drivers/net/wireless/b43/b43.h+5−0
@@ -7,6 +7,7 @@ · 6 unmodified lines
77 #include <linux/hw_random.h>
88 #include <linux/bcma/bcma.h>
99 #include <linux/ssb/ssb.h>
10+#include <linux/completion.h>
1011 #include <net/mac80211.h>
1112
1213 #include "debugfs.h"
@@ -722,6 +723,10 @@ enum b43_firmware_file_type { · 709 unmodified lines
722723 struct b43_request_fw_context {
723724 /* The device we are requesting the fw for. */
724725 struct b43_wldev *dev;
726+ /* a completion event structure needed if this call is asynchronous */
727+ struct completion fw_load_complete;
728+ /* a pointer to the firmware object */
729+ const struct firmware *blob;
725730 /* The type of firmware to request. */
726731 enum b43_firmware_file_type req_type;
727732 /* Error messages for each firmware type. */
drivers/net/wireless/b43/main.c+41−13
@@ -2088,11 +2088,18 @@ static void b43_print_fw_helptext(struct b43_wl *wl, bool error) · 2087 unmodified lines
20882088 b43warn(wl, text);
20892089 }
20902090
2091+static void b43_fw_cb(const struct firmware *firmware, void *context)
2092+{
2093+ struct b43_request_fw_context *ctx = context;
2094+
2095+ ctx->blob = firmware;
2096+ complete(&ctx->fw_load_complete);
2097+}
2098+
20912099 int b43_do_request_fw(struct b43_request_fw_context *ctx,
20922100 const char *name,
2093− struct b43_firmware_file *fw)
2101+ struct b43_firmware_file *fw, bool async)
20942102 {
2095− const struct firmware *blob;
20962103 struct b43_fw_header *hdr;
20972104 u32 size;
20982105 int err;
@@ -2131,11 +2138,31 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx, · 32 unmodified lines
21312138 B43_WARN_ON(1);
21322139 return -ENOSYS;
21332140 }
2134− err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev);
2141+ if (async) {
2142+ /* do this part asynchronously */
2143+ init_completion(&ctx->fw_load_complete);
2144+ err = request_firmware_nowait(THIS_MODULE, 1, ctx->fwname,
2145+ ctx->dev->dev->dev, GFP_KERNEL,
2146+ ctx, b43_fw_cb);
2147+ if (err < 0) {
2148+ pr_err("Unable to load firmware\n");
2149+ return err;
2150+ }
2151+ /* stall here until fw ready */
2152+ wait_for_completion(&ctx->fw_load_complete);
2153+ if (ctx->blob)
2154+ goto fw_ready;
2155+ /* On some ARM systems, the async request will fail, but the next sync
2156+ * request works. For this reason, we dall through here
2157+ */
2158+ }
2159+ err = request_firmware(&ctx->blob, ctx->fwname,
2160+ ctx->dev->dev->dev);
21352161 if (err == -ENOENT) {
21362162 snprintf(ctx->errors[ctx->req_type],
21372163 sizeof(ctx->errors[ctx->req_type]),
2138− "Firmware file \"%s\" not found\n", ctx->fwname);
2164+ "Firmware file \"%s\" not found\n",
2165+ ctx->fwname);
21392166 return err;
21402167 } else if (err) {
21412168 snprintf(ctx->errors[ctx->req_type],
@@ -2144,14 +2171,15 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx, · 2 unmodified lines
21442171 ctx->fwname, err);
21452172 return err;
21462173 }
2147− if (blob->size < sizeof(struct b43_fw_header))
2174+fw_ready:
2175+ if (ctx->blob->size < sizeof(struct b43_fw_header))
21482176 goto err_format;
2149− hdr = (struct b43_fw_header *)(blob->data);
2177+ hdr = (struct b43_fw_header *)(ctx->blob->data);
21502178 switch (hdr->type) {
21512179 case B43_FW_TYPE_UCODE:
21522180 case B43_FW_TYPE_PCM:
21532181 size = be32_to_cpu(hdr->size);
2154− if (size != blob->size - sizeof(struct b43_fw_header))
2182+ if (size != ctx->blob->size - sizeof(struct b43_fw_header))
21552183 goto err_format;
21562184 /* fallthrough */
21572185 case B43_FW_TYPE_IV:
@@ -2162,7 +2190,7 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx, · 4 unmodified lines
21622190 goto err_format;
21632191 }
21642192
2165− fw->data = blob;
2193+ fw->data = ctx->blob;
21662194 fw->filename = name;
21672195 fw->type = ctx->req_type;
21682196
@@ -2172,7 +2200,7 @@ err_format: · 3 unmodified lines
21722200 snprintf(ctx->errors[ctx->req_type],
21732201 sizeof(ctx->errors[ctx->req_type]),
21742202 "Firmware file \"%s\" format error.\n", ctx->fwname);
2175− release_firmware(blob);
2203+ release_firmware(ctx->blob);
21762204
21772205 return -EPROTO;
21782206 }
@@ -2223,7 +2251,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) · 44 unmodified lines
22232251 goto err_no_ucode;
22242252 }
22252253 }
2226− err = b43_do_request_fw(ctx, filename, &fw->ucode);
2254+ err = b43_do_request_fw(ctx, filename, &fw->ucode, true);
22272255 if (err)
22282256 goto err_load;
22292257
@@ -2235,7 +2263,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) · 5 unmodified lines
22352263 else
22362264 goto err_no_pcm;
22372265 fw->pcm_request_failed = false;
2238− err = b43_do_request_fw(ctx, filename, &fw->pcm);
2266+ err = b43_do_request_fw(ctx, filename, &fw->pcm, false);
22392267 if (err == -ENOENT) {
22402268 /* We did not find a PCM file? Not fatal, but
22412269 * core rev <= 10 must do without hwcrypto then. */
@@ -2296,7 +2324,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) · 54 unmodified lines
22962324 default:
22972325 goto err_no_initvals;
22982326 }
2299− err = b43_do_request_fw(ctx, filename, &fw->initvals);
2327+ err = b43_do_request_fw(ctx, filename, &fw->initvals, false);
23002328 if (err)
23012329 goto err_load;
23022330
@@ -2355,7 +2383,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) · 52 unmodified lines
23552383 default:
23562384 goto err_no_initvals;
23572385 }
2358− err = b43_do_request_fw(ctx, filename, &fw->initvals_band);
2386+ err = b43_do_request_fw(ctx, filename, &fw->initvals_band, false);
23592387 if (err)
23602388 goto err_load;
23612389
drivers/net/wireless/b43/main.h+2−3
@@ -137,9 +137,8 @@ void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on); · 136 unmodified lines
137137
138138
139139 struct b43_request_fw_context;
140−int b43_do_request_fw(struct b43_request_fw_context *ctx,
141− const char *name,
142− struct b43_firmware_file *fw);
140+int b43_do_request_fw(struct b43_request_fw_context *ctx, const char *name,
141+ struct b43_firmware_file *fw, bool async);
143142 void b43_do_release_fw(struct b43_firmware_file *fw);
144143
145144 #endif /* B43_MAIN_H_ */
drivers/net/wireless/b43/tables_nphy.c+8−22
@@ -3226,8 +3226,6 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( · 3225 unmodified lines
32263226 {
32273227 struct nphy_gain_ctl_workaround_entry *e;
32283228 u8 phy_idx;
3229− u8 tr_iso = ghz5 ? dev->dev->bus_sprom->fem.ghz5.tr_iso :
3230− dev->dev->bus_sprom->fem.ghz2.tr_iso;
32313229
32323230 if (!ghz5 && dev->phy.rev >= 6 && dev->phy.radio_rev == 11)
32333231 return &nphy_gain_ctl_wa_phy6_radio11_ghz2;
@@ -3249,6 +3247,10 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( · 15 unmodified lines
32493247 !b43_channel_type_is_40mhz(dev->phy.channel_type))
32503248 e->cliplo_gain = 0x2d;
32513249 } else if (!ghz5 && dev->phy.rev >= 5) {
3250+ static const int gain_data[] = {0x0062, 0x0064, 0x006a, 0x106a,
3251+ 0x106c, 0x1074, 0x107c, 0x207c};
3252+ u8 tr_iso = dev->dev->bus_sprom->fem.ghz2.tr_iso;
3253+
32523254 if (ext_lna) {
32533255 e->rfseq_init[0] &= ~0x4000;
32543256 e->rfseq_init[1] &= ~0x4000;
@@ -3256,26 +3258,10 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( · 1 unmodified line
32563258 e->rfseq_init[3] &= ~0x4000;
32573259 e->init_gain &= ~0x4000;
32583260 }
3259− switch (tr_iso) {
3260− case 0:
3261− e->cliplo_gain = 0x0062;
3262− case 1:
3263− e->cliplo_gain = 0x0064;
3264− case 2:
3265− e->cliplo_gain = 0x006a;
3266− case 3:
3267− e->cliplo_gain = 0x106a;
3268− case 4:
3269− e->cliplo_gain = 0x106c;
3270− case 5:
3271− e->cliplo_gain = 0x1074;
3272− case 6:
3273− e->cliplo_gain = 0x107c;
3274− case 7:
3275− e->cliplo_gain = 0x207c;
3276− default:
3277− e->cliplo_gain = 0x106a;
3278− }
3261+ if (tr_iso > 7)
3262+ tr_iso = 3;
3263+ e->cliplo_gain = gain_data[tr_iso];
3264+
32793265 } else if (ghz5 && dev->phy.rev == 4 && ext_lna) {
32803266 e->rfseq_init[0] &= ~0x4000;
32813267 e->rfseq_init[1] &= ~0x4000;
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c+0−2
@@ -15,8 +15,6 @@ · 14 unmodified lines
1515 */
1616 /* ****************** SDIO CARD Interface Functions **************************/
1717
18−#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19−
2018 #include <linux/types.h>
2119 #include <linux/netdevice.h>
2220 #include <linux/export.h>
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c+0−2
@@ -14,8 +14,6 @@ · 13 unmodified lines
1414 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1515 */
1616
17−#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18−
1917 #include <linux/types.h>
2018 #include <linux/netdevice.h>
2119 #include <linux/mmc/sdio.h>
drivers/net/wireless/brcm80211/brcmfmac/dhd.h+5−34
@@ -39,6 +39,7 @@ · 38 unmodified lines
3939 #define BRCMF_C_GET_BSSID 23
4040 #define BRCMF_C_GET_SSID 25
4141 #define BRCMF_C_SET_SSID 26
42+#define BRCMF_C_TERMINATED 28
4243 #define BRCMF_C_GET_CHANNEL 29
4344 #define BRCMF_C_SET_CHANNEL 30
4445 #define BRCMF_C_GET_SRL 31
@@ -480,36 +481,14 @@ struct brcmf_pub { · 435 unmodified lines
480481 unsigned long drv_version; /* Version of dongle-resident driver */
481482 u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */
482483
483− /* Additional stats for the bus level */
484−
485484 /* Multicast data packets sent to dongle */
486485 unsigned long tx_multicast;
487− /* Packets flushed due to unscheduled sendup thread */
488− unsigned long rx_flushed;
489− /* Number of times dpc scheduled by watchdog timer */
490− unsigned long wd_dpc_sched;
491−
492− /* Number of flow control pkts recvd */
493− unsigned long fc_packets;
494−
495− /* Last error return */
496− int bcmerror;
497−
498− /* Last error from dongle */
499− int dongle_error;
500−
501− /* Suspend disable flag flag */
502− int suspend_disable_flag; /* "1" to disable all extra powersaving
503− during suspend */
504− int in_suspend; /* flag set to 1 when early suspend called */
505− int dtim_skip; /* dtim skip , default 0 means wake each dtim */
506486
507487 struct brcmf_if *iflist[BRCMF_MAX_IFS];
508488
509489 struct mutex proto_block;
510490 unsigned char proto_buf[BRCMF_DCMD_MAXLEN];
511491
512− u8 macvalue[ETH_ALEN];
513492 atomic_t pend_8021x_cnt;
514493 wait_queue_head_t pend_8021x_wait;
515494
@@ -519,11 +498,6 @@ struct brcmf_pub { · 3 unmodified lines
519498 #endif
520499 };
521500
522−struct bcmevent_name {
523− uint event;
524− const char *name;
525−};
526−
527501 struct brcmf_if_event {
528502 u8 ifidx;
529503 u8 action;
@@ -557,13 +531,6 @@ struct brcmf_if { · 27 unmodified lines
557531 u8 mac_addr[ETH_ALEN];
558532 };
559533
560−static inline s32 brcmf_ndev_bssidx(struct net_device *ndev)
561−{
562− struct brcmf_if *ifp = netdev_priv(ndev);
563− return ifp->bssidx;
564−}
565−
566−extern const struct bcmevent_name bcmevent_names[];
567534
568535 extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
569536
@@ -576,6 +543,10 @@ extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, · 6 unmodified lines
576543 extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
577544 void *buf, uint len);
578545
546+/* Remove any protocol-specific data header. */
547+extern int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx,
548+ struct sk_buff *rxp);
549+
579550 extern int brcmf_net_attach(struct brcmf_if *ifp);
580551 extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx,
581552 s32 bssidx, char *name, u8 *mac_addr);
drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h+3−16
@@ -130,31 +130,18 @@ int brcmf_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint len) · 129 unmodified lines
130130 * interface functions from common layer
131131 */
132132
133−/* Remove any protocol-specific data header. */
134−extern int brcmf_proto_hdrpull(struct device *dev, int *ifidx,
135− struct sk_buff *rxp);
136−
137133 extern bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
138134 struct sk_buff *pkt, int prec);
139135
140136 /* Receive frame for delivery to OS. Callee disposes of rxp. */
141−extern void brcmf_rx_frame(struct device *dev, u8 ifidx,
142− struct sk_buff_head *rxlist);
143−static inline void brcmf_rx_packet(struct device *dev, int ifidx,
144− struct sk_buff *pkt)
145−{
146− struct sk_buff_head q;
147−
148− skb_queue_head_init(&q);
149− skb_queue_tail(&q, pkt);
150− brcmf_rx_frame(dev, ifidx, &q);
151−}
137+extern void brcmf_rx_frames(struct device *dev, struct sk_buff_head *rxlist);
152138
153139 /* Indication from bus module regarding presence/insertion of dongle. */
154140 extern int brcmf_attach(uint bus_hdrlen, struct device *dev);
155141 /* Indication from bus module regarding removal/absence of dongle */
156142 extern void brcmf_detach(struct device *dev);
157−
143+/* Indication from bus module that dongle should be reset */
144+extern void brcmf_dev_reset(struct device *dev);
158145 /* Indication from bus module to change flow-control state */
159146 extern void brcmf_txflowblock(struct device *dev, bool state);
160147
drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c+12−36
@@ -19,8 +19,6 @@ · 18 unmodified lines
1919 * For certain dcmd codes, the dongle interprets string data from the host.
2020 ******************************************************************************/
2121
22−#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23−
2422 #include <linux/types.h>
2523 #include <linux/netdevice.h>
2624
@@ -94,8 +92,6 @@ struct brcmf_proto_bdc_header { · 67 unmodified lines
9492
9593 struct brcmf_proto {
9694 u16 reqid;
97− u8 pending;
98− u32 lastcmd;
9995 u8 bus_header[BUS_HEADER_LEN];
10096 struct brcmf_proto_cdc_dcmd msg;
10197 unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN];
@@ -107,7 +103,7 @@ static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr) · 5 unmodified lines
107103 int len = le32_to_cpu(prot->msg.len) +
108104 sizeof(struct brcmf_proto_cdc_dcmd);
109105
110− brcmf_dbg(TRACE, "Enter\n");
106+ brcmf_dbg(CDC, "Enter\n");
111107
112108 /* NOTE : cdc->msg.len holds the desired length of the buffer to be
113109 * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
@@ -125,7 +121,7 @@ static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) · 11 unmodified lines
125121 int ret;
126122 struct brcmf_proto *prot = drvr->prot;
127123
128− brcmf_dbg(TRACE, "Enter\n");
124+ brcmf_dbg(CDC, "Enter\n");
129125 len += sizeof(struct brcmf_proto_cdc_dcmd);
130126 do {
131127 ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&prot->msg,
@@ -147,20 +143,7 @@ brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, · 15 unmodified lines
147143 int ret = 0, retries = 0;
148144 u32 id, flags;
149145
150− brcmf_dbg(TRACE, "Enter\n");
151− brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
152−
153− /* Respond "bcmerror" and "bcmerrorstr" with local cache */
154− if (cmd == BRCMF_C_GET_VAR && buf) {
155− if (!strcmp((char *)buf, "bcmerrorstr")) {
156− strncpy((char *)buf, "bcm_error",
157− BCME_STRLEN);
158− goto done;
159− } else if (!strcmp((char *)buf, "bcmerror")) {
160− *(int *)buf = drvr->dongle_error;
161− goto done;
162− }
163− }
146+ brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len);
164147
165148 memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
166149
@@ -210,11 +193,8 @@ retry: · 43 unmodified lines
210193 }
211194
212195 /* Check the ERROR flag */
213− if (flags & CDC_DCMD_ERROR) {
196+ if (flags & CDC_DCMD_ERROR)
214197 ret = le32_to_cpu(msg->status);
215− /* Cache error from dongle */
216− drvr->dongle_error = ret;
217− }
218198
219199 done:
220200 return ret;
@@ -228,8 +208,7 @@ int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, · 7 unmodified lines
228208 int ret = 0;
229209 u32 flags, id;
230210
231− brcmf_dbg(TRACE, "Enter\n");
232− brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
211+ brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len);
233212
234213 memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
235214
@@ -262,11 +241,8 @@ int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, · 26 unmodified lines
262241 }
263242
264243 /* Check the ERROR flag */
265− if (flags & CDC_DCMD_ERROR) {
244+ if (flags & CDC_DCMD_ERROR)
266245 ret = le32_to_cpu(msg->status);
267− /* Cache error from dongle */
268− drvr->dongle_error = ret;
269− }
270246
271247 done:
272248 return ret;
@@ -287,7 +263,7 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, · 14 unmodified lines
287263 {
288264 struct brcmf_proto_bdc_header *h;
289265
290− brcmf_dbg(TRACE, "Enter\n");
266+ brcmf_dbg(CDC, "Enter\n");
291267
292268 /* Push BDC header used to convey priority for buses that don't */
293269
@@ -305,14 +281,12 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, · 11 unmodified lines
305281 BDC_SET_IF_IDX(h, ifidx);
306282 }
307283
308−int brcmf_proto_hdrpull(struct device *dev, int *ifidx,
284+int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx,
309285 struct sk_buff *pktbuf)
310286 {
311287 struct brcmf_proto_bdc_header *h;
312− struct brcmf_bus *bus_if = dev_get_drvdata(dev);
313− struct brcmf_pub *drvr = bus_if->drvr;
314288
315− brcmf_dbg(TRACE, "Enter\n");
289+ brcmf_dbg(CDC, "Enter\n");
316290
317291 /* Pop BDC header used to convey priority for buses that don't */
318292
@@ -338,7 +312,7 @@ int brcmf_proto_hdrpull(struct device *dev, int *ifidx, · 19 unmodified lines
338312 }
339313
340314 if (h->flags & BDC_FLAG_SUM_GOOD) {
341− brcmf_dbg(INFO, "%s: BDC packet received with good rx-csum, flags 0x%x\n",
315+ brcmf_dbg(CDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
342316 brcmf_ifname(drvr, *ifidx), h->flags);
343317 pkt_set_sum_good(pktbuf, true);
344318 }
@@ -348,6 +322,8 @@ int brcmf_proto_hdrpull(struct device *dev, int *ifidx, · 3 unmodified lines
348322 skb_pull(pktbuf, BDC_HEADER_LEN);
349323 skb_pull(pktbuf, h->data_offset << 2);
350324
325+ if (pktbuf->len == 0)
326+ return -ENODATA;
351327 return 0;
352328 }
353329
drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c+0−2
@@ -14,8 +14,6 @@ · 13 unmodified lines
1414 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1515 */
1616
17−#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18−
1917 #include <linux/kernel.h>
2018 #include <linux/string.h>
2119 #include <linux/netdevice.h>
drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h+20−15
@@ -18,21 +18,26 @@ · 17 unmodified lines
1818 #define _BRCMF_DBG_H_
1919
2020 /* message levels */
21−#define BRCMF_TRACE_VAL 0x0002
22−#define BRCMF_INFO_VAL 0x0004
23−#define BRCMF_DATA_VAL 0x0008
24−#define BRCMF_CTL_VAL 0x0010
25−#define BRCMF_TIMER_VAL 0x0020
26−#define BRCMF_HDRS_VAL 0x0040
27−#define BRCMF_BYTES_VAL 0x0080
28−#define BRCMF_INTR_VAL 0x0100
29−#define BRCMF_GLOM_VAL 0x0200
30−#define BRCMF_EVENT_VAL 0x0400
31−#define BRCMF_BTA_VAL 0x0800
32−#define BRCMF_FIL_VAL 0x1000
33−#define BRCMF_USB_VAL 0x2000
34−#define BRCMF_SCAN_VAL 0x4000
35−#define BRCMF_CONN_VAL 0x8000
21+#define BRCMF_TRACE_VAL 0x00000002
22+#define BRCMF_INFO_VAL 0x00000004
23+#define BRCMF_DATA_VAL 0x00000008
24+#define BRCMF_CTL_VAL 0x00000010
25+#define BRCMF_TIMER_VAL 0x00000020
26+#define BRCMF_HDRS_VAL 0x00000040
27+#define BRCMF_BYTES_VAL 0x00000080
28+#define BRCMF_INTR_VAL 0x00000100
29+#define BRCMF_GLOM_VAL 0x00000200
30+#define BRCMF_EVENT_VAL 0x00000400
31+#define BRCMF_BTA_VAL 0x00000800
32+#define BRCMF_FIL_VAL 0x00001000
33+#define BRCMF_USB_VAL 0x00002000
34+#define BRCMF_SCAN_VAL 0x00004000
35+#define BRCMF_CONN_VAL 0x00008000
36+#define BRCMF_CDC_VAL 0x00010000
37+
38+/* set default print format */
39+#undef pr_fmt
40+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
3641
3742 /* Macro for error messages. net_ratelimit() is used when driver
3843 * debugging is not selected. When debugging the driver error
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c+55−35
@@ -14,8 +14,6 @@ · 13 unmodified lines
1414 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1515 */
1616
17−#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18−
1917 #include <linux/kernel.h>
2018 #include <linux/etherdevice.h>
2119 #include <linux/module.h>
@@ -162,28 +160,31 @@ static void brcmf_netdev_set_multicast_list(struct net_device *ndev) · 140 unmodified lines
162160 schedule_work(&ifp->multicast_work);
163161 }
164162
165−static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
163+static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
164+ struct net_device *ndev)
166165 {
167166 int ret;
168167 struct brcmf_if *ifp = netdev_priv(ndev);
169168 struct brcmf_pub *drvr = ifp->drvr;
169+ struct ethhdr *eh;
170170
171171 brcmf_dbg(TRACE, "Enter\n");
172172
173− /* Reject if down */
174− if (!drvr->bus_if->drvr_up ||
175− (drvr->bus_if->state != BRCMF_BUS_DATA)) {
176− brcmf_err("xmit rejected drvup=%d state=%d\n",
177− drvr->bus_if->drvr_up,
178− drvr->bus_if->state);
173+ /* Can the device send data? */
174+ if (drvr->bus_if->state != BRCMF_BUS_DATA) {
175+ brcmf_err("xmit rejected state=%d\n", drvr->bus_if->state);
179176 netif_stop_queue(ndev);
180− return -ENODEV;
177+ dev_kfree_skb(skb);
178+ ret = -ENODEV;
179+ goto done;
181180 }
182181
183182 if (!drvr->iflist[ifp->idx]) {
184183 brcmf_err("bad ifidx %d\n", ifp->idx);
185184 netif_stop_queue(ndev);
186− return -ENODEV;
185+ dev_kfree_skb(skb);
186+ ret = -ENODEV;
187+ goto done;
187188 }
188189
189190 /* Make sure there's enough room for any header */
@@ -204,17 +205,20 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 14 unmodified lines
204205 }
205206 }
206207
207− /* Update multicast statistic */
208− if (skb->len >= ETH_ALEN) {
209− u8 *pktdata = (u8 *)(skb->data);
210− struct ethhdr *eh = (struct ethhdr *)pktdata;
211−
212− if (is_multicast_ether_addr(eh->h_dest))
213− drvr->tx_multicast++;
214− if (ntohs(eh->h_proto) == ETH_P_PAE)
215− atomic_inc(&drvr->pend_8021x_cnt);
208+ /* validate length for ether packet */
209+ if (skb->len < sizeof(*eh)) {
210+ ret = -EINVAL;
211+ dev_kfree_skb(skb);
212+ goto done;
216213 }
217214
215+ /* handle ethernet header */
216+ eh = (struct ethhdr *)(skb->data);
217+ if (is_multicast_ether_addr(eh->h_dest))
218+ drvr->tx_multicast++;
219+ if (ntohs(eh->h_proto) == ETH_P_PAE)
220+ atomic_inc(&drvr->pend_8021x_cnt);
221+
218222 /* If the protocol uses a data header, apply it */
219223 brcmf_proto_hdrpush(drvr, ifp->idx, skb);
220224
@@ -228,7 +232,7 @@ done: · 7 unmodified lines
228232 drvr->bus_if->dstats.tx_packets++;
229233
230234 /* Return ok: we always eat the packet */
231− return 0;
235+ return NETDEV_TX_OK;
232236 }
233237
234238 void brcmf_txflowblock(struct device *dev, bool state)
@@ -250,8 +254,7 @@ void brcmf_txflowblock(struct device *dev, bool state) · 15 unmodified lines
250254 }
251255 }
252256
253−void brcmf_rx_frame(struct device *dev, u8 ifidx,
254− struct sk_buff_head *skb_list)
257+void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
255258 {
256259 unsigned char *eth;
257260 uint len;
@@ -259,12 +262,24 @@ void brcmf_rx_frame(struct device *dev, u8 ifidx, · 1 unmodified line
259262 struct brcmf_if *ifp;
260263 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
261264 struct brcmf_pub *drvr = bus_if->drvr;
265+ u8 ifidx;
266+ int ret;
262267
263268 brcmf_dbg(TRACE, "Enter\n");
264269
265270 skb_queue_walk_safe(skb_list, skb, pnext) {
266271 skb_unlink(skb, skb_list);
267272
273+ /* process and remove protocol-specific header
274+ */
275+ ret = brcmf_proto_hdrpull(drvr, &ifidx, skb);
276+ if (ret < 0) {
277+ if (ret != -ENODATA)
278+ bus_if->dstats.rx_errors++;
279+ brcmu_pkt_buf_free_skb(skb);
280+ continue;
281+ }
282+
268283 /* Get the protocol, maintain skb around eth_type_trans()
269284 * The main reason for this hack is for the limitation of
270285 * Linux 2.4 where 'eth_type_trans' uses the
@@ -328,13 +343,13 @@ void brcmf_rx_frame(struct device *dev, u8 ifidx, · 57 unmodified lines
328343
329344 void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
330345 {
331− uint ifidx;
346+ u8 ifidx;
332347 struct ethhdr *eh;
333348 u16 type;
334349 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
335350 struct brcmf_pub *drvr = bus_if->drvr;
336351
337− brcmf_proto_hdrpull(dev, &ifidx, txp);
352+ brcmf_proto_hdrpull(drvr, &ifidx, txp);
338353
339354 eh = (struct ethhdr *)(txp->data);
340355 type = ntohs(eh->h_proto);
@@ -450,7 +465,7 @@ static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr) · 109 unmodified lines
450465 sprintf(info.version, "%lu", drvr->drv_version);
451466 if (copy_to_user(uaddr, &info, sizeof(info)))
452467 return -EFAULT;
453− brcmf_dbg(CTL, "given %*s, returning %s\n",
468+ brcmf_dbg(TRACE, "given %*s, returning %s\n",
454469 (int)sizeof(drvname), drvname, info.driver);
455470 break;
456471
@@ -570,14 +585,9 @@ static int brcmf_netdev_open(struct net_device *ndev) · 113 unmodified lines
570585 /* Get current TOE mode from dongle */
571586 if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0
572587 && (toe_ol & TOE_TX_CSUM_OL) != 0)
573− drvr->iflist[ifp->idx]->ndev->features |=
574− NETIF_F_IP_CSUM;
588+ ndev->features |= NETIF_F_IP_CSUM;
575589 else
576− drvr->iflist[ifp->idx]->ndev->features &=
577− ~NETIF_F_IP_CSUM;
578−
579− /* make sure RF is ready for work */
580− brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
590+ ndev->features &= ~NETIF_F_IP_CSUM;
581591
582592 /* Allow transmit calls */
583593 netif_start_queue(ndev);
@@ -845,6 +855,17 @@ static void brcmf_bus_detach(struct brcmf_pub *drvr) · 261 unmodified lines
845855 }
846856 }
847857
858+void brcmf_dev_reset(struct device *dev)
859+{
860+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
861+ struct brcmf_pub *drvr = bus_if->drvr;
862+
863+ if (drvr == NULL)
864+ return;
865+
866+ brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1);
867+}
868+
848869 void brcmf_detach(struct device *dev)
849870 {
850871 int i;
@@ -866,9 +887,8 @@ void brcmf_detach(struct device *dev) · 15 unmodified lines
866887
867888 brcmf_bus_detach(drvr);
868889
869− if (drvr->prot) {
890+ if (drvr->prot)
870891 brcmf_proto_detach(drvr);
871− }
872892
873893 brcmf_debugfs_detach(drvr);
874894 bus_if->drvr = NULL;
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c+5−19
@@ -14,8 +14,6 @@ · 13 unmodified lines
1414 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1515 */
1616
17−#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18−
1917 #include <linux/types.h>
2018 #include <linux/kernel.h>
2119 #include <linux/kthread.h>
@@ -1169,7 +1167,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) · 1147 unmodified lines
11691167 int errcode;
11701168 u8 doff, sfdoff;
11711169
1172− int ifidx = 0;
11731170 bool usechain = bus->use_rxchain;
11741171
11751172 struct brcmf_sdio_read rd_new;
@@ -1388,13 +1385,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) · 212 unmodified lines
13881385 skb_unlink(pfirst, &bus->glom);
13891386 brcmu_pkt_buf_free_skb(pfirst);
13901387 continue;
1391− } else if (brcmf_proto_hdrpull(bus->sdiodev->dev,
1392− &ifidx, pfirst) != 0) {
1393− brcmf_err("rx protocol error\n");
1394− bus->sdiodev->bus_if->dstats.rx_errors++;
1395− skb_unlink(pfirst, &bus->glom);
1396− brcmu_pkt_buf_free_skb(pfirst);
1397− continue;
13981388 }
13991389
14001390 brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
@@ -1407,7 +1397,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) · 6 unmodified lines
14071397 }
14081398 /* sent any remaining packets up */
14091399 if (bus->glom.qlen)
1410− brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom);
1400+ brcmf_rx_frames(bus->sdiodev->dev, &bus->glom);
14111401
14121402 bus->sdcnt.rxglomframes++;
14131403 bus->sdcnt.rxglompkts += bus->glom.qlen;
@@ -1558,10 +1548,10 @@ static void brcmf_pad(struct brcmf_sdio *bus, u16 *pad, u16 *rdlen) · 144 unmodified lines
15581548 static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
15591549 {
15601550 struct sk_buff *pkt; /* Packet for event or data frames */
1551+ struct sk_buff_head pktlist; /* needed for bus interface */
15611552 u16 pad; /* Number of pad bytes to read */
15621553 uint rxleft = 0; /* Remaining number of frames allowed */
15631554 int sdret; /* Return code from calls */
1564− int ifidx = 0;
15651555 uint rxcount = 0; /* Total frames read */
15661556 struct brcmf_sdio_read *rd = &bus->cur_read, rd_new;
15671557 u8 head_read = 0;
@@ -1760,15 +1750,11 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) · 192 unmodified lines
17601750 if (pkt->len == 0) {
17611751 brcmu_pkt_buf_free_skb(pkt);
17621752 continue;
1763− } else if (brcmf_proto_hdrpull(bus->sdiodev->dev, &ifidx,
1764− pkt) != 0) {
1765− brcmf_err("rx protocol error\n");
1766− brcmu_pkt_buf_free_skb(pkt);
1767− bus->sdiodev->bus_if->dstats.rx_errors++;
1768− continue;
17691753 }
17701754
1771− brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt);
1755+ skb_queue_head_init(&pktlist);
1756+ skb_queue_tail(&pktlist, pkt);
1757+ brcmf_rx_frames(bus->sdiodev->dev, &pktlist);
17721758 }
17731759
17741760 rxcount = maxframes - rxleft;
drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c+0−2
@@ -15,8 +15,6 @@ · 14 unmodified lines
1515 */
1616 /* ***** SDIO interface chip backplane handle functions ***** */
1717
18−#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19−
2018 #include <linux/types.h>
2119 #include <linux/netdevice.h>
2220 #include <linux/mmc/card.h>
drivers/net/wireless/brcm80211/brcmfmac/usb.c+19−8
@@ -443,14 +443,15 @@ static void brcmf_usb_rx_complete(struct urb *urb) · 442 unmodified lines
443443 struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context;
444444 struct brcmf_usbdev_info *devinfo = req->devinfo;
445445 struct sk_buff *skb;
446− int ifidx = 0;
446+ struct sk_buff_head skbq;
447447
448448 brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status);
449449 brcmf_usb_del_fromq(devinfo, req);
450450 skb = req->skb;
451451 req->skb = NULL;
452452
453− if (urb->status == 0) {
453+ /* zero lenght packets indicate usb "failure". Do not refill */
454+ if (urb->status == 0 && urb->actual_length) {
454455 devinfo->bus_pub.bus->dstats.rx_packets++;
455456 } else {
456457 devinfo->bus_pub.bus->dstats.rx_errors++;
@@ -460,13 +461,10 @@ static void brcmf_usb_rx_complete(struct urb *urb) · 3 unmodified lines
460461 }
461462
462463 if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) {
464+ skb_queue_head_init(&skbq);
465+ skb_queue_tail(&skbq, skb);
463466 skb_put(skb, urb->actual_length);
464− if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) {
465− brcmf_err("rx protocol error\n");
466− brcmu_pkt_buf_free_skb(skb);
467− devinfo->bus_pub.bus->dstats.rx_errors++;
468− } else
469− brcmf_rx_packet(devinfo->dev, ifidx, skb);
467+ brcmf_rx_frames(devinfo->dev, &skbq);
470468 brcmf_usb_rx_refill(devinfo, req);
471469 } else {
472470 brcmu_pkt_buf_free_skb(skb);
@@ -1520,10 +1518,23 @@ static void brcmf_release_fw(struct list_head *q) · 1047 unmodified lines
15201518 }
15211519 }
15221520
1521+static int brcmf_usb_reset_device(struct device *dev, void *notused)
1522+{
1523+ /* device past is the usb interface so we
1524+ * need to use parent here.
1525+ */
1526+ brcmf_dev_reset(dev->parent);
1527+ return 0;
1528+}
15231529
15241530 void brcmf_usb_exit(void)
15251531 {
1532+ struct device_driver *drv = &brcmf_usbdrvr.drvwrap.driver;
1533+ int ret;
1534+
15261535 brcmf_dbg(USB, "Enter\n");
1536+ ret = driver_for_each_device(drv, NULL, NULL,
1537+ brcmf_usb_reset_device);
15271538 usb_deregister(&brcmf_usbdrvr);
15281539 brcmf_release_fw(&fw_image_list);
15291540 }
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c+16−83
@@ -16,8 +16,6 @@ · 15 unmodified lines
1616
1717 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
1818
19−#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20−
2119 #include <linux/kernel.h>
2220 #include <linux/etherdevice.h>
2321 #include <net/cfg80211.h>
@@ -2011,67 +2009,6 @@ done: · 1987 unmodified lines
20112009 return err;
20122010 }
20132011
2014−static s32
2015−brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
2016− const u8 *addr,
2017− const struct cfg80211_bitrate_mask *mask)
2018−{
2019− struct brcmf_if *ifp = netdev_priv(ndev);
2020− struct brcm_rateset_le rateset_le;
2021− s32 rate;
2022− s32 val;
2023− s32 err_bg;
2024− s32 err_a;
2025− u32 legacy;
2026− s32 err = 0;
2027−
2028− brcmf_dbg(TRACE, "Enter\n");
2029− if (!check_vif_up(ifp->vif))
2030− return -EIO;
2031−
2032− /* addr param is always NULL. ignore it */
2033− /* Get current rateset */
2034− err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CURR_RATESET,
2035− &rateset_le, sizeof(rateset_le));
2036− if (err) {
2037− brcmf_err("could not get current rateset (%d)\n", err);
2038− goto done;
2039− }
2040−
2041− legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
2042− if (!legacy)
2043− legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
2044− 0xFFFF);
2045−
2046− val = wl_g_rates[legacy - 1].bitrate * 100000;
2047−
2048− if (val < le32_to_cpu(rateset_le.count))
2049− /* Select rate by rateset index */
2050− rate = rateset_le.rates[val] & 0x7f;
2051− else
2052− /* Specified rate in bps */
2053− rate = val / 500000;
2054−
2055− brcmf_dbg(CONN, "rate %d mbps\n", rate / 2);
2056−
2057− /*
2058− *
2059− * Set rate override,
2060− * Since the is a/b/g-blind, both a/bg_rate are enforced.
2061− */
2062− err_bg = brcmf_fil_iovar_int_set(ifp, "bg_rate", rate);
2063− err_a = brcmf_fil_iovar_int_set(ifp, "a_rate", rate);
2064− if (err_bg && err_a) {
2065− brcmf_err("could not set fixed rate (%d) (%d)\n", err_bg,
2066− err_a);
2067− err = err_bg | err_a;
2068− }
2069−
2070−done:
2071− brcmf_dbg(TRACE, "Exit\n");
2072− return err;
2073−}
2074−
20752012 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
20762013 struct brcmf_bss_info_le *bi)
20772014 {
@@ -3091,10 +3028,11 @@ brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, · 1013 unmodified lines
30913028
30923029 len = wpa_ie->len + TLV_HDR_LEN;
30933030 data = (u8 *)wpa_ie;
3094− offset = 0;
3031+ offset = TLV_HDR_LEN;
30953032 if (!is_rsn_ie)
30963033 offset += VS_IE_FIXED_HDR_LEN;
3097− offset += WPA_IE_VERSION_LEN;
3034+ else
3035+ offset += WPA_IE_VERSION_LEN;
30983036
30993037 /* check for multicast cipher suite */
31003038 if (offset + WPA_IE_MIN_OUI_LEN > len) {
@@ -3703,7 +3641,6 @@ static struct cfg80211_ops wl_cfg80211_ops = { · 602 unmodified lines
37033641 .set_default_key = brcmf_cfg80211_config_default_key,
37043642 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
37053643 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
3706− .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
37073644 .connect = brcmf_cfg80211_connect,
37083645 .disconnect = brcmf_cfg80211_disconnect,
37093646 .suspend = brcmf_cfg80211_suspend,
@@ -4329,9 +4266,8 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) · 619 unmodified lines
43294266 }
43304267
43314268 static s32
4332−brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
4269+brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
43334270 {
4334− struct brcmf_if *ifp = netdev_priv(ndev);
43354271 s32 err = 0;
43364272 __le32 roamtrigger[2];
43374273 __le32 roam_delta[2];
@@ -4382,10 +4318,9 @@ dongle_rom_out: · 44 unmodified lines
43824318 }
43834319
43844320 static s32
4385−brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
4321+brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
43864322 s32 scan_unassoc_time, s32 scan_passive_time)
43874323 {
4388− struct brcmf_if *ifp = netdev_priv(ndev);
43894324 s32 err = 0;
43904325
43914326 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
@@ -4455,6 +4390,7 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) · 63 unmodified lines
44554390 {
44564391 struct net_device *ndev;
44574392 struct wireless_dev *wdev;
4393+ struct brcmf_if *ifp;
44584394 s32 power_mode;
44594395 s32 err = 0;
44604396
@@ -4463,35 +4399,34 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) · 2 unmodified lines
44634399
44644400 ndev = cfg_to_ndev(cfg);
44654401 wdev = ndev->ieee80211_ptr;
4402+ ifp = netdev_priv(ndev);
44664403
4467− brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
4468− WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
4404+ /* make sure RF is ready for work */
4405+ brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
4406+
4407+ brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
4408+ WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
44694409
44704410 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
4471− err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM,
4472− power_mode);
4411+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
44734412 if (err)
44744413 goto default_conf_out;
44754414 brcmf_dbg(INFO, "power save set to %s\n",
44764415 (power_mode ? "enabled" : "disabled"));
44774416
4478− err = brcmf_dongle_roam(ndev, (cfg->roam_on ? 0 : 1),
4479− WL_BEACON_TIMEOUT);
4417+ err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
44804418 if (err)
44814419 goto default_conf_out;
44824420 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
44834421 NULL, NULL);
4484− if (err && err != -EINPROGRESS)
4422+ if (err)
44854423 goto default_conf_out;
44864424 err = brcmf_dongle_probecap(cfg);
44874425 if (err)
44884426 goto default_conf_out;
44894427
4490− /* -EINPROGRESS: Call commit handler */
4491−
4492−default_conf_out:
4493−
44944428 cfg->dongle_up = true;
4429+default_conf_out:
44954430
44964431 return err;
44974432
@@ -4500,8 +4435,6 @@ default_conf_out: · 2 unmodified lines
45004435 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
45014436 {
45024437 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
4503− if (ifp->idx)
4504− return 0;
45054438
45064439 return brcmf_config_dongle(ifp->drvr->config);
45074440 }
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c+2−5
@@ -961,7 +961,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, · 960 unmodified lines
961961 /* if acked then clear bit and free packet */
962962 if ((bindex < AMPDU_TX_BA_MAX_WSIZE)
963963 && isset(bitmap, bindex)) {
964− ini->tx_in_transit--;
965964 ini->txretry[index] = 0;
966965
967966 /*
@@ -990,7 +989,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, · 22 unmodified lines
990989 if (retry && (ini->txretry[index] < (int)retry_limit)) {
991990 int ret;
992991 ini->txretry[index]++;
993− ini->tx_in_transit--;
994992 ret = brcms_c_txfifo(wlc, queue, p);
995993 /*
996994 * We shouldn't be out of space in the DMA
@@ -1000,7 +998,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, · 3 unmodified lines
1000998 WARN_ONCE(ret, "queue %d out of txds\n", queue);
1001999 } else {
10021000 /* Retry timeout */
1003− ini->tx_in_transit--;
10041001 ieee80211_tx_info_clear_status(tx_info);
10051002 tx_info->status.ampdu_ack_len = 0;
10061003 tx_info->status.ampdu_len = 1;
@@ -1009,8 +1006,8 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, · 2 unmodified lines
10091006 skb_pull(p, D11_PHY_HDR_LEN);
10101007 skb_pull(p, D11_TXH_LEN);
10111008 brcms_dbg_ht(wlc->hw->d11core,
1012− "BA Timeout, seq %d, in_transit %d\n",
1013− seq, ini->tx_in_transit);
1009+ "BA Timeout, seq %d\n",
1010+ seq);
10141011 ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
10151012 p);
10161013 }
drivers/net/wireless/brcm80211/brcmsmac/debug.h+1−0
@@ -1,5 +1,6 @@
11 /*
22 * Copyright (c) 2012 Broadcom Corporation
3+ * Copyright (c) 2012 Canonical Ltd.
34 *
45 * Permission to use, copy, modify, and/or distribute this software for any
56 * purpose with or without fee is hereby granted, provided that the above
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c+7−3
@@ -362,8 +362,11 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) · 361 unmodified lines
362362 return -EOPNOTSUPP;
363363 }
364364
365+ spin_lock_bh(&wl->lock);
366+ memcpy(wl->pub->cur_etheraddr, vif->addr, sizeof(vif->addr));
365367 wl->mute_tx = false;
366368 brcms_c_mute(wl->wlc, false);
369+ spin_unlock_bh(&wl->lock);
367370
368371 return 0;
369372 }
@@ -1408,9 +1411,10 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic) · 1038 unmodified lines
14081411 #endif
14091412 t->ms = ms;
14101413 t->periodic = (bool) periodic;
1411− t->set = true;
1412−
1413− atomic_inc(&t->wl->callbacks);
1414+ if (!t->set) {
1415+ t->set = true;
1416+ atomic_inc(&t->wl->callbacks);
1417+ }
14141418
14151419 ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms));
14161420 }
drivers/net/wireless/brcm80211/brcmsmac/main.c+4−5
@@ -2473,6 +2473,7 @@ static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw, · 2472 unmodified lines
24732473 static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx)
24742474 {
24752475 static const u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
2476+ u8 *ethaddr = wlc_hw->wlc->pub->cur_etheraddr;
24762477
24772478 if (mute_tx) {
24782479 /* suspend tx fifos */
@@ -2482,8 +2483,7 @@ static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx) · 3 unmodified lines
24822483 brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO);
24832484
24842485 /* zero the address match register so we do not send ACKs */
2485− brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
2486− null_ether_addr);
2486+ brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, null_ether_addr);
24872487 } else {
24882488 /* resume tx fifos */
24892489 brcms_b_tx_fifo_resume(wlc_hw, TX_DATA_FIFO);
@@ -2492,8 +2492,7 @@ static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx) · 2 unmodified lines
24922492 brcms_b_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO);
24932493
24942494 /* Restore address */
2495− brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
2496− wlc_hw->etheraddr);
2495+ brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, ethaddr);
24972496 }
24982497
24992498 wlc_phy_mute_upd(wlc_hw->band->pi, mute_tx, 0);
@@ -7633,7 +7632,7 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) · 5133 unmodified lines
76337632
76347633 uint n = 0;
76357634 uint bound_limit = bound ? RXBND : -1;
7636− bool morepending;
7635+ bool morepending = false;
76377636
76387637 skb_queue_head_init(&recv_frames);
76397638
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c+2−2
@@ -1343,13 +1343,13 @@ static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain, · 1342 unmodified lines
13431343
13441344 wlc_lcnphy_rx_gain_override_enable(pi, true);
13451345 wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0);
1346− usleep_range(500, 500);
1346+ udelay(500);
13471347 write_radio_reg(pi, RADIO_2064_REG112, 0);
13481348 if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l))
13491349 return false;
13501350
13511351 wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0);
1352− usleep_range(500, 500);
1352+ udelay(500);
13531353 write_radio_reg(pi, RADIO_2064_REG112, 0);
13541354 if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h))
13551355 return false;
drivers/net/wireless/brcm80211/brcmsmac/scb.h+0−1
@@ -36,7 +36,6 @@ · 35 unmodified lines
3636
3737 /* structure to store per-tid state for the ampdu initiator */
3838 struct scb_ampdu_tid_ini {
39− u8 tx_in_transit; /* number of pending mpdus in transit in driver */
4039 u8 tid; /* initiator tid for easy lookup */
4140 /* tx retry count; indexed by seq modulo */
4241 u8 txretry[AMPDU_TX_BA_MAX_WSIZE];
drivers/net/wireless/iwlegacy/3945-mac.c+6−2
@@ -3273,7 +3273,7 @@ il3945_store_measurement(struct device *d, struct device_attribute *attr, · 3272 unmodified lines
32733273
32743274 if (count) {
32753275 char *p = buffer;
3276− strncpy(buffer, buf, min(sizeof(buffer), count));
3276+ strlcpy(buffer, buf, sizeof(buffer));
32773277 channel = simple_strtoul(p, NULL, 0);
32783278 if (channel)
32793279 params.channel = channel;
@@ -3474,6 +3474,7 @@ struct ieee80211_ops il3945_mac_ops = { · 194 unmodified lines
34743474 .sta_add = il3945_mac_sta_add,
34753475 .sta_remove = il_mac_sta_remove,
34763476 .tx_last_beacon = il_mac_tx_last_beacon,
3477+ .flush = il_mac_flush,
34773478 };
34783479
34793480 static int
@@ -3548,7 +3549,8 @@ il3945_setup_mac(struct il_priv *il) · 68 unmodified lines
35483549 hw->vif_data_size = sizeof(struct il_vif_priv);
35493550
35503551 /* Tell mac80211 our characteristics */
3551− hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SPECTRUM_MGMT;
3552+ hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SPECTRUM_MGMT |
3553+ IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
35523554
35533555 hw->wiphy->interface_modes =
35543556 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
@@ -3557,6 +3559,8 @@ il3945_setup_mac(struct il_priv *il) · 2 unmodified lines
35573559 WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS |
35583560 WIPHY_FLAG_IBSS_RSN;
35593561
3562+ hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
3563+
35603564 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;
35613565 /* we create the 802.11 header and a zero-length SSID element */
35623566 hw->wiphy->max_scan_ie_len = IL3945_MAX_PROBE_REQUEST - 24 - 2;
drivers/net/wireless/iwlegacy/4965-mac.c+4−2
@@ -5712,8 +5712,8 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length) · 5711 unmodified lines
57125712 hw->flags =
57135713 IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_AMPDU_AGGREGATION |
57145714 IEEE80211_HW_NEED_DTIM_PERIOD | IEEE80211_HW_SPECTRUM_MGMT |
5715− IEEE80211_HW_REPORTS_TX_ACK_STATUS;
5716−
5715+ IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SUPPORTS_PS |
5716+ IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
57175717 if (il->cfg->sku & IL_SKU_N)
57185718 hw->flags |=
57195719 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
@@ -6308,6 +6308,7 @@ const struct ieee80211_ops il4965_mac_ops = { · 588 unmodified lines
63086308 .sta_remove = il_mac_sta_remove,
63096309 .channel_switch = il4965_mac_channel_switch,
63106310 .tx_last_beacon = il_mac_tx_last_beacon,
6311+ .flush = il_mac_flush,
63116312 };
63126313
63136314 static int
@@ -6555,6 +6556,7 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 241 unmodified lines
65556556 il4965_prepare_card_hw(il);
65566557 if (!il->hw_ready) {
65576558 IL_WARN("Failed, HW not ready\n");
6559+ err = -EIO;
65586560 goto out_iounmap;
65596561 }
65606562
drivers/net/wireless/iwlegacy/common.c+50−21
@@ -3958,17 +3958,21 @@ il_connection_init_rx_config(struct il_priv *il) · 3957 unmodified lines
39583958
39593959 memset(&il->staging, 0, sizeof(il->staging));
39603960
3961− if (!il->vif) {
3961+ switch (il->iw_mode) {
3962+ case NL80211_IFTYPE_UNSPECIFIED:
39623963 il->staging.dev_type = RXON_DEV_TYPE_ESS;
3963− } else if (il->vif->type == NL80211_IFTYPE_STATION) {
3964+ break;
3965+ case NL80211_IFTYPE_STATION:
39643966 il->staging.dev_type = RXON_DEV_TYPE_ESS;
39653967 il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
3966− } else if (il->vif->type == NL80211_IFTYPE_ADHOC) {
3968+ break;
3969+ case NL80211_IFTYPE_ADHOC:
39673970 il->staging.dev_type = RXON_DEV_TYPE_IBSS;
39683971 il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
39693972 il->staging.filter_flags =
39703973 RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
3971− } else {
3974+ break;
3975+ default:
39723976 IL_ERR("Unsupported interface type %d\n", il->vif->type);
39733977 return;
39743978 }
@@ -4550,8 +4554,7 @@ out: · 575 unmodified lines
45504554 EXPORT_SYMBOL(il_mac_add_interface);
45514555
45524556 static void
4553−il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif,
4554− bool mode_change)
4557+il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif)
45554558 {
45564559 lockdep_assert_held(&il->mutex);
45574560
@@ -4560,9 +4563,7 @@ il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif, · 2 unmodified lines
45604563 il_force_scan_end(il);
45614564 }
45624565
4563− if (!mode_change)
4564− il_set_mode(il);
4565−
4566+ il_set_mode(il);
45664567 }
45674568
45684569 void
@@ -4575,8 +4576,8 @@ il_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) · 6 unmodified lines
45754576
45764577 WARN_ON(il->vif != vif);
45774578 il->vif = NULL;
4578−
4579− il_teardown_interface(il, vif, false);
4579+ il->iw_mode = NL80211_IFTYPE_UNSPECIFIED;
4580+ il_teardown_interface(il, vif);
45804581 memset(il->bssid, 0, ETH_ALEN);
45814582
45824583 D_MAC80211("leave\n");
@@ -4685,18 +4686,10 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, · 102 unmodified lines
46854686 }
46864687
46874688 /* success */
4688− il_teardown_interface(il, vif, true);
46894689 vif->type = newtype;
46904690 vif->p2p = false;
4691− err = il_set_mode(il);
4692− WARN_ON(err);
4693− /*
4694− * We've switched internally, but submitting to the
4695− * device may have failed for some reason. Mask this
4696− * error, because otherwise mac80211 will not switch
4697− * (and set the interface type back) and we'll be
4698− * out of sync with it.
4699− */
4691+ il->iw_mode = newtype;
4692+ il_teardown_interface(il, vif);
47004693 err = 0;
47014694
47024695 out:
@@ -4707,6 +4700,42 @@ out: · 4 unmodified lines
47074700 }
47084701 EXPORT_SYMBOL(il_mac_change_interface);
47094702
4703+void
4704+il_mac_flush(struct ieee80211_hw *hw, bool drop)
4705+{
4706+ struct il_priv *il = hw->priv;
4707+ unsigned long timeout = jiffies + msecs_to_jiffies(500);
4708+ int i;
4709+
4710+ mutex_lock(&il->mutex);
4711+ D_MAC80211("enter\n");
4712+
4713+ if (il->txq == NULL)
4714+ goto out;
4715+
4716+ for (i = 0; i < il->hw_params.max_txq_num; i++) {
4717+ struct il_queue *q;
4718+
4719+ if (i == il->cmd_queue)
4720+ continue;
4721+
4722+ q = &il->txq[i].q;
4723+ if (q->read_ptr == q->write_ptr)
4724+ continue;
4725+
4726+ if (time_after(jiffies, timeout)) {
4727+ IL_ERR("Failed to flush queue %d\n", q->id);
4728+ break;
4729+ }
4730+
4731+ msleep(20);
4732+ }
4733+out:
4734+ D_MAC80211("leave\n");
4735+ mutex_unlock(&il->mutex);
4736+}
4737+EXPORT_SYMBOL(il_mac_flush);
4738+
47104739 /*
47114740 * On every watchdog tick we check (latest) time stamp. If it does not
47124741 * change during timeout period and queue is not empty we reset firmware.
drivers/net/wireless/iwlegacy/common.h+1−0
@@ -1723,6 +1723,7 @@ void il_mac_remove_interface(struct ieee80211_hw *hw, · 1722 unmodified lines
17231723 struct ieee80211_vif *vif);
17241724 int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
17251725 enum nl80211_iftype newtype, bool newp2p);
1726+void il_mac_flush(struct ieee80211_hw *hw, bool drop);
17261727 int il_alloc_txq_mem(struct il_priv *il);
17271728 void il_free_txq_mem(struct il_priv *il);
17281729
drivers/net/wireless/iwlwifi/dvm/commands.h+4−4
@@ -3695,7 +3695,7 @@ struct iwl_bt_uart_msg { · 3694 unmodified lines
36953695 u8 frame5;
36963696 u8 frame6;
36973697 u8 frame7;
3698−} __attribute__((packed));
3698+} __packed;
36993699
37003700 struct iwl_bt_coex_profile_notif {
37013701 struct iwl_bt_uart_msg last_bt_uart_msg;
@@ -3703,7 +3703,7 @@ struct iwl_bt_coex_profile_notif { · 1 unmodified line
37033703 u8 bt_traffic_load; /* 0 .. 3? */
37043704 u8 bt_ci_compliance; /* 0 - not complied, 1 - complied */
37053705 u8 reserved;
3706−} __attribute__((packed));
3706+} __packed;
37073707
37083708 #define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS 0
37093709 #define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_MSK 0x1
@@ -3752,7 +3752,7 @@ enum bt_coex_prio_table_priorities { · 42 unmodified lines
37523752
37533753 struct iwl_bt_coex_prio_table_cmd {
37543754 u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX];
3755−} __attribute__((packed));
3755+} __packed;
37563756
37573757 #define IWL_BT_COEX_ENV_CLOSE 0
37583758 #define IWL_BT_COEX_ENV_OPEN 1
@@ -3764,7 +3764,7 @@ struct iwl_bt_coex_prot_env_cmd { · 5 unmodified lines
37643764 u8 action; /* 0 = closed, 1 = open */
37653765 u8 type; /* 0 .. 15 */
37663766 u8 reserved[2];
3767−} __attribute__((packed));
3767+} __packed;
37683768
37693769 /*
37703770 * REPLY_D3_CONFIG
drivers/net/wireless/iwlwifi/dvm/debugfs.c+2−2
@@ -157,7 +157,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, · 156 unmodified lines
157157 sram = priv->dbgfs_sram_offset & ~0x3;
158158
159159 /* read the first u32 from sram */
160− val = iwl_read_targ_mem(priv->trans, sram);
160+ val = iwl_trans_read_mem32(priv->trans, sram);
161161
162162 for (; len; len--) {
163163 /* put the address at the start of every line */
@@ -176,7 +176,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, · 12 unmodified lines
176176 if (++offset == 4) {
177177 sram += 4;
178178 offset = 0;
179− val = iwl_read_targ_mem(priv->trans, sram);
179+ val = iwl_trans_read_mem32(priv->trans, sram);
180180 }
181181
182182 /* put in extra spaces and split lines for human readability */
drivers/net/wireless/iwlwifi/dvm/led.c+1−1
@@ -69,7 +69,7 @@ static const struct ieee80211_tpt_blink iwl_blink[] = { · 68 unmodified lines
6969 /* Set led register off */
7070 void iwlagn_led_enable(struct iwl_priv *priv)
7171 {
72− iwl_write32(priv->trans, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
72+ iwl_write32(priv->trans, CSR_LED_REG, CSR_LED_REG_TURN_ON);
7373 }
7474
7575 /*
drivers/net/wireless/iwlwifi/dvm/mac80211.c+7−9
@@ -206,7 +206,8 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, · 205 unmodified lines
206206
207207 #ifdef CONFIG_PM_SLEEP
208208 if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
209− priv->trans->ops->wowlan_suspend &&
209+ priv->trans->ops->d3_suspend &&
210+ priv->trans->ops->d3_resume &&
210211 device_can_wakeup(priv->trans->dev)) {
211212 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
212213 WIPHY_WOWLAN_DISCONNECT |
@@ -426,7 +427,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, · 213 unmodified lines
426427 if (ret)
427428 goto error;
428429
429− iwl_trans_wowlan_suspend(priv->trans);
430+ iwl_trans_d3_suspend(priv->trans);
430431
431432 goto out;
432433
@@ -459,11 +460,11 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) · 26 unmodified lines
459460 base = priv->device_pointers.error_event_table;
460461 if (iwlagn_hw_valid_rtc_data_addr(base)) {
461462 spin_lock_irqsave(&priv->trans->reg_lock, flags);
462− ret = iwl_grab_nic_access_silent(priv->trans);
463− if (likely(ret == 0)) {
463+ if (iwl_trans_grab_nic_access(priv->trans, true)) {
464464 iwl_write32(priv->trans, HBUS_TARG_MEM_RADDR, base);
465465 status = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT);
466− iwl_release_nic_access(priv->trans);
466+ iwl_trans_release_nic_access(priv->trans);
467+ ret = 0;
467468 }
468469 spin_unlock_irqrestore(&priv->trans->reg_lock, flags);
469470
@@ -479,7 +480,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) · 9 unmodified lines
479480 }
480481
481482 if (priv->wowlan_sram)
482− _iwl_read_targ_mem_dwords(
483+ iwl_trans_read_mem(
483484 priv->trans, 0x800000,
484485 priv->wowlan_sram,
485486 img->sec[IWL_UCODE_SECTION_DATA].len / 4);
@@ -520,9 +521,6 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw, · 34 unmodified lines
520521 {
521522 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
522523
523− IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
524− ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
525−
526524 if (iwlagn_tx_skb(priv, control->sta, skb))
527525 ieee80211_free_txskb(hw, skb);
528526 }
drivers/net/wireless/iwlwifi/dvm/main.c+11−10
@@ -354,7 +354,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, · 353 unmodified lines
354354
355355 /* Make sure device is powered up for SRAM reads */
356356 spin_lock_irqsave(&priv->trans->reg_lock, reg_flags);
357− if (unlikely(!iwl_grab_nic_access(priv->trans))) {
357+ if (!iwl_trans_grab_nic_access(priv->trans, false)) {
358358 spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags);
359359 return;
360360 }
@@ -388,7 +388,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, · 27 unmodified lines
388388 }
389389 }
390390 /* Allow device to power down */
391− iwl_release_nic_access(priv->trans);
391+ iwl_trans_release_nic_access(priv->trans);
392392 spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags);
393393 }
394394
@@ -408,7 +408,8 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv) · 13 unmodified lines
408408
409409 base = priv->device_pointers.log_event_table;
410410 if (iwlagn_hw_valid_rtc_data_addr(base)) {
411− iwl_read_targ_mem_bytes(priv->trans, base, &read, sizeof(read));
411+ iwl_trans_read_mem_bytes(priv->trans, base,
412+ &read, sizeof(read));
412413 capacity = read.capacity;
413414 mode = read.mode;
414415 num_wraps = read.wrap_counter;
@@ -1627,7 +1628,7 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv) · 1212 unmodified lines
16271628 }
16281629
16291630 /*TODO: Update dbgfs with ISR error stats obtained below */
1630− iwl_read_targ_mem_bytes(trans, base, &table, sizeof(table));
1631+ iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table));
16311632
16321633 if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
16331634 IWL_ERR(trans, "Start IWL Error Log Dump:\n");
@@ -1717,7 +1718,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, · 83 unmodified lines
17171718
17181719 /* Make sure device is powered up for SRAM reads */
17191720 spin_lock_irqsave(&trans->reg_lock, reg_flags);
1720− if (unlikely(!iwl_grab_nic_access(trans)))
1721+ if (!iwl_trans_grab_nic_access(trans, false))
17211722 goto out_unlock;
17221723
17231724 /* Set starting address; reads will auto-increment */
@@ -1756,7 +1757,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, · 32 unmodified lines
17561757 }
17571758
17581759 /* Allow device to power down */
1759− iwl_release_nic_access(trans);
1760+ iwl_trans_release_nic_access(trans);
17601761 out_unlock:
17611762 spin_unlock_irqrestore(&trans->reg_lock, reg_flags);
17621763 return pos;
@@ -1835,10 +1836,10 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, · 72 unmodified lines
18351836 }
18361837
18371838 /* event log header */
1838− capacity = iwl_read_targ_mem(trans, base);
1839− mode = iwl_read_targ_mem(trans, base + (1 * sizeof(u32)));
1840− num_wraps = iwl_read_targ_mem(trans, base + (2 * sizeof(u32)));
1841− next_entry = iwl_read_targ_mem(trans, base + (3 * sizeof(u32)));
1839+ capacity = iwl_trans_read_mem32(trans, base);
1840+ mode = iwl_trans_read_mem32(trans, base + (1 * sizeof(u32)));
1841+ num_wraps = iwl_trans_read_mem32(trans, base + (2 * sizeof(u32)));
1842+ next_entry = iwl_trans_read_mem32(trans, base + (3 * sizeof(u32)));
18421843
18431844 if (capacity > logsize) {
18441845 IWL_ERR(priv, "Log capacity %d is bogus, limit to %d "
drivers/net/wireless/iwlwifi/dvm/tt.c+2−2
@@ -186,8 +186,8 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) · 185 unmodified lines
186186 }
187187 iwl_read32(priv->trans, CSR_UCODE_DRV_GP1);
188188 spin_lock_irqsave(&priv->trans->reg_lock, flags);
189− if (likely(iwl_grab_nic_access(priv->trans)))
190− iwl_release_nic_access(priv->trans);
189+ if (iwl_trans_grab_nic_access(priv->trans, false))
190+ iwl_trans_release_nic_access(priv->trans);
191191 spin_unlock_irqrestore(&priv->trans->reg_lock, flags);
192192
193193 /* Reschedule the ct_kill timer to occur in
drivers/net/wireless/iwlwifi/dvm/tx.c+45−30
@@ -231,13 +231,11 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, · 230 unmodified lines
231231 memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
232232 if (info->flags & IEEE80211_TX_CTL_AMPDU)
233233 tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK;
234− IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
235234 break;
236235
237236 case WLAN_CIPHER_SUITE_TKIP:
238237 tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
239238 ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key);
240− IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
241239 break;
242240
243241 case WLAN_CIPHER_SUITE_WEP104:
@@ -355,8 +353,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, · 111 unmodified lines
355353 }
356354 }
357355
358− IWL_DEBUG_TX(priv, "station Id %d\n", sta_id);
359−
360356 if (sta)
361357 sta_priv = (void *)sta->drv_priv;
362358
@@ -472,6 +468,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, · 109 unmodified lines
472468 WARN_ON_ONCE(is_agg &&
473469 priv->queue_to_mac80211[txq_id] != info->hw_queue);
474470
471+ IWL_DEBUG_TX(priv, "TX to [%d|%d] Q:%d - seq: 0x%x\n", sta_id, tid,
472+ txq_id, seq_number);
473+
475474 if (iwl_trans_tx(priv->trans, skb, dev_cmd, txq_id))
476475 goto drop_unlock_sta;
477476
@@ -541,9 +540,9 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, · 63 unmodified lines
541540 spin_lock_bh(&priv->sta_lock);
542541
543542 tid_data = &priv->tid_data[sta_id][tid];
544− txq_id = priv->tid_data[sta_id][tid].agg.txq_id;
543+ txq_id = tid_data->agg.txq_id;
545544
546− switch (priv->tid_data[sta_id][tid].agg.state) {
545+ switch (tid_data->agg.state) {
547546 case IWL_EMPTYING_HW_QUEUE_ADDBA:
548547 /*
549548 * This can happen if the peer stops aggregation
@@ -563,9 +562,9 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, · 13 unmodified lines
563562 case IWL_AGG_ON:
564563 break;
565564 default:
566− IWL_WARN(priv, "Stopping AGG while state not ON "
567− "or starting for %d on %d (%d)\n", sta_id, tid,
568− priv->tid_data[sta_id][tid].agg.state);
565+ IWL_WARN(priv,
566+ "Stopping AGG while state not ON or starting for %d on %d (%d)\n",
567+ sta_id, tid, tid_data->agg.state);
569568 spin_unlock_bh(&priv->sta_lock);
570569 return 0;
571570 }
@@ -578,12 +577,11 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, · 6 unmodified lines
578577 "stopping AGG on STA/TID %d/%d but hwq %d not used\n",
579578 sta_id, tid, txq_id);
580579 } else if (tid_data->agg.ssn != tid_data->next_reclaimed) {
581− IWL_DEBUG_TX_QUEUES(priv, "Can't proceed: ssn %d, "
582− "next_recl = %d\n",
580+ IWL_DEBUG_TX_QUEUES(priv,
581+ "Can't proceed: ssn %d, next_recl = %d\n",
583582 tid_data->agg.ssn,
584583 tid_data->next_reclaimed);
585− priv->tid_data[sta_id][tid].agg.state =
586− IWL_EMPTYING_HW_QUEUE_DELBA;
584+ tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_DELBA;
587585 spin_unlock_bh(&priv->sta_lock);
588586 return 0;
589587 }
@@ -591,8 +589,8 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, · 1 unmodified line
591589 IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n",
592590 tid_data->agg.ssn);
593591 turn_off:
594− agg_state = priv->tid_data[sta_id][tid].agg.state;
595− priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF;
592+ agg_state = tid_data->agg.state;
593+ tid_data->agg.state = IWL_AGG_OFF;
596594
597595 spin_unlock_bh(&priv->sta_lock);
598596
@@ -954,12 +952,6 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv, · 355 unmodified lines
954952 if (status & (AGG_TX_STATE_FEW_BYTES_MSK |
955953 AGG_TX_STATE_ABORT_MSK))
956954 continue;
957−
958− IWL_DEBUG_TX_REPLY(priv, "status %s (0x%08x), "
959− "try-count (0x%08x)\n",
960− iwl_get_agg_tx_fail_reason(fstatus),
961− fstatus & AGG_TX_STATUS_MSK,
962− fstatus & AGG_TX_TRY_MSK);
963955 }
964956 }
965957
@@ -1079,6 +1071,8 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv, · 113 unmodified lines
10791071 {
10801072 u16 status = le16_to_cpu(tx_resp->status.status);
10811073
1074+ info->flags &= ~IEEE80211_TX_CTL_AMPDU;
1075+
10821076 info->status.rates[0].count = tx_resp->failure_frame + 1;
10831077 info->flags |= iwl_tx_status_to_mac80211(status);
10841078 iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
@@ -1151,13 +1145,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, · 66 unmodified lines
11511145 next_reclaimed = ssn;
11521146 }
11531147
1154− if (tid != IWL_TID_NON_QOS) {
1155− priv->tid_data[sta_id][tid].next_reclaimed =
1156− next_reclaimed;
1157− IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n",
1158− next_reclaimed);
1159− }
1160−
11611148 iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs);
11621149
11631150 iwlagn_check_ratid_empty(priv, sta_id, tid);
@@ -1208,21 +1195,49 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, · 44 unmodified lines
12081195 if (!is_agg)
12091196 iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1);
12101197
1198+ /*
1199+ * W/A for FW bug - the seq_ctl isn't updated when the
1200+ * queues are flushed. Fetch it from the packet itself
1201+ */
1202+ if (!is_agg && status == TX_STATUS_FAIL_FIFO_FLUSHED) {
1203+ next_reclaimed = le16_to_cpu(hdr->seq_ctrl);
1204+ next_reclaimed =
1205+ SEQ_TO_SN(next_reclaimed + 0x10);
1206+ }
1207+
12111208 is_offchannel_skb =
12121209 (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN);
12131210 freed++;
12141211 }
12151212
1216− WARN_ON(!is_agg && freed != 1);
1213+ if (tid != IWL_TID_NON_QOS) {
1214+ priv->tid_data[sta_id][tid].next_reclaimed =
1215+ next_reclaimed;
1216+ IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n",
1217+ next_reclaimed);
1218+ }
1219+
1220+ if (!is_agg && freed != 1)
1221+ IWL_ERR(priv, "Q: %d, freed %d\n", txq_id, freed);
12171222
12181223 /*
12191224 * An offchannel frame can be send only on the AUX queue, where
12201225 * there is no aggregation (and reordering) so it only is single
12211226 * skb is expected to be processed.
12221227 */
1223− WARN_ON(is_offchannel_skb && freed != 1);
1228+ if (is_offchannel_skb && freed != 1)
1229+ IWL_ERR(priv, "OFFCHANNEL SKB freed %d\n", freed);
12241230 }
12251231
1232+ IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x)\n", txq_id,
1233+ iwl_get_tx_fail_reason(status), status);
1234+
1235+ IWL_DEBUG_TX_REPLY(priv,
1236+ "\t\t\t\tinitial_rate 0x%x retries %d, idx=%d ssn=%d seq_ctl=0x%x\n",
1237+ le32_to_cpu(tx_resp->rate_n_flags),
1238+ tx_resp->failure_frame, SEQ_TO_INDEX(sequence), ssn,
1239+ le16_to_cpu(tx_resp->seq_ctl));
1240+
12261241 iwl_check_abort_status(priv, tx_resp->frame_count, status);
12271242 spin_unlock(&priv->sta_lock);
12281243
drivers/net/wireless/iwlwifi/dvm/ucode.c+1−95
@@ -286,89 +286,6 @@ static int iwl_alive_notify(struct iwl_priv *priv) · 285 unmodified lines
286286 return iwl_send_calib_results(priv);
287287 }
288288
289−
290−/**
291− * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host,
292− * using sample data 100 bytes apart. If these sample points are good,
293− * it's a pretty good bet that everything between them is good, too.
294− */
295−static int iwl_verify_sec_sparse(struct iwl_priv *priv,
296− const struct fw_desc *fw_desc)
297−{
298− __le32 *image = (__le32 *)fw_desc->data;
299− u32 len = fw_desc->len;
300− u32 val;
301− u32 i;
302−
303− IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len);
304−
305− for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
306− /* read data comes through single port, auto-incr addr */
307− /* NOTE: Use the debugless read so we don't flood kernel log
308− * if IWL_DL_IO is set */
309− iwl_write_direct32(priv->trans, HBUS_TARG_MEM_RADDR,
310− i + fw_desc->offset);
311− val = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT);
312− if (val != le32_to_cpu(*image))
313− return -EIO;
314− }
315−
316− return 0;
317−}
318−
319−static void iwl_print_mismatch_sec(struct iwl_priv *priv,
320− const struct fw_desc *fw_desc)
321−{
322− __le32 *image = (__le32 *)fw_desc->data;
323− u32 len = fw_desc->len;
324− u32 val;
325− u32 offs;
326− int errors = 0;
327−
328− IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len);
329−
330− iwl_write_direct32(priv->trans, HBUS_TARG_MEM_RADDR,
331− fw_desc->offset);
332−
333− for (offs = 0;
334− offs < len && errors < 20;
335− offs += sizeof(u32), image++) {
336− /* read data comes through single port, auto-incr addr */
337− val = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT);
338− if (val != le32_to_cpu(*image)) {
339− IWL_ERR(priv, "uCode INST section at "
340− "offset 0x%x, is 0x%x, s/b 0x%x\n",
341− offs, val, le32_to_cpu(*image));
342− errors++;
343− }
344− }
345−}
346−
347−/**
348− * iwl_verify_ucode - determine which instruction image is in SRAM,
349− * and verify its contents
350− */
351−static int iwl_verify_ucode(struct iwl_priv *priv,
352− enum iwl_ucode_type ucode_type)
353−{
354− const struct fw_img *img = iwl_get_ucode_image(priv, ucode_type);
355−
356− if (!img) {
357− IWL_ERR(priv, "Invalid ucode requested (%d)\n", ucode_type);
358− return -EINVAL;
359− }
360−
361− if (!iwl_verify_sec_sparse(priv, &img->sec[IWL_UCODE_SECTION_INST])) {
362− IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n");
363− return 0;
364− }
365−
366− IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n");
367−
368− iwl_print_mismatch_sec(priv, &img->sec[IWL_UCODE_SECTION_INST]);
369− return -EIO;
370−}
371−
372289 struct iwl_alive_data {
373290 bool valid;
374291 u8 subtype;
@@ -426,7 +343,7 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, · 51 unmodified lines
426343 alive_cmd, ARRAY_SIZE(alive_cmd),
427344 iwl_alive_fn, &alive_data);
428345
429− ret = iwl_trans_start_fw(priv->trans, fw);
346+ ret = iwl_trans_start_fw(priv->trans, fw, false);
430347 if (ret) {
431348 priv->cur_ucode = old_type;
432349 iwl_remove_notification(&priv->notif_wait, &alive_wait);
@@ -450,18 +367,7 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, · 17 unmodified lines
450367 return -EIO;
451368 }
452369
453− /*
454− * This step takes a long time (60-80ms!!) and
455− * WoWLAN image should be loaded quickly, so
456− * skip it for WoWLAN.
457− */
458370 if (ucode_type != IWL_UCODE_WOWLAN) {
459− ret = iwl_verify_ucode(priv, ucode_type);
460− if (ret) {
461− priv->cur_ucode = old_type;
462− return ret;
463− }
464−
465371 /* delay a bit to give rfkill time to run */
466372 msleep(5);
467373 }
drivers/net/wireless/iwlwifi/iwl-csr.h+2−2
@@ -381,8 +381,8 @@ · 380 unmodified lines
381381
382382 /* LED */
383383 #define CSR_LED_BSM_CTRL_MSK (0xFFFFFFDF)
384−#define CSR_LED_REG_TRUN_ON (0x78)
385−#define CSR_LED_REG_TRUN_OFF (0x38)
384+#define CSR_LED_REG_TURN_ON (0x60)
385+#define CSR_LED_REG_TURN_OFF (0x20)
386386
387387 /* ANA_PLL */
388388 #define CSR50_ANA_PLL_CFG_VAL (0x00880300)
drivers/net/wireless/iwlwifi/iwl-fh.h+4−0
@@ -225,6 +225,8 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) · 224 unmodified lines
225225 #define FH_RSCSR_CHNL0_RBDCB_WPTR_REG (FH_MEM_RSCSR_CHNL0 + 0x008)
226226 #define FH_RSCSR_CHNL0_WPTR (FH_RSCSR_CHNL0_RBDCB_WPTR_REG)
227227
228+#define FW_RSCSR_CHNL0_RXDCB_RDPTR_REG (FH_MEM_RSCSR_CHNL0 + 0x00c)
229+#define FH_RSCSR_CHNL0_RDPTR FW_RSCSR_CHNL0_RXDCB_RDPTR_REG
228230
229231 /**
230232 * Rx Config/Status Registers (RCSR)
@@ -257,6 +259,8 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) · 26 unmodified lines
257259 #define FH_MEM_RCSR_CHNL0 (FH_MEM_RCSR_LOWER_BOUND)
258260
259261 #define FH_MEM_RCSR_CHNL0_CONFIG_REG (FH_MEM_RCSR_CHNL0)
262+#define FH_MEM_RCSR_CHNL0_RBDCB_WPTR (FH_MEM_RCSR_CHNL0 + 0x8)
263+#define FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ (FH_MEM_RCSR_CHNL0 + 0x10)
260264
261265 #define FH_RCSR_CHNL0_RX_CONFIG_RB_TIMEOUT_MSK (0x00000FF0) /* bits 4-11 */
262266 #define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_MSK (0x00001000) /* bits 12 */
drivers/net/wireless/iwlwifi/iwl-io.c+22−146
@@ -35,12 +35,12 @@ · 34 unmodified lines
3535
3636 #define IWL_POLL_INTERVAL 10 /* microseconds */
3737
38−static inline void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask)
38+void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask)
3939 {
4040 iwl_write32(trans, reg, iwl_read32(trans, reg) | mask);
4141 }
4242
43−static inline void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask)
43+void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask)
4444 {
4545 iwl_write32(trans, reg, iwl_read32(trans, reg) & ~mask);
4646 }
@@ -99,86 +99,16 @@ int iwl_poll_bit(struct iwl_trans *trans, u32 addr, · 52 unmodified lines
9999 }
100100 EXPORT_SYMBOL_GPL(iwl_poll_bit);
101101
102−int iwl_grab_nic_access_silent(struct iwl_trans *trans)
103−{
104− int ret;
105−
106− lockdep_assert_held(&trans->reg_lock);
107−
108− /* this bit wakes up the NIC */
109− __iwl_set_bit(trans, CSR_GP_CNTRL,
110− CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
111−
112− /*
113− * These bits say the device is running, and should keep running for
114− * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
115− * but they do not indicate that embedded SRAM is restored yet;
116− * 3945 and 4965 have volatile SRAM, and must save/restore contents
117− * to/from host DRAM when sleeping/waking for power-saving.
118− * Each direction takes approximately 1/4 millisecond; with this
119− * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
120− * series of register accesses are expected (e.g. reading Event Log),
121− * to keep device from sleeping.
122− *
123− * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
124− * SRAM is okay/restored. We don't check that here because this call
125− * is just for hardware register access; but GP1 MAC_SLEEP check is a
126− * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
127− *
128− * 5000 series and later (including 1000 series) have non-volatile SRAM,
129− * and do not save/restore SRAM when power cycling.
130− */
131− ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
132− CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
133− (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
134− CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
135− if (ret < 0) {
136− iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
137− return -EIO;
138− }
139−
140− return 0;
141−}
142−EXPORT_SYMBOL_GPL(iwl_grab_nic_access_silent);
143−
144−bool iwl_grab_nic_access(struct iwl_trans *trans)
145−{
146− int ret = iwl_grab_nic_access_silent(trans);
147− if (unlikely(ret)) {
148− u32 val = iwl_read32(trans, CSR_GP_CNTRL);
149− WARN_ONCE(1, "Timeout waiting for hardware access "
150− "(CSR_GP_CNTRL 0x%08x)\n", val);
151− return false;
152− }
153−
154− return true;
155−}
156−EXPORT_SYMBOL_GPL(iwl_grab_nic_access);
157−
158−void iwl_release_nic_access(struct iwl_trans *trans)
159−{
160− lockdep_assert_held(&trans->reg_lock);
161− __iwl_clear_bit(trans, CSR_GP_CNTRL,
162− CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
163− /*
164− * Above we read the CSR_GP_CNTRL register, which will flush
165− * any previous writes, but we need the write that clears the
166− * MAC_ACCESS_REQ bit to be performed before any other writes
167− * scheduled on different CPUs (after we drop reg_lock).
168− */
169− mmiowb();
170−}
171−EXPORT_SYMBOL_GPL(iwl_release_nic_access);
172−
173102 u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
174103 {
175− u32 value;
104+ u32 value = 0x5a5a5a5a;
176105 unsigned long flags;
177106
178107 spin_lock_irqsave(&trans->reg_lock, flags);
179− iwl_grab_nic_access(trans);
180− value = iwl_read32(trans, reg);
181− iwl_release_nic_access(trans);
108+ if (iwl_trans_grab_nic_access(trans, false)) {
109+ value = iwl_read32(trans, reg);
110+ iwl_trans_release_nic_access(trans);
111+ }
182112 spin_unlock_irqrestore(&trans->reg_lock, flags);
183113
184114 return value;
@@ -190,9 +120,9 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) · 5 unmodified lines
190120 unsigned long flags;
191121
192122 spin_lock_irqsave(&trans->reg_lock, flags);
193− if (likely(iwl_grab_nic_access(trans))) {
123+ if (iwl_trans_grab_nic_access(trans, false)) {
194124 iwl_write32(trans, reg, value);
195− iwl_release_nic_access(trans);
125+ iwl_trans_release_nic_access(trans);
196126 }
197127 spin_unlock_irqrestore(&trans->reg_lock, flags);
198128 }
@@ -230,12 +160,13 @@ static inline void __iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) · 31 unmodified lines
230160 u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs)
231161 {
232162 unsigned long flags;
233− u32 val;
163+ u32 val = 0x5a5a5a5a;
234164
235165 spin_lock_irqsave(&trans->reg_lock, flags);
236− iwl_grab_nic_access(trans);
237− val = __iwl_read_prph(trans, ofs);
238− iwl_release_nic_access(trans);
166+ if (iwl_trans_grab_nic_access(trans, false)) {
167+ val = __iwl_read_prph(trans, ofs);
168+ iwl_trans_release_nic_access(trans);
169+ }
239170 spin_unlock_irqrestore(&trans->reg_lock, flags);
240171 return val;
241172 }
@@ -246,9 +177,9 @@ void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) · 4 unmodified lines
246177 unsigned long flags;
247178
248179 spin_lock_irqsave(&trans->reg_lock, flags);
249− if (likely(iwl_grab_nic_access(trans))) {
180+ if (iwl_trans_grab_nic_access(trans, false)) {
250181 __iwl_write_prph(trans, ofs, val);
251− iwl_release_nic_access(trans);
182+ iwl_trans_release_nic_access(trans);
252183 }
253184 spin_unlock_irqrestore(&trans->reg_lock, flags);
254185 }
@@ -259,10 +190,10 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) · 4 unmodified lines
259190 unsigned long flags;
260191
261192 spin_lock_irqsave(&trans->reg_lock, flags);
262− if (likely(iwl_grab_nic_access(trans))) {
193+ if (iwl_trans_grab_nic_access(trans, false)) {
263194 __iwl_write_prph(trans, ofs,
264195 __iwl_read_prph(trans, ofs) | mask);
265− iwl_release_nic_access(trans);
196+ iwl_trans_release_nic_access(trans);
266197 }
267198 spin_unlock_irqrestore(&trans->reg_lock, flags);
268199 }
@@ -274,10 +205,10 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, · 5 unmodified lines
274205 unsigned long flags;
275206
276207 spin_lock_irqsave(&trans->reg_lock, flags);
277− if (likely(iwl_grab_nic_access(trans))) {
208+ if (iwl_trans_grab_nic_access(trans, false)) {
278209 __iwl_write_prph(trans, ofs,
279210 (__iwl_read_prph(trans, ofs) & mask) | bits);
280− iwl_release_nic_access(trans);
211+ iwl_trans_release_nic_access(trans);
281212 }
282213 spin_unlock_irqrestore(&trans->reg_lock, flags);
283214 }
@@ -289,66 +220,11 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) · 5 unmodified lines
289220 u32 val;
290221
291222 spin_lock_irqsave(&trans->reg_lock, flags);
292− if (likely(iwl_grab_nic_access(trans))) {
223+ if (iwl_trans_grab_nic_access(trans, false)) {
293224 val = __iwl_read_prph(trans, ofs);
294225 __iwl_write_prph(trans, ofs, (val & ~mask));
295− iwl_release_nic_access(trans);
226+ iwl_trans_release_nic_access(trans);
296227 }
297228 spin_unlock_irqrestore(&trans->reg_lock, flags);
298229 }
299230 EXPORT_SYMBOL_GPL(iwl_clear_bits_prph);
300−
301−void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr,
302− void *buf, int dwords)
303−{
304− unsigned long flags;
305− int offs;
306− u32 *vals = buf;
307−
308− spin_lock_irqsave(&trans->reg_lock, flags);
309− if (likely(iwl_grab_nic_access(trans))) {
310− iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr);
311− for (offs = 0; offs < dwords; offs++)
312− vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
313− iwl_release_nic_access(trans);
314− }
315− spin_unlock_irqrestore(&trans->reg_lock, flags);
316−}
317−EXPORT_SYMBOL_GPL(_iwl_read_targ_mem_dwords);
318−
319−u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr)
320−{
321− u32 value;
322−
323− _iwl_read_targ_mem_dwords(trans, addr, &value, 1);
324−
325− return value;
326−}
327−EXPORT_SYMBOL_GPL(iwl_read_targ_mem);
328−
329−int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr,
330− const void *buf, int dwords)
331−{
332− unsigned long flags;
333− int offs, result = 0;
334− const u32 *vals = buf;
335−
336− spin_lock_irqsave(&trans->reg_lock, flags);
337− if (likely(iwl_grab_nic_access(trans))) {
338− iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
339− for (offs = 0; offs < dwords; offs++)
340− iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]);
341− iwl_release_nic_access(trans);
342− } else
343− result = -EBUSY;
344− spin_unlock_irqrestore(&trans->reg_lock, flags);
345−
346− return result;
347−}
348−EXPORT_SYMBOL_GPL(_iwl_write_targ_mem_dwords);
349−
350−int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val)
351−{
352− return _iwl_write_targ_mem_dwords(trans, addr, &val, 1);
353−}
354−EXPORT_SYMBOL_GPL(iwl_write_targ_mem);
drivers/net/wireless/iwlwifi/iwl-io.h+2−19
@@ -53,6 +53,8 @@ static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs) · 52 unmodified lines
5353
5454 void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask);
5555 void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask);
56+void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask);
57+void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask);
5658
5759 void iwl_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value);
5860
@@ -61,10 +63,6 @@ int iwl_poll_bit(struct iwl_trans *trans, u32 addr, · 2 unmodified lines
6163 int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
6264 int timeout);
6365
64−int iwl_grab_nic_access_silent(struct iwl_trans *trans);
65−bool iwl_grab_nic_access(struct iwl_trans *trans);
66−void iwl_release_nic_access(struct iwl_trans *trans);
67−
6866 u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg);
6967 void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value);
7068
@@ -76,19 +74,4 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, · 5 unmodified lines
7674 u32 bits, u32 mask);
7775 void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask);
7876
79−void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr,
80− void *buf, int dwords);
81−
82−#define iwl_read_targ_mem_bytes(trans, addr, buf, bufsize) \
83− do { \
84− BUILD_BUG_ON((bufsize) % sizeof(u32)); \
85− _iwl_read_targ_mem_dwords(trans, addr, buf, \
86− (bufsize) / sizeof(u32));\
87− } while (0)
88−
89−int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr,
90− const void *buf, int dwords);
91−
92−u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr);
93−int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val);
9477 #endif
drivers/net/wireless/iwlwifi/iwl-test.c+29−24
@@ -467,18 +467,20 @@ static int iwl_test_indirect_read(struct iwl_test *tst, u32 addr, u32 size) · 466 unmodified lines
467467 if (IWL_ABS_PRPH_START <= addr &&
468468 addr < IWL_ABS_PRPH_START + PRPH_END) {
469469 spin_lock_irqsave(&trans->reg_lock, flags);
470− iwl_grab_nic_access(trans);
470+ if (!iwl_trans_grab_nic_access(trans, false)) {
471+ spin_unlock_irqrestore(&trans->reg_lock, flags);
472+ return -EIO;
473+ }
471474 iwl_write32(trans, HBUS_TARG_PRPH_RADDR,
472475 addr | (3 << 24));
473476 for (i = 0; i < size; i += 4)
474477 *(u32 *)(tst->mem.addr + i) =
475478 iwl_read32(trans, HBUS_TARG_PRPH_RDAT);
476− iwl_release_nic_access(trans);
479+ iwl_trans_release_nic_access(trans);
477480 spin_unlock_irqrestore(&trans->reg_lock, flags);
478481 } else { /* target memory (SRAM) */
479− _iwl_read_targ_mem_dwords(trans, addr,
480− tst->mem.addr,
481− tst->mem.size / 4);
482+ iwl_trans_read_mem(trans, addr, tst->mem.addr,
483+ tst->mem.size / 4);
482484 }
483485
484486 tst->mem.nchunks =
@@ -501,28 +503,31 @@ static int iwl_test_indirect_write(struct iwl_test *tst, u32 addr, · 16 unmodified lines
501503
502504 if (IWL_ABS_PRPH_START <= addr &&
503505 addr < IWL_ABS_PRPH_START + PRPH_END) {
504− /* Periphery writes can be 1-3 bytes long, or DWORDs */
505− if (size < 4) {
506− memcpy(&val, buf, size);
507− spin_lock_irqsave(&trans->reg_lock, flags);
508− iwl_grab_nic_access(trans);
509− iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
510− (addr & 0x0000FFFF) |
511− ((size - 1) << 24));
512− iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
513− iwl_release_nic_access(trans);
514− /* needed after consecutive writes w/o read */
515− mmiowb();
506+ /* Periphery writes can be 1-3 bytes long, or DWORDs */
507+ if (size < 4) {
508+ memcpy(&val, buf, size);
509+ spin_lock_irqsave(&trans->reg_lock, flags);
510+ if (!iwl_trans_grab_nic_access(trans, false)) {
516511 spin_unlock_irqrestore(&trans->reg_lock, flags);
517− } else {
518− if (size % 4)
519− return -EINVAL;
520− for (i = 0; i < size; i += 4)
521− iwl_write_prph(trans, addr+i,
522− *(u32 *)(buf+i));
512+ return -EIO;
523513 }
514+ iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
515+ (addr & 0x0000FFFF) |
516+ ((size - 1) << 24));
517+ iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
518+ iwl_trans_release_nic_access(trans);
519+ /* needed after consecutive writes w/o read */
520+ mmiowb();
521+ spin_unlock_irqrestore(&trans->reg_lock, flags);
522+ } else {
523+ if (size % 4)
524+ return -EINVAL;
525+ for (i = 0; i < size; i += 4)
526+ iwl_write_prph(trans, addr+i,
527+ *(u32 *)(buf+i));
528+ }
524529 } else if (iwl_test_valid_hw_addr(tst, addr)) {
525− _iwl_write_targ_mem_dwords(trans, addr, buf, size / 4);
530+ iwl_trans_write_mem(trans, addr, buf, size / 4);
526531 } else {
527532 return -EINVAL;
528533 }
drivers/net/wireless/iwlwifi/iwl-trans.h+91−8
@@ -307,6 +307,16 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) · 306 unmodified lines
307307 #define IWL_MAX_TID_COUNT 8
308308 #define IWL_FRAME_LIMIT 64
309309
310+/**
311+ * enum iwl_wowlan_status - WoWLAN image/device status
312+ * @IWL_D3_STATUS_ALIVE: firmware is still running after resume
313+ * @IWL_D3_STATUS_RESET: device was reset while suspended
314+ */
315+enum iwl_d3_status {
316+ IWL_D3_STATUS_ALIVE,
317+ IWL_D3_STATUS_RESET,
318+};
319+
310320 /**
311321 * struct iwl_trans_config - transport configuration
312322 *
@@ -321,6 +331,8 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) · 8 unmodified lines
321331 * @n_no_reclaim_cmds: # of commands in list
322332 * @rx_buf_size_8k: 8 kB RX buffer size needed for A-MSDUs,
323333 * if unset 4k will be the RX buffer size
334+ * @bc_table_dword: set to true if the BC table expects the byte count to be
335+ * in DWORD (as opposed to bytes)
324336 * @queue_watchdog_timeout: time (in ms) after which queues
325337 * are considered stuck and will trigger device restart
326338 * @command_names: array of command names, must be 256 entries
@@ -335,6 +347,7 @@ struct iwl_trans_config { · 8 unmodified lines
335347 int n_no_reclaim_cmds;
336348
337349 bool rx_buf_size_8k;
350+ bool bc_table_dword;
338351 unsigned int queue_watchdog_timeout;
339352 const char **command_names;
340353 };
@@ -360,9 +373,12 @@ struct iwl_trans; · 19 unmodified lines
360373 * May sleep
361374 * @stop_device:stops the whole device (embedded CPU put to reset)
362375 * May sleep
363− * @wowlan_suspend: put the device into the correct mode for WoWLAN during
376+ * @d3_suspend: put the device into the correct mode for WoWLAN during
364377 * suspend. This is optional, if not implemented WoWLAN will not be
365378 * supported. This callback may sleep.
379+ * @d3_resume: resume the device after WoWLAN, enabling the opmode to
380+ * talk to the WoWLAN image to get its status. This is optional, if not
381+ * implemented WoWLAN will not be supported. This callback may sleep.
366382 * @send_cmd:send a host command. Must return -ERFKILL if RFkill is asserted.
367383 * If RFkill is asserted in the middle of a SYNC host command, it must
368384 * return -ERFKILL straight away.
@@ -387,20 +403,27 @@ struct iwl_trans; · 18 unmodified lines
387403 * @read32: read a u32 register at offset ofs from the BAR
388404 * @read_prph: read a DWORD from a periphery register
389405 * @write_prph: write a DWORD to a periphery register
406+ * @read_mem: read device's SRAM in DWORD
407+ * @write_mem: write device's SRAM in DWORD. If %buf is %NULL, then the memory
408+ * will be zeroed.
390409 * @configure: configure parameters required by the transport layer from
391410 * the op_mode. May be called several times before start_fw, can't be
392411 * called after that.
393412 * @set_pmi: set the power pmi state
413+ * @grab_nic_access: wake the NIC to be able to access non-HBUS regs
414+ * @release_nic_access: let the NIC go to sleep
394415 */
395416 struct iwl_trans_ops {
396417
397418 int (*start_hw)(struct iwl_trans *iwl_trans);
398419 void (*stop_hw)(struct iwl_trans *iwl_trans, bool op_mode_leaving);
399− int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw);
420+ int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw,
421+ bool run_in_rfkill);
400422 void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr);
401423 void (*stop_device)(struct iwl_trans *trans);
402424
403− void (*wowlan_suspend)(struct iwl_trans *trans);
425+ void (*d3_suspend)(struct iwl_trans *trans);
426+ int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status);
404427
405428 int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
406429
@@ -424,9 +447,15 @@ struct iwl_trans_ops { · 17 unmodified lines
424447 u32 (*read32)(struct iwl_trans *trans, u32 ofs);
425448 u32 (*read_prph)(struct iwl_trans *trans, u32 ofs);
426449 void (*write_prph)(struct iwl_trans *trans, u32 ofs, u32 val);
450+ int (*read_mem)(struct iwl_trans *trans, u32 addr,
451+ void *buf, int dwords);
452+ int (*write_mem)(struct iwl_trans *trans, u32 addr,
453+ void *buf, int dwords);
427454 void (*configure)(struct iwl_trans *trans,
428455 const struct iwl_trans_config *trans_cfg);
429456 void (*set_pmi)(struct iwl_trans *trans, bool state);
457+ bool (*grab_nic_access)(struct iwl_trans *trans, bool silent);
458+ void (*release_nic_access)(struct iwl_trans *trans);
430459 };
431460
432461 /**
@@ -528,13 +557,14 @@ static inline void iwl_trans_fw_alive(struct iwl_trans *trans, u32 scd_addr) · 95 unmodified lines
528557 }
529558
530559 static inline int iwl_trans_start_fw(struct iwl_trans *trans,
531− const struct fw_img *fw)
560+ const struct fw_img *fw,
561+ bool run_in_rfkill)
532562 {
533563 might_sleep();
534564
535565 WARN_ON_ONCE(!trans->rx_mpdu_cmd);
536566
537− return trans->ops->start_fw(trans, fw);
567+ return trans->ops->start_fw(trans, fw, run_in_rfkill);
538568 }
539569
540570 static inline void iwl_trans_stop_device(struct iwl_trans *trans)
@@ -546,10 +576,17 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans) · 5 unmodified lines
546576 trans->state = IWL_TRANS_NO_FW;
547577 }
548578
549−static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans)
579+static inline void iwl_trans_d3_suspend(struct iwl_trans *trans)
580+{
581+ might_sleep();
582+ trans->ops->d3_suspend(trans);
583+}
584+
585+static inline int iwl_trans_d3_resume(struct iwl_trans *trans,
586+ enum iwl_d3_status *status)
550587 {
551588 might_sleep();
552− trans->ops->wowlan_suspend(trans);
589+ return trans->ops->d3_resume(trans, status);
553590 }
554591
555592 static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
@@ -636,7 +673,7 @@ static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) · 80 unmodified lines
636673 }
637674
638675 static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans,
639− struct dentry *dir)
676+ struct dentry *dir)
640677 {
641678 return trans->ops->dbgfs_register(trans, dir);
642679 }
@@ -679,11 +716,57 @@ static inline void iwl_trans_write_prph(struct iwl_trans *trans, u32 ofs, · 36 unmodified lines
679716 return trans->ops->write_prph(trans, ofs, val);
680717 }
681718
719+static inline int iwl_trans_read_mem(struct iwl_trans *trans, u32 addr,
720+ void *buf, int dwords)
721+{
722+ return trans->ops->read_mem(trans, addr, buf, dwords);
723+}
724+
725+#define iwl_trans_read_mem_bytes(trans, addr, buf, bufsize) \
726+ do { \
727+ if (__builtin_constant_p(bufsize)) \
728+ BUILD_BUG_ON((bufsize) % sizeof(u32)); \
729+ iwl_trans_read_mem(trans, addr, buf, (bufsize) / sizeof(u32));\
730+ } while (0)
731+
732+static inline u32 iwl_trans_read_mem32(struct iwl_trans *trans, u32 addr)
733+{
734+ u32 value;
735+
736+ if (WARN_ON(iwl_trans_read_mem(trans, addr, &value, 1)))
737+ return 0xa5a5a5a5;
738+
739+ return value;
740+}
741+
742+static inline int iwl_trans_write_mem(struct iwl_trans *trans, u32 addr,
743+ void *buf, int dwords)
744+{
745+ return trans->ops->write_mem(trans, addr, buf, dwords);
746+}
747+
748+static inline u32 iwl_trans_write_mem32(struct iwl_trans *trans, u32 addr,
749+ u32 val)
750+{
751+ return iwl_trans_write_mem(trans, addr, &val, 1);
752+}
753+
682754 static inline void iwl_trans_set_pmi(struct iwl_trans *trans, bool state)
683755 {
684756 trans->ops->set_pmi(trans, state);
685757 }
686758
759+#define iwl_trans_grab_nic_access(trans, silent) \
760+ __cond_lock(nic_access, \
761+ likely((trans)->ops->grab_nic_access(trans, silent)))
762+
763+static inline void __releases(nic_access)
764+iwl_trans_release_nic_access(struct iwl_trans *trans)
765+{
766+ trans->ops->release_nic_access(trans);
767+ __release(nic_access);
768+}
769+
687770 /*****************************************************
688771 * driver (transport) register/unregister functions
689772 ******************************************************/
drivers/net/wireless/iwlwifi/pcie/internal.h+4−4
@@ -222,8 +222,6 @@ struct iwl_txq { · 221 unmodified lines
222222 * @rx_replenish: work that will be called when buffers need to be allocated
223223 * @drv - pointer to iwl_drv
224224 * @trans: pointer to the generic transport area
225− * @irq - the irq number for the device
226− * @irq_requested: true when the irq has been requested
227225 * @scd_base_addr: scheduler sram base address in SRAM
228226 * @scd_bc_tbls: pointer to the byte count table of the scheduler
229227 * @kw: keep warm address
@@ -234,6 +232,7 @@ struct iwl_txq { · 4 unmodified lines
234232 * @status - transport specific status flags
235233 * @cmd_queue - command queue number
236234 * @rx_buf_size_8k: 8 kB RX buffer size
235+ * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes)
237236 * @rx_page_order: page order for receive buffer size
238237 * @wd_timeout: queue watchdog timeout (jiffies)
239238 */
@@ -249,11 +248,9 @@ struct iwl_trans_pcie { · 9 unmodified lines
249248 int ict_index;
250249 u32 inta;
251250 bool use_ict;
252− bool irq_requested;
253251 struct tasklet_struct irq_tasklet;
254252 struct isr_statistics isr_stats;
255253
256− unsigned int irq;
257254 spinlock_t irq_lock;
258255 u32 inta_mask;
259256 u32 scd_base_addr;
@@ -279,6 +276,7 @@ struct iwl_trans_pcie { · 19 unmodified lines
279276 u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS];
280277
281278 bool rx_buf_size_8k;
279+ bool bc_table_dword;
282280 u32 rx_page_order;
283281
284282 const char **command_names;
@@ -359,6 +357,8 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, · 74 unmodified lines
359357 struct iwl_rx_cmd_buffer *rxb, int handler_status);
360358 void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
361359 struct sk_buff_head *skbs);
360+void iwl_trans_pcie_tx_reset(struct iwl_trans *trans);
361+
362362 /*****************************************************
363363 * Error handling
364364 ******************************************************/
drivers/net/wireless/iwlwifi/pcie/rx.c+11−4
@@ -436,7 +436,7 @@ static int iwl_pcie_rx_alloc(struct iwl_trans *trans) · 435 unmodified lines
436436 err_rb_stts:
437437 dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE,
438438 rxq->bd, rxq->bd_dma);
439− memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma));
439+ rxq->bd_dma = 0;
440440 rxq->bd = NULL;
441441 err_bd:
442442 return -ENOMEM;
@@ -455,6 +455,10 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq) · 12 unmodified lines
455455
456456 /* Stop Rx DMA */
457457 iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
458+ /* reset and flush pointers */
459+ iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_RBDCB_WPTR, 0);
460+ iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ, 0);
461+ iwl_write_direct32(trans, FH_RSCSR_CHNL0_RDPTR, 0);
458462
459463 /* Reset driver's Rx queue write index */
460464 iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
@@ -491,7 +495,6 @@ int iwl_pcie_rx_init(struct iwl_trans *trans) · 30 unmodified lines
491495 {
492496 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
493497 struct iwl_rxq *rxq = &trans_pcie->rxq;
494−
495498 int i, err;
496499 unsigned long flags;
497500
@@ -518,6 +521,7 @@ int iwl_pcie_rx_init(struct iwl_trans *trans) · 20 unmodified lines
518521 rxq->read = rxq->write = 0;
519522 rxq->write_actual = 0;
520523 rxq->free_count = 0;
524+ memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts));
521525 spin_unlock_irqrestore(&rxq->lock, flags);
522526
523527 iwl_pcie_rx_replenish(trans);
@@ -545,13 +549,15 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) · 21 unmodified lines
545549 return;
546550 }
547551
552+ cancel_work_sync(&trans_pcie->rx_replenish);
553+
548554 spin_lock_irqsave(&rxq->lock, flags);
549555 iwl_pcie_rxq_free_rbs(trans);
550556 spin_unlock_irqrestore(&rxq->lock, flags);
551557
552558 dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE,
553559 rxq->bd, rxq->bd_dma);
554− memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma));
560+ rxq->bd_dma = 0;
555561 rxq->bd = NULL;
556562
557563 if (rxq->rb_stts)
@@ -560,7 +566,7 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) · 2 unmodified lines
560566 rxq->rb_stts, rxq->rb_stts_dma);
561567 else
562568 IWL_DEBUG_INFO(trans, "Free rxq->rb_stts which is NULL\n");
563− memset(&rxq->rb_stts_dma, 0, sizeof(rxq->rb_stts_dma));
569+ rxq->rb_stts_dma = 0;
564570 rxq->rb_stts = NULL;
565571 }
566572
@@ -1166,6 +1172,7 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data) · 599 unmodified lines
11661172 else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
11671173 !trans_pcie->inta)
11681174 iwl_enable_interrupts(trans);
1175+ return IRQ_HANDLED;
11691176
11701177 none:
11711178 /* re-enable interrupts here since we don't have anything to service. */
drivers/net/wireless/iwlwifi/pcie/trans.c+248−61
@@ -75,21 +75,16 @@ · 74 unmodified lines
7575 #include "iwl-agn-hw.h"
7676 #include "internal.h"
7777
78−static void iwl_pcie_set_pwr_vmain(struct iwl_trans *trans)
78+static void iwl_pcie_set_pwr(struct iwl_trans *trans, bool vaux)
7979 {
80−/*
81− * (for documentation purposes)
82− * to set power to V_AUX, do:
83−
84− if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
85− iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG,
86− APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
87− ~APMG_PS_CTRL_MSK_PWR_SRC);
88− */
89−
90− iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG,
91− APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
92− ~APMG_PS_CTRL_MSK_PWR_SRC);
80+ if (vaux && pci_pme_capable(to_pci_dev(trans->dev), PCI_D3cold))
81+ iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG,
82+ APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
83+ ~APMG_PS_CTRL_MSK_PWR_SRC);
84+ else
85+ iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG,
86+ APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
87+ ~APMG_PS_CTRL_MSK_PWR_SRC);
9388 }
9489
9590 /* PCI registers */
@@ -259,7 +254,7 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans) · 163 unmodified lines
259254
260255 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
261256
262− iwl_pcie_set_pwr_vmain(trans);
257+ iwl_pcie_set_pwr(trans, false);
263258
264259 iwl_op_mode_nic_config(trans->op_mode);
265260
@@ -435,7 +430,7 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, · 169 unmodified lines
435430 }
436431
437432 static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
438− const struct fw_img *fw)
433+ const struct fw_img *fw, bool run_in_rfkill)
439434 {
440435 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
441436 int ret;
@@ -454,7 +449,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, · 12 unmodified lines
454449 /* If platform's RF_KILL switch is NOT set to KILL */
455450 hw_rfkill = iwl_is_rfkill_set(trans);
456451 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
457− if (hw_rfkill)
452+ if (hw_rfkill && !run_in_rfkill)
458453 return -ERFKILL;
459454
460455 iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
@@ -534,12 +529,6 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) · 73 unmodified lines
534529
535530 iwl_enable_rfkill_int(trans);
536531
537− /* wait to make sure we flush pending tasklet*/
538− synchronize_irq(trans_pcie->irq);
539− tasklet_kill(&trans_pcie->irq_tasklet);
540−
541− cancel_work_sync(&trans_pcie->rx_replenish);
542−
543532 /* stop and reset the on-board processor */
544533 iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
545534
@@ -551,46 +540,87 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) · 5 unmodified lines
551540 clear_bit(STATUS_RFKILL, &trans_pcie->status);
552541 }
553542
554−static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans)
543+static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans)
555544 {
556545 /* let the ucode operate on its own */
557546 iwl_write32(trans, CSR_UCODE_DRV_GP1_SET,
558547 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
559548
560549 iwl_disable_interrupts(trans);
550+ iwl_pcie_disable_ict(trans);
551+
561552 iwl_clear_bit(trans, CSR_GP_CNTRL,
562553 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
554+ iwl_clear_bit(trans, CSR_GP_CNTRL,
555+ CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
556+
557+ /*
558+ * reset TX queues -- some of their registers reset during S3
559+ * so if we don't reset everything here the D3 image would try
560+ * to execute some invalid memory upon resume
561+ */
562+ iwl_trans_pcie_tx_reset(trans);
563+
564+ iwl_pcie_set_pwr(trans, true);
563565 }
564566
565−static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
567+static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
568+ enum iwl_d3_status *status)
566569 {
567− struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
568− int err;
569− bool hw_rfkill;
570+ u32 val;
571+ int ret;
570572
571− trans_pcie->inta_mask = CSR_INI_SET_MASK;
573+ iwl_pcie_set_pwr(trans, false);
572574
573− if (!trans_pcie->irq_requested) {
574− tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long))
575− iwl_pcie_tasklet, (unsigned long)trans);
575+ val = iwl_read32(trans, CSR_RESET);
576+ if (val & CSR_RESET_REG_FLAG_NEVO_RESET) {
577+ *status = IWL_D3_STATUS_RESET;
578+ return 0;
579+ }
576580
577− iwl_pcie_alloc_ict(trans);
581+ /*
582+ * Also enables interrupts - none will happen as the device doesn't
583+ * know we're waking it up, only when the opmode actually tells it
584+ * after this call.
585+ */
586+ iwl_pcie_reset_ict(trans);
578587
579− err = request_irq(trans_pcie->irq, iwl_pcie_isr_ict,
580− IRQF_SHARED, DRV_NAME, trans);
581− if (err) {
582− IWL_ERR(trans, "Error allocating IRQ %d\n",
583− trans_pcie->irq);
584− goto error;
585− }
588+ iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
589+ iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
586590
587− trans_pcie->irq_requested = true;
591+ ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
592+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
593+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
594+ 25000);
595+ if (ret) {
596+ IWL_ERR(trans, "Failed to resume the device (mac ready)\n");
597+ return ret;
588598 }
589599
600+ iwl_trans_pcie_tx_reset(trans);
601+
602+ ret = iwl_pcie_rx_init(trans);
603+ if (ret) {
604+ IWL_ERR(trans, "Failed to resume the device (RX reset)\n");
605+ return ret;
606+ }
607+
608+ iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR,
609+ CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
610+
611+ *status = IWL_D3_STATUS_ALIVE;
612+ return 0;
613+}
614+
615+static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
616+{
617+ bool hw_rfkill;
618+ int err;
619+
590620 err = iwl_pcie_prepare_card_hw(trans);
591621 if (err) {
592622 IWL_ERR(trans, "Error while preparing HW: %d\n", err);
593− goto err_free_irq;
623+ return err;
594624 }
595625
596626 iwl_pcie_apm_init(trans);
@@ -601,15 +631,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) · 4 unmodified lines
601631 hw_rfkill = iwl_is_rfkill_set(trans);
602632 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
603633
604− return err;
605−
606−err_free_irq:
607− trans_pcie->irq_requested = false;
608− free_irq(trans_pcie->irq, trans);
609−error:
610− iwl_pcie_free_ict(trans);
611− tasklet_kill(&trans_pcie->irq_tasklet);
612− return err;
634+ return 0;
613635 }
614636
615637 static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans,
@@ -703,19 +725,21 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, · 87 unmodified lines
703725 msecs_to_jiffies(trans_cfg->queue_watchdog_timeout);
704726
705727 trans_pcie->command_names = trans_cfg->command_names;
728+ trans_pcie->bc_table_dword = trans_cfg->bc_table_dword;
706729 }
707730
708731 void iwl_trans_pcie_free(struct iwl_trans *trans)
709732 {
710733 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
711734
735+ synchronize_irq(trans_pcie->pci_dev->irq);
736+ tasklet_kill(&trans_pcie->irq_tasklet);
737+
712738 iwl_pcie_tx_free(trans);
713739 iwl_pcie_rx_free(trans);
714740
715− if (trans_pcie->irq_requested == true) {
716− free_irq(trans_pcie->irq, trans);
717− iwl_pcie_free_ict(trans);
718− }
741+ free_irq(trans_pcie->pci_dev->irq, trans);
742+ iwl_pcie_free_ict(trans);
719743
720744 pci_disable_msi(trans_pcie->pci_dev);
721745 iounmap(trans_pcie->hw_base);
@@ -751,13 +775,112 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) · 29 unmodified lines
751775 hw_rfkill = iwl_is_rfkill_set(trans);
752776 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
753777
754− if (!hw_rfkill)
755− iwl_enable_interrupts(trans);
756−
757778 return 0;
758779 }
759780 #endif /* CONFIG_PM_SLEEP */
760781
782+static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent)
783+{
784+ int ret;
785+
786+ lockdep_assert_held(&trans->reg_lock);
787+
788+ /* this bit wakes up the NIC */
789+ __iwl_set_bit(trans, CSR_GP_CNTRL,
790+ CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
791+
792+ /*
793+ * These bits say the device is running, and should keep running for
794+ * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
795+ * but they do not indicate that embedded SRAM is restored yet;
796+ * 3945 and 4965 have volatile SRAM, and must save/restore contents
797+ * to/from host DRAM when sleeping/waking for power-saving.
798+ * Each direction takes approximately 1/4 millisecond; with this
799+ * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
800+ * series of register accesses are expected (e.g. reading Event Log),
801+ * to keep device from sleeping.
802+ *
803+ * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
804+ * SRAM is okay/restored. We don't check that here because this call
805+ * is just for hardware register access; but GP1 MAC_SLEEP check is a
806+ * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
807+ *
808+ * 5000 series and later (including 1000 series) have non-volatile SRAM,
809+ * and do not save/restore SRAM when power cycling.
810+ */
811+ ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
812+ CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
813+ (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
814+ CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
815+ if (unlikely(ret < 0)) {
816+ iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
817+ if (!silent) {
818+ u32 val = iwl_read32(trans, CSR_GP_CNTRL);
819+ WARN_ONCE(1,
820+ "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n",
821+ val);
822+ return false;
823+ }
824+ }
825+
826+ return true;
827+}
828+
829+static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans)
830+{
831+ lockdep_assert_held(&trans->reg_lock);
832+ __iwl_clear_bit(trans, CSR_GP_CNTRL,
833+ CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
834+ /*
835+ * Above we read the CSR_GP_CNTRL register, which will flush
836+ * any previous writes, but we need the write that clears the
837+ * MAC_ACCESS_REQ bit to be performed before any other writes
838+ * scheduled on different CPUs (after we drop reg_lock).
839+ */
840+ mmiowb();
841+}
842+
843+static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr,
844+ void *buf, int dwords)
845+{
846+ unsigned long flags;
847+ int offs, ret = 0;
848+ u32 *vals = buf;
849+
850+ spin_lock_irqsave(&trans->reg_lock, flags);
851+ if (iwl_trans_grab_nic_access(trans, false)) {
852+ iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr);
853+ for (offs = 0; offs < dwords; offs++)
854+ vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
855+ iwl_trans_release_nic_access(trans);
856+ } else {
857+ ret = -EBUSY;
858+ }
859+ spin_unlock_irqrestore(&trans->reg_lock, flags);
860+ return ret;
861+}
862+
863+static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr,
864+ void *buf, int dwords)
865+{
866+ unsigned long flags;
867+ int offs, ret = 0;
868+ u32 *vals = buf;
869+
870+ spin_lock_irqsave(&trans->reg_lock, flags);
871+ if (iwl_trans_grab_nic_access(trans, false)) {
872+ iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
873+ for (offs = 0; offs < dwords; offs++)
874+ iwl_write32(trans, HBUS_TARG_MEM_WDAT,
875+ vals ? vals[offs] : 0);
876+ iwl_trans_release_nic_access(trans);
877+ } else {
878+ ret = -EBUSY;
879+ }
880+ spin_unlock_irqrestore(&trans->reg_lock, flags);
881+ return ret;
882+}
883+
761884 #define IWL_FLUSH_WAIT_MS 2000
762885
763886 static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans)
@@ -767,6 +890,8 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) · 3 unmodified lines
767890 struct iwl_queue *q;
768891 int cnt;
769892 unsigned long now = jiffies;
893+ u32 scd_sram_addr;
894+ u8 buf[16];
770895 int ret = 0;
771896
772897 /* waiting for all the tx frames complete might take a while */
@@ -780,11 +905,50 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) · 7 unmodified lines
780905 msleep(1);
781906
782907 if (q->read_ptr != q->write_ptr) {
783− IWL_ERR(trans, "fail to flush all tx fifo queues\n");
908+ IWL_ERR(trans,
909+ "fail to flush all tx fifo queues Q %d\n", cnt);
784910 ret = -ETIMEDOUT;
785911 break;
786912 }
787913 }
914+
915+ if (!ret)
916+ return 0;
917+
918+ IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n",
919+ txq->q.read_ptr, txq->q.write_ptr);
920+
921+ scd_sram_addr = trans_pcie->scd_base_addr +
922+ SCD_TX_STTS_QUEUE_OFFSET(txq->q.id);
923+ iwl_trans_read_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf));
924+
925+ iwl_print_hex_error(trans, buf, sizeof(buf));
926+
927+ for (cnt = 0; cnt < FH_TCSR_CHNL_NUM; cnt++)
928+ IWL_ERR(trans, "FH TRBs(%d) = 0x%08x\n", cnt,
929+ iwl_read_direct32(trans, FH_TX_TRB_REG(cnt)));
930+
931+ for (cnt = 0; cnt < trans->cfg->base_params->num_of_queues; cnt++) {
932+ u32 status = iwl_read_prph(trans, SCD_QUEUE_STATUS_BITS(cnt));
933+ u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7;
934+ bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE));
935+ u32 tbl_dw =
936+ iwl_trans_read_mem32(trans, trans_pcie->scd_base_addr +
937+ SCD_TRANS_TBL_OFFSET_QUEUE(cnt));
938+
939+ if (cnt & 0x1)
940+ tbl_dw = (tbl_dw & 0xFFFF0000) >> 16;
941+ else
942+ tbl_dw = tbl_dw & 0x0000FFFF;
943+
944+ IWL_ERR(trans,
945+ "Q %d is %sactive and mapped to fifo %d ra_tid 0x%04x [%d,%d]\n",
946+ cnt, active ? "" : "in", fifo, tbl_dw,
947+ iwl_read_prph(trans,
948+ SCD_QUEUE_RDPTR(cnt)) & (txq->q.n_bd - 1),
949+ iwl_read_prph(trans, SCD_QUEUE_WRPTR(cnt)));
950+ }
951+
788952 return ret;
789953 }
790954
@@ -1212,7 +1376,8 @@ static const struct iwl_trans_ops trans_ops_pcie = { · 421 unmodified lines
12121376 .start_fw = iwl_trans_pcie_start_fw,
12131377 .stop_device = iwl_trans_pcie_stop_device,
12141378
1215− .wowlan_suspend = iwl_trans_pcie_wowlan_suspend,
1379+ .d3_suspend = iwl_trans_pcie_d3_suspend,
1380+ .d3_resume = iwl_trans_pcie_d3_resume,
12161381
12171382 .send_cmd = iwl_trans_pcie_send_hcmd,
12181383
@@ -1235,8 +1400,12 @@ static const struct iwl_trans_ops trans_ops_pcie = { · 16 unmodified lines
12351400 .read32 = iwl_trans_pcie_read32,
12361401 .read_prph = iwl_trans_pcie_read_prph,
12371402 .write_prph = iwl_trans_pcie_write_prph,
1403+ .read_mem = iwl_trans_pcie_read_mem,
1404+ .write_mem = iwl_trans_pcie_write_mem,
12381405 .configure = iwl_trans_pcie_configure,
12391406 .set_pmi = iwl_trans_pcie_set_pmi,
1407+ .grab_nic_access = iwl_trans_pcie_grab_nic_access,
1408+ .release_nic_access = iwl_trans_pcie_release_nic_access
12401409 };
12411410
12421411 struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
@@ -1318,7 +1487,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, · 75 unmodified lines
13181487 }
13191488
13201489 trans->dev = &pdev->dev;
1321− trans_pcie->irq = pdev->irq;
13221490 trans_pcie->pci_dev = pdev;
13231491 trans->hw_rev = iwl_read32(trans, CSR_HW_REV);
13241492 trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
@@ -1344,8 +1512,27 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, · 19 unmodified lines
13441512 if (!trans->dev_cmd_pool)
13451513 goto out_pci_disable_msi;
13461514
1515+ trans_pcie->inta_mask = CSR_INI_SET_MASK;
1516+
1517+ tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long))
1518+ iwl_pcie_tasklet, (unsigned long)trans);
1519+
1520+ if (iwl_pcie_alloc_ict(trans))
1521+ goto out_free_cmd_pool;
1522+
1523+ err = request_irq(pdev->irq, iwl_pcie_isr_ict,
1524+ IRQF_SHARED, DRV_NAME, trans);
1525+ if (err) {
1526+ IWL_ERR(trans, "Error allocating IRQ %d\n", pdev->irq);
1527+ goto out_free_ict;
1528+ }
1529+
13471530 return trans;
13481531
1532+out_free_ict:
1533+ iwl_pcie_free_ict(trans);
1534+out_free_cmd_pool:
1535+ kmem_cache_destroy(trans->dev_cmd_pool);
13491536 out_pci_disable_msi:
13501537 pci_disable_msi(pdev);
13511538 out_pci_release_regions:
drivers/net/wireless/iwlwifi/pcie/tx.c+48−31
@@ -160,7 +160,7 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data) · 159 unmodified lines
160160 IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n",
161161 txq->q.read_ptr, txq->q.write_ptr);
162162
163− iwl_read_targ_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf));
163+ iwl_trans_read_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf));
164164
165165 iwl_print_hex_error(trans, buf, sizeof(buf));
166166
@@ -173,9 +173,9 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data) · 6 unmodified lines
173173 u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7;
174174 bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE));
175175 u32 tbl_dw =
176− iwl_read_targ_mem(trans,
177− trans_pcie->scd_base_addr +
178− SCD_TRANS_TBL_OFFSET_QUEUE(i));
176+ iwl_trans_read_mem32(trans,
177+ trans_pcie->scd_base_addr +
178+ SCD_TRANS_TBL_OFFSET_QUEUE(i));
179179
180180 if (i & 0x1)
181181 tbl_dw = (tbl_dw & 0xFFFF0000) >> 16;
@@ -237,7 +237,10 @@ static void iwl_pcie_txq_update_byte_cnt_tbl(struct iwl_trans *trans, · 55 unmodified lines
237237 break;
238238 }
239239
240− bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12));
240+ if (trans_pcie->bc_table_dword)
241+ len = DIV_ROUND_UP(len, 4);
242+
243+ bc_ent = cpu_to_le16(len | (sta_id << 12));
241244
242245 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
243246
@@ -306,6 +309,9 @@ void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq) · 62 unmodified lines
306309 return;
307310 }
308311
312+ IWL_DEBUG_TX(trans, "Q:%d WR: 0x%x\n", txq_id,
313+ txq->q.write_ptr);
314+
309315 iwl_write_direct32(trans, HBUS_TARG_WRPTR,
310316 txq->q.write_ptr | (txq_id << 8));
311317
@@ -612,7 +618,7 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) · 300 unmodified lines
612618 if (txq->q.n_bd) {
613619 dma_free_coherent(dev, sizeof(struct iwl_tfd) *
614620 txq->q.n_bd, txq->tfds, txq->q.dma_addr);
615− memset(&txq->q.dma_addr, 0, sizeof(txq->q.dma_addr));
621+ txq->q.dma_addr = 0;
616622 }
617623
618624 kfree(txq->entries);
@@ -638,9 +644,11 @@ static void iwl_pcie_txq_set_sched(struct iwl_trans *trans, u32 mask) · 19 unmodified lines
638644 void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
639645 {
640646 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
641− u32 a;
647+ int nq = trans->cfg->base_params->num_of_queues;
642648 int chan;
643649 u32 reg_val;
650+ int clear_dwords = (SCD_TRANS_TBL_OFFSET_QUEUE(nq) -
651+ SCD_CONTEXT_MEM_LOWER_BOUND) / sizeof(u32);
644652
645653 /* make sure all queue are not stopped/used */
646654 memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped));
@@ -652,20 +660,10 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) · 5 unmodified lines
652660 WARN_ON(scd_base_addr != 0 &&
653661 scd_base_addr != trans_pcie->scd_base_addr);
654662
655− a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND;
656− /* reset conext data memory */
657− for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND;
658− a += 4)
659− iwl_write_targ_mem(trans, a, 0);
660− /* reset tx status memory */
661− for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND;
662− a += 4)
663− iwl_write_targ_mem(trans, a, 0);
664− for (; a < trans_pcie->scd_base_addr +
665− SCD_TRANS_TBL_OFFSET_QUEUE(
666− trans->cfg->base_params->num_of_queues);
667− a += 4)
668− iwl_write_targ_mem(trans, a, 0);
663+ /* reset context data, TX status and translation data */
664+ iwl_trans_write_mem(trans, trans_pcie->scd_base_addr +
665+ SCD_CONTEXT_MEM_LOWER_BOUND,
666+ NULL, clear_dwords);
669667
670668 iwl_write_prph(trans, SCD_DRAM_BASE_ADDR,
671669 trans_pcie->scd_bc_tbls.dma >> 10);
@@ -697,6 +695,29 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) · 25 unmodified lines
697695 APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
698696 }
699697
698+void iwl_trans_pcie_tx_reset(struct iwl_trans *trans)
699+{
700+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
701+ int txq_id;
702+
703+ for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues;
704+ txq_id++) {
705+ struct iwl_txq *txq = &trans_pcie->txq[txq_id];
706+
707+ iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(txq_id),
708+ txq->q.dma_addr >> 8);
709+ iwl_pcie_txq_unmap(trans, txq_id);
710+ txq->q.read_ptr = 0;
711+ txq->q.write_ptr = 0;
712+ }
713+
714+ /* Tell NIC where to find the "keep warm" buffer */
715+ iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG,
716+ trans_pcie->kw.dma >> 4);
717+
718+ iwl_pcie_tx_start(trans, trans_pcie->scd_base_addr);
719+}
720+
700721 /*
701722 * iwl_pcie_tx_stop - Stop all Tx DMA channels
702723 */
@@ -1002,14 +1023,14 @@ static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, · 299 unmodified lines
10021023 tbl_dw_addr = trans_pcie->scd_base_addr +
10031024 SCD_TRANS_TBL_OFFSET_QUEUE(txq_id);
10041025
1005− tbl_dw = iwl_read_targ_mem(trans, tbl_dw_addr);
1026+ tbl_dw = iwl_trans_read_mem32(trans, tbl_dw_addr);
10061027
10071028 if (txq_id & 0x1)
10081029 tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
10091030 else
10101031 tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
10111032
1012− iwl_write_targ_mem(trans, tbl_dw_addr, tbl_dw);
1033+ iwl_trans_write_mem32(trans, tbl_dw_addr, tbl_dw);
10131034
10141035 return 0;
10151036 }
@@ -1068,9 +1089,9 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, · 52 unmodified lines
10681089 iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn);
10691090
10701091 /* Set up Tx window size and frame limit for this queue */
1071− iwl_write_targ_mem(trans, trans_pcie->scd_base_addr +
1092+ iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr +
10721093 SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0);
1073− iwl_write_targ_mem(trans, trans_pcie->scd_base_addr +
1094+ iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr +
10741095 SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32),
10751096 ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
10761097 SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
@@ -1101,8 +1122,8 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) · 24 unmodified lines
11011122
11021123 iwl_pcie_txq_set_inactive(trans, txq_id);
11031124
1104− _iwl_write_targ_mem_dwords(trans, stts_addr,
1105− zero_val, ARRAY_SIZE(zero_val));
1125+ iwl_trans_write_mem(trans, stts_addr, (void *)zero_val,
1126+ ARRAY_SIZE(zero_val));
11061127
11071128 iwl_pcie_txq_unmap(trans, txq_id);
11081129
@@ -1642,10 +1663,6 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, · 533 unmodified lines
16421663 tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
16431664 tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
16441665
1645− IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n",
1646− le16_to_cpu(dev_cmd->hdr.sequence));
1647− IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags));
1648−
16491666 /* Set up entry for this TFD in Tx byte-count array */
16501667 iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len));
16511668
drivers/net/wireless/mac80211_hwsim.c+39−18
@@ -363,6 +363,8 @@ struct mac80211_hwsim_data { · 362 unmodified lines
363363 /* difference between this hw's clock and the real clock, in usecs */
364364 s64 tsf_offset;
365365 s64 bcn_delta;
366+ /* absolute beacon transmission time. Used to cover up "tx" delay. */
367+ u64 abs_bcn_ts;
366368 };
367369
368370
@@ -410,15 +412,19 @@ static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb, · 41 unmodified lines
410412 return NETDEV_TX_OK;
411413 }
412414
415+static inline u64 mac80211_hwsim_get_tsf_raw(void)
416+{
417+ return ktime_to_us(ktime_get_real());
418+}
419+
413420 static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data)
414421 {
415− struct timeval tv = ktime_to_timeval(ktime_get_real());
416− u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
422+ u64 now = mac80211_hwsim_get_tsf_raw();
417423 return cpu_to_le64(now + data->tsf_offset);
418424 }
419425
420426 static u64 mac80211_hwsim_get_tsf(struct ieee80211_hw *hw,
421− struct ieee80211_vif *vif)
427+ struct ieee80211_vif *vif)
422428 {
423429 struct mac80211_hwsim_data *data = hw->priv;
424430 return le64_to_cpu(__mac80211_hwsim_get_tsf(data));
@@ -705,7 +711,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, · 280 unmodified lines
705711 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
706712 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
707713 struct ieee80211_rx_status rx_status;
708− struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info);
714+ u64 now;
709715
710716 memset(&rx_status, 0, sizeof(rx_status));
711717 rx_status.flag |= RX_FLAG_MACTIME_START;
@@ -731,11 +737,23 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, · 19 unmodified lines
731737 secpath_reset(skb);
732738 nf_reset(skb);
733739
740+ /*
741+ * Get absolute mactime here so all HWs RX at the "same time", and
742+ * absolute TX time for beacon mactime so the timestamp matches.
743+ * Giving beacons a different mactime than non-beacons looks messy, but
744+ * it helps the Toffset be exact and a ~10us mactime discrepancy
745+ * probably doesn't really matter.
746+ */
747+ if (ieee80211_is_beacon(hdr->frame_control) ||
748+ ieee80211_is_probe_resp(hdr->frame_control))
749+ now = data->abs_bcn_ts;
750+ else
751+ now = mac80211_hwsim_get_tsf_raw();
752+
734753 /* Copy skb to all enabled radios that are on the current frequency */
735754 spin_lock(&hwsim_radio_lock);
736755 list_for_each_entry(data2, &hwsim_radios, list) {
737756 struct sk_buff *nskb;
738− struct ieee80211_mgmt *mgmt;
739757 struct tx_iter_data tx_iter_data = {
740758 .receive = false,
741759 .channel = chan,
@@ -787,17 +805,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, · 45 unmodified lines
787805 if (mac80211_hwsim_addr_match(data2, hdr->addr1))
788806 ack = true;
789807
790− /* set bcn timestamp relative to receiver mactime */
791− rx_status.mactime =
792− le64_to_cpu(__mac80211_hwsim_get_tsf(data2));
793− mgmt = (struct ieee80211_mgmt *) nskb->data;
794− if (ieee80211_is_beacon(mgmt->frame_control) ||
795− ieee80211_is_probe_resp(mgmt->frame_control))
796− mgmt->u.beacon.timestamp = cpu_to_le64(
797− rx_status.mactime +
798− (data->tsf_offset - data2->tsf_offset) +
799− 24 * 8 * 10 / txrate->bitrate);
800−
808+ rx_status.mactime = now + data2->tsf_offset;
801809 #if 0
802810 /*
803811 * Don't enable this code by default as the OUI 00:00:00
@@ -987,7 +995,11 @@ static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, · 183 unmodified lines
987995 static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
988996 struct ieee80211_vif *vif)
989997 {
990− struct ieee80211_hw *hw = arg;
998+ struct mac80211_hwsim_data *data = arg;
999+ struct ieee80211_hw *hw = data->hw;
1000+ struct ieee80211_tx_info *info;
1001+ struct ieee80211_rate *txrate;
1002+ struct ieee80211_mgmt *mgmt;
9911003 struct sk_buff *skb;
9921004
9931005 hwsim_check_magic(vif);
@@ -1000,6 +1012,15 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, · 6 unmodified lines
10001012 skb = ieee80211_beacon_get(hw, vif);
10011013 if (skb == NULL)
10021014 return;
1015+ info = IEEE80211_SKB_CB(skb);
1016+ txrate = ieee80211_get_tx_rate(hw, info);
1017+
1018+ mgmt = (struct ieee80211_mgmt *) skb->data;
1019+ /* fake header transmission time */
1020+ data->abs_bcn_ts = mac80211_hwsim_get_tsf_raw();
1021+ mgmt->u.beacon.timestamp = cpu_to_le64(data->abs_bcn_ts +
1022+ data->tsf_offset +
1023+ 24 * 8 * 10 / txrate->bitrate);
10031024
10041025 mac80211_hwsim_tx_frame(hw, skb,
10051026 rcu_dereference(vif->chanctx_conf)->def.chan);
@@ -1020,7 +1041,7 @@ mac80211_hwsim_beacon(struct hrtimer *timer) · 14 unmodified lines
10201041
10211042 ieee80211_iterate_active_interfaces_atomic(
10221043 hw, IEEE80211_IFACE_ITER_NORMAL,
1023− mac80211_hwsim_beacon_tx, hw);
1044+ mac80211_hwsim_beacon_tx, data);
10241045
10251046 /* beacon at new TBTT + beacon interval */
10261047 if (data->bcn_delta) {
drivers/net/wireless/mwifiex/11n.c+3−1
@@ -53,7 +53,9 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type, · 52 unmodified lines
5353 sizeof(sband->ht_cap.mcs));
5454
5555 if (priv->bss_mode == NL80211_IFTYPE_STATION ||
56− sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
56+ (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 &&
57+ (priv->adapter->sec_chan_offset !=
58+ IEEE80211_HT_PARAM_CHA_SEC_NONE)))
5759 /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
5860 SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask);
5961
drivers/net/wireless/mwifiex/11n_aggr.c+4−2
@@ -278,14 +278,16 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, · 277 unmodified lines
278278 dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
279279 break;
280280 case -1:
281− adapter->data_sent = false;
281+ if (adapter->iface_type != MWIFIEX_PCIE)
282+ adapter->data_sent = false;
282283 dev_err(adapter->dev, "%s: host_to_card failed: %#x\n",
283284 __func__, ret);
284285 adapter->dbg.num_tx_host_to_card_failure++;
285286 mwifiex_write_data_complete(adapter, skb_aggr, 1, ret);
286287 return 0;
287288 case -EINPROGRESS:
288− adapter->data_sent = false;
289+ if (adapter->iface_type != MWIFIEX_PCIE)
290+ adapter->data_sent = false;
289291 break;
290292 case 0:
291293 mwifiex_write_data_complete(adapter, skb_aggr, 1, ret);
drivers/net/wireless/mwifiex/cfg80211.c+5−16
@@ -1325,6 +1325,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, · 1324 unmodified lines
13251325 }
13261326
13271327 mwifiex_set_ht_params(priv, bss_cfg, params);
1328+ mwifiex_set_wmm_params(priv, bss_cfg, params);
13281329
13291330 if (params->inactivity_timeout > 0) {
13301331 /* sta_ao_timer/ps_sta_ao_timer is in unit of 100ms */
@@ -1457,7 +1458,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, · 126 unmodified lines
14571458 struct cfg80211_ssid req_ssid;
14581459 int ret, auth_type = 0;
14591460 struct cfg80211_bss *bss = NULL;
1460− u8 is_scanning_required = 0, config_bands = 0;
1461+ u8 is_scanning_required = 0;
14611462
14621463 memset(&req_ssid, 0, sizeof(struct cfg80211_ssid));
14631464
@@ -1476,19 +1477,6 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, · 12 unmodified lines
14761477 /* disconnect before try to associate */
14771478 mwifiex_deauthenticate(priv, NULL);
14781479
1479− if (channel) {
1480− if (mode == NL80211_IFTYPE_STATION) {
1481− if (channel->band == IEEE80211_BAND_2GHZ)
1482− config_bands = BAND_B | BAND_G | BAND_GN;
1483− else
1484− config_bands = BAND_A | BAND_AN;
1485−
1486− if (!((config_bands | priv->adapter->fw_bands) &
1487− ~priv->adapter->fw_bands))
1488− priv->adapter->config_bands = config_bands;
1489− }
1490− }
1491−
14921480 /* As this is new association, clear locally stored
14931481 * keys and security related flags */
14941482 priv->sec_info.wpa_enabled = false;
@@ -1705,9 +1693,9 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv, · 210 unmodified lines
17051693
17061694 if (cfg80211_get_chandef_type(&params->chandef) !=
17071695 NL80211_CHAN_NO_HT)
1708− config_bands |= BAND_GN;
1696+ config_bands |= BAND_G | BAND_GN;
17091697 } else {
1710− if (cfg80211_get_chandef_type(&params->chandef) !=
1698+ if (cfg80211_get_chandef_type(&params->chandef) ==
17111699 NL80211_CHAN_NO_HT)
17121700 config_bands = BAND_A;
17131701 else
@@ -2259,6 +2247,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) · 545 unmodified lines
22592247 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
22602248 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
22612249 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
2250+ WIPHY_FLAG_AP_UAPSD |
22622251 WIPHY_FLAG_CUSTOM_REGULATORY |
22632252 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
22642253
drivers/net/wireless/mwifiex/decl.h+18−0
@@ -26,6 +26,7 @@ · 25 unmodified lines
2626 #include <linux/wait.h>
2727 #include <linux/timer.h>
2828 #include <linux/ieee80211.h>
29+#include <net/mac80211.h>
2930
3031
3132 #define MWIFIEX_MAX_BSS_NUM (3)
@@ -58,6 +59,8 @@ · 26 unmodified lines
5859 #define MWIFIEX_RTS_MAX_VALUE (2347)
5960 #define MWIFIEX_FRAG_MIN_VALUE (256)
6061 #define MWIFIEX_FRAG_MAX_VALUE (2346)
62+#define MWIFIEX_WMM_VERSION 0x01
63+#define MWIFIEX_WMM_SUBTYPE 0x01
6164
6265 #define MWIFIEX_RETRY_LIMIT 14
6366 #define MWIFIEX_SDIO_BLOCK_SIZE 256
@@ -126,4 +129,19 @@ enum mwifiex_wmm_ac_e { · 62 unmodified lines
126129 WMM_AC_VI,
127130 WMM_AC_VO
128131 } __packed;
132+
133+struct ieee_types_wmm_ac_parameters {
134+ u8 aci_aifsn_bitmap;
135+ u8 ecw_bitmap;
136+ __le16 tx_op_limit;
137+} __packed;
138+
139+struct mwifiex_types_wmm_info {
140+ u8 oui[4];
141+ u8 subtype;
142+ u8 version;
143+ u8 qos_info;
144+ u8 reserved;
145+ struct ieee_types_wmm_ac_parameters ac_params[IEEE80211_NUM_ACS];
146+} __packed;
129147 #endif /* !_MWIFIEX_DECL_H_ */
drivers/net/wireless/mwifiex/fw.h+8−6
@@ -330,6 +330,9 @@ enum P2P_MODES { · 329 unmodified lines
330330 #define HOST_SLEEP_CFG_GPIO_DEF 0xff
331331 #define HOST_SLEEP_CFG_GAP_DEF 0
332332
333+#define MWIFIEX_TIMEOUT_FOR_AP_RESP 0xfffc
334+#define MWIFIEX_STATUS_CODE_AUTH_TIMEOUT 2
335+
333336 #define CMD_F_HOSTCMD (1 << 0)
334337 #define CMD_F_CANCELED (1 << 1)
335338
@@ -1131,12 +1134,6 @@ struct ieee_types_vendor_header { · 795 unmodified lines
11311134 u8 version;
11321135 } __packed;
11331136
1134−struct ieee_types_wmm_ac_parameters {
1135− u8 aci_aifsn_bitmap;
1136− u8 ecw_bitmap;
1137− __le16 tx_op_limit;
1138−} __packed;
1139−
11401137 struct ieee_types_wmm_parameter {
11411138 /*
11421139 * WMM Parameter IE - Vendor Specific Header:
@@ -1186,6 +1183,11 @@ struct mwifiex_ie_types_htcap { · 43 unmodified lines
11861183 struct ieee80211_ht_cap ht_cap;
11871184 } __packed;
11881185
1186+struct mwifiex_ie_types_wmmcap {
1187+ struct mwifiex_ie_types_header header;
1188+ struct mwifiex_types_wmm_info wmm_info;
1189+} __packed;
1190+
11891191 struct mwifiex_ie_types_htinfo {
11901192 struct mwifiex_ie_types_header header;
11911193 struct ieee80211_ht_operation ht_oper;
drivers/net/wireless/mwifiex/init.c+6−0
@@ -591,6 +591,12 @@ int mwifiex_init_fw(struct mwifiex_adapter *adapter) · 590 unmodified lines
591591 return -1;
592592 }
593593 }
594+
595+ if (adapter->if_ops.init_fw_port) {
596+ if (adapter->if_ops.init_fw_port(adapter))
597+ return -1;
598+ }
599+
594600 for (i = 0; i < adapter->priv_num; i++) {
595601 if (adapter->priv[i]) {
596602 ret = mwifiex_sta_init_cmd(adapter->priv[i], first_sta);
drivers/net/wireless/mwifiex/ioctl.h+2−1
@@ -20,7 +20,6 @@ · 19 unmodified lines
2020 #ifndef _MWIFIEX_IOCTL_H_
2121 #define _MWIFIEX_IOCTL_H_
2222
23−#include <net/mac80211.h>
2423 #include <net/lib80211.h>
2524
2625 enum {
@@ -107,6 +106,8 @@ struct mwifiex_uap_bss_param { · 80 unmodified lines
107106 u8 rates[MWIFIEX_SUPPORTED_RATES];
108107 u32 sta_ao_timer;
109108 u32 ps_sta_ao_timer;
109+ u8 qos_info;
110+ struct mwifiex_types_wmm_info wmm_info;
110111 };
111112
112113 enum {
drivers/net/wireless/mwifiex/join.c+25−5
@@ -615,23 +615,33 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, · 614 unmodified lines
615615 struct ieee_types_assoc_rsp *assoc_rsp;
616616 struct mwifiex_bssdescriptor *bss_desc;
617617 u8 enable_data = true;
618+ u16 cap_info, status_code;
618619
619620 assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params;
620621
622+ cap_info = le16_to_cpu(assoc_rsp->cap_info_bitmap);
623+ status_code = le16_to_cpu(assoc_rsp->status_code);
624+
621625 priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN,
622626 sizeof(priv->assoc_rsp_buf));
623627
624628 memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size);
625629
626− if (le16_to_cpu(assoc_rsp->status_code)) {
630+ if (status_code) {
627631 priv->adapter->dbg.num_cmd_assoc_failure++;
628632 dev_err(priv->adapter->dev,
629633 "ASSOC_RESP: failed, status code=%d err=%#x a_id=%#x\n",
630− le16_to_cpu(assoc_rsp->status_code),
631− le16_to_cpu(assoc_rsp->cap_info_bitmap),
632− le16_to_cpu(assoc_rsp->a_id));
634+ status_code, cap_info, le16_to_cpu(assoc_rsp->a_id));
635+
636+ if (cap_info == MWIFIEX_TIMEOUT_FOR_AP_RESP) {
637+ if (status_code == MWIFIEX_STATUS_CODE_AUTH_TIMEOUT)
638+ ret = WLAN_STATUS_AUTH_TIMEOUT;
639+ else
640+ ret = WLAN_STATUS_UNSPECIFIED_FAILURE;
641+ } else {
642+ ret = status_code;
643+ }
633644
634− ret = le16_to_cpu(assoc_rsp->status_code);
635645 goto done;
636646 }
637647
@@ -969,6 +979,16 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, · 331 unmodified lines
969979 priv->adapter->config_bands);
970980 mwifiex_fill_cap_info(priv, radio_type, ht_cap);
971981
982+ if (adapter->sec_chan_offset ==
983+ IEEE80211_HT_PARAM_CHA_SEC_NONE) {
984+ u16 tmp_ht_cap;
985+
986+ tmp_ht_cap = le16_to_cpu(ht_cap->ht_cap.cap_info);
987+ tmp_ht_cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
988+ tmp_ht_cap &= ~IEEE80211_HT_CAP_SGI_40;
989+ ht_cap->ht_cap.cap_info = cpu_to_le16(tmp_ht_cap);
990+ }
991+
972992 pos += sizeof(struct mwifiex_ie_types_htcap);
973993 cmd_append_size += sizeof(struct mwifiex_ie_types_htcap);
974994
drivers/net/wireless/mwifiex/main.h+6−0
@@ -599,8 +599,10 @@ struct mwifiex_if_ops { · 598 unmodified lines
599599 int (*cmdrsp_complete) (struct mwifiex_adapter *, struct sk_buff *);
600600 int (*event_complete) (struct mwifiex_adapter *, struct sk_buff *);
601601 int (*data_complete) (struct mwifiex_adapter *, struct sk_buff *);
602+ int (*init_fw_port) (struct mwifiex_adapter *);
602603 int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *);
603604 void (*card_reset) (struct mwifiex_adapter *);
605+ int (*clean_pcie_ring) (struct mwifiex_adapter *adapter);
604606 };
605607
606608 struct mwifiex_adapter {
@@ -890,6 +892,10 @@ void mwifiex_set_ht_params(struct mwifiex_private *priv, · 283 unmodified lines
890892 struct cfg80211_ap_settings *params);
891893 void mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg,
892894 struct cfg80211_ap_settings *params);
895+void
896+mwifiex_set_wmm_params(struct mwifiex_private *priv,
897+ struct mwifiex_uap_bss_param *bss_cfg,
898+ struct cfg80211_ap_settings *params);
893899
894900 /*
895901 * This function checks if the queuing is RA based or not.
drivers/net/wireless/mwifiex/pcie.c+452−204
@@ -39,17 +39,20 @@ static struct semaphore add_remove_card_sem; · 38 unmodified lines
3939 static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter);
4040 static int mwifiex_pcie_resume(struct pci_dev *pdev);
4141
42−/*
43− * This function is called after skb allocation to update
44− * "skb->cb" with physical address of data pointer.
45− */
46−static phys_addr_t *mwifiex_update_sk_buff_pa(struct sk_buff *skb)
42+static int
43+mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
44+ int size, int flags)
4745 {
48− phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb);
49−
50− *buf_pa = (phys_addr_t)virt_to_phys(skb->data);
46+ struct pcie_service_card *card = adapter->card;
47+ dma_addr_t buf_pa;
5148
52− return buf_pa;
49+ buf_pa = pci_map_single(card->dev, skb->data, size, flags);
50+ if (pci_dma_mapping_error(card->dev, buf_pa)) {
51+ dev_err(adapter->dev, "failed to map pci memory!\n");
52+ return -1;
53+ }
54+ memcpy(skb->cb, &buf_pa, sizeof(dma_addr_t));
55+ return 0;
5356 }
5457
5558 /*
@@ -60,8 +63,8 @@ static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter) · 4 unmodified lines
6063 u32 *cookie_addr;
6164 struct pcie_service_card *card = adapter->card;
6265
63− if (card->sleep_cookie) {
64− cookie_addr = (u32 *)card->sleep_cookie->data;
66+ if (card->sleep_cookie_vbase) {
67+ cookie_addr = (u32 *)card->sleep_cookie_vbase;
6568 dev_dbg(adapter->dev, "info: ACCESS_HW: sleep cookie=0x%x\n",
6669 *cookie_addr);
6770 if (*cookie_addr == FW_AWAKE_COOKIE)
@@ -161,7 +164,7 @@ static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state) · 93 unmodified lines
161164
162165 if (pdev) {
163166 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
164− if (!card || card->adapter) {
167+ if (!card || !card->adapter) {
165168 pr_err("Card or adapter structure is not valid\n");
166169 return 0;
167170 }
@@ -366,9 +369,7 @@ static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter) · 198 unmodified lines
366369 static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
367370 {
368371 struct pcie_service_card *card = adapter->card;
369− struct sk_buff *skb;
370372 int i;
371− phys_addr_t *buf_pa;
372373
373374 /*
374375 * driver maintaines the write pointer and firmware maintaines the read
@@ -384,16 +385,18 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) · 9 unmodified lines
384385 MWIFIEX_MAX_TXRX_BD;
385386 dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
386387 card->txbd_ring_size);
387− card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL);
388+ card->txbd_ring_vbase = pci_alloc_consistent(card->dev,
389+ card->txbd_ring_size,
390+ &card->txbd_ring_pbase);
388391 if (!card->txbd_ring_vbase) {
389− dev_err(adapter->dev, "Unable to alloc buffer for txbd ring\n");
392+ dev_err(adapter->dev,
393+ "allocate consistent memory (%d bytes) failed!\n",
394+ card->txbd_ring_size);
390395 return -ENOMEM;
391396 }
392− card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase);
393−
394397 dev_dbg(adapter->dev,
395398 "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
396− card->txbd_ring_vbase, (u32)card->txbd_ring_pbase,
399+ card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase,
397400 (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size);
398401
399402 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
@@ -402,24 +405,9 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) · 2 unmodified lines
402405 (sizeof(struct mwifiex_pcie_buf_desc)
403406 * i));
404407
405− /* Allocate buffer here so that firmware can DMA data from it */
406− skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
407− if (!skb) {
408− dev_err(adapter->dev, "Unable to allocate skb for TX ring.\n");
409− kfree(card->txbd_ring_vbase);
410− return -ENOMEM;
411− }
412− buf_pa = mwifiex_update_sk_buff_pa(skb);
413−
414− skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE);
415− dev_dbg(adapter->dev, "info: TX ring: add new skb base: %p, "
416− "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n",
417− skb, skb->data, (u32)*buf_pa,
418− (u32)(((u64)*buf_pa >> 32)), skb->len);
419−
420− card->tx_buf_list[i] = skb;
421− card->txbd_ring[i]->paddr = *buf_pa;
422− card->txbd_ring[i]->len = (u16)skb->len;
408+ card->tx_buf_list[i] = NULL;
409+ card->txbd_ring[i]->paddr = 0;
410+ card->txbd_ring[i]->len = 0;
423411 card->txbd_ring[i]->flags = 0;
424412 }
425413
@@ -429,11 +417,16 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) · 3 unmodified lines
429417 static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
430418 {
431419 struct pcie_service_card *card = adapter->card;
420+ struct sk_buff *skb;
432421 int i;
433422
434423 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
435− if (card->tx_buf_list[i])
436− dev_kfree_skb_any(card->tx_buf_list[i]);
424+ if (card->tx_buf_list[i]) {
425+ skb = card->tx_buf_list[i];
426+ pci_unmap_single(card->dev, card->txbd_ring[i]->paddr,
427+ skb->len, PCI_DMA_TODEVICE);
428+ dev_kfree_skb_any(skb);
429+ }
437430 card->tx_buf_list[i] = NULL;
438431 card->txbd_ring[i]->paddr = 0;
439432 card->txbd_ring[i]->len = 0;
@@ -441,11 +434,15 @@ static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter) · 1 unmodified line
441434 card->txbd_ring[i] = NULL;
442435 }
443436
444− kfree(card->txbd_ring_vbase);
437+ if (card->txbd_ring_vbase)
438+ pci_free_consistent(card->dev, card->txbd_ring_size,
439+ card->txbd_ring_vbase,
440+ card->txbd_ring_pbase);
445441 card->txbd_ring_size = 0;
446442 card->txbd_wrptr = 0;
447443 card->txbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND;
448444 card->txbd_ring_vbase = NULL;
445+ card->txbd_ring_pbase = 0;
449446
450447 return 0;
451448 }
@@ -458,7 +455,7 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) · 6 unmodified lines
458455 struct pcie_service_card *card = adapter->card;
459456 struct sk_buff *skb;
460457 int i;
461− phys_addr_t *buf_pa;
458+ dma_addr_t buf_pa;
462459
463460 /*
464461 * driver maintaines the read pointer and firmware maintaines the write
@@ -472,13 +469,15 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) · 7 unmodified lines
472469 MWIFIEX_MAX_TXRX_BD;
473470 dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
474471 card->rxbd_ring_size);
475− card->rxbd_ring_vbase = kzalloc(card->rxbd_ring_size, GFP_KERNEL);
472+ card->rxbd_ring_vbase = pci_alloc_consistent(card->dev,
473+ card->rxbd_ring_size,
474+ &card->rxbd_ring_pbase);
476475 if (!card->rxbd_ring_vbase) {
477− dev_err(adapter->dev, "Unable to allocate buffer for "
478− "rxbd_ring.\n");
476+ dev_err(adapter->dev,
477+ "allocate consistent memory (%d bytes) failed!\n",
478+ card->rxbd_ring_size);
479479 return -ENOMEM;
480480 }
481− card->rxbd_ring_pbase = virt_to_phys(card->rxbd_ring_vbase);
482481
483482 dev_dbg(adapter->dev,
484483 "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
@@ -500,16 +499,20 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) · 15 unmodified lines
500499 kfree(card->rxbd_ring_vbase);
501500 return -ENOMEM;
502501 }
503− buf_pa = mwifiex_update_sk_buff_pa(skb);
504− skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE);
502+ if (mwifiex_map_pci_memory(adapter, skb,
503+ MWIFIEX_RX_DATA_BUF_SIZE,
504+ PCI_DMA_FROMDEVICE))
505+ return -1;
506+
507+ MWIFIEX_SKB_PACB(skb, &buf_pa);
505508
506509 dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, "
507510 "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n",
508− skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32),
511+ skb, skb->data, (u32)buf_pa, (u32)((u64)buf_pa >> 32),
509512 skb->len);
510513
511514 card->rx_buf_list[i] = skb;
512− card->rxbd_ring[i]->paddr = *buf_pa;
515+ card->rxbd_ring[i]->paddr = buf_pa;
513516 card->rxbd_ring[i]->len = (u16)skb->len;
514517 card->rxbd_ring[i]->flags = 0;
515518 }
@@ -523,11 +526,17 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) · 7 unmodified lines
523526 static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
524527 {
525528 struct pcie_service_card *card = adapter->card;
529+ struct sk_buff *skb;
526530 int i;
527531
528532 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
529− if (card->rx_buf_list[i])
530− dev_kfree_skb_any(card->rx_buf_list[i]);
533+ if (card->rx_buf_list[i]) {
534+ skb = card->rx_buf_list[i];
535+ pci_unmap_single(card->dev, card->rxbd_ring[i]->paddr ,
536+ MWIFIEX_RX_DATA_BUF_SIZE,
537+ PCI_DMA_FROMDEVICE);
538+ dev_kfree_skb_any(skb);
539+ }
531540 card->rx_buf_list[i] = NULL;
532541 card->rxbd_ring[i]->paddr = 0;
533542 card->rxbd_ring[i]->len = 0;
@@ -535,11 +544,15 @@ static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter) · 1 unmodified line
535544 card->rxbd_ring[i] = NULL;
536545 }
537546
538− kfree(card->rxbd_ring_vbase);
547+ if (card->rxbd_ring_vbase)
548+ pci_free_consistent(card->dev, card->rxbd_ring_size,
549+ card->rxbd_ring_vbase,
550+ card->rxbd_ring_pbase);
539551 card->rxbd_ring_size = 0;
540552 card->rxbd_wrptr = 0;
541553 card->rxbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND;
542554 card->rxbd_ring_vbase = NULL;
555+ card->rxbd_ring_pbase = 0;
543556
544557 return 0;
545558 }
@@ -552,7 +565,7 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) · 6 unmodified lines
552565 struct pcie_service_card *card = adapter->card;
553566 struct sk_buff *skb;
554567 int i;
555− phys_addr_t *buf_pa;
568+ dma_addr_t buf_pa;
556569
557570 /*
558571 * driver maintaines the read pointer and firmware maintaines the write
@@ -566,13 +579,15 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) · 7 unmodified lines
566579 MWIFIEX_MAX_EVT_BD;
567580 dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
568581 card->evtbd_ring_size);
569− card->evtbd_ring_vbase = kzalloc(card->evtbd_ring_size, GFP_KERNEL);
582+ card->evtbd_ring_vbase = pci_alloc_consistent(card->dev,
583+ card->evtbd_ring_size,
584+ &card->evtbd_ring_pbase);
570585 if (!card->evtbd_ring_vbase) {
571586 dev_err(adapter->dev,
572− "Unable to allocate buffer. Terminating download\n");
587+ "allocate consistent memory (%d bytes) failed!\n",
588+ card->evtbd_ring_size);
573589 return -ENOMEM;
574590 }
575− card->evtbd_ring_pbase = virt_to_phys(card->evtbd_ring_vbase);
576591
577592 dev_dbg(adapter->dev,
578593 "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
@@ -594,16 +609,20 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) · 15 unmodified lines
594609 kfree(card->evtbd_ring_vbase);
595610 return -ENOMEM;
596611 }
597− buf_pa = mwifiex_update_sk_buff_pa(skb);
598612 skb_put(skb, MAX_EVENT_SIZE);
599613
614+ if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
615+ PCI_DMA_FROMDEVICE))
616+ return -1;
617+
618+ MWIFIEX_SKB_PACB(skb, &buf_pa);
600619 dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, "
601620 "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n",
602− skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32),
621+ skb, skb->data, (u32)buf_pa, (u32)((u64)buf_pa >> 32),
603622 skb->len);
604623
605624 card->evt_buf_list[i] = skb;
606− card->evtbd_ring[i]->paddr = *buf_pa;
625+ card->evtbd_ring[i]->paddr = buf_pa;
607626 card->evtbd_ring[i]->len = (u16)skb->len;
608627 card->evtbd_ring[i]->flags = 0;
609628 }
@@ -617,11 +636,16 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) · 7 unmodified lines
617636 static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
618637 {
619638 struct pcie_service_card *card = adapter->card;
639+ struct sk_buff *skb;
620640 int i;
621641
622642 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
623− if (card->evt_buf_list[i])
624− dev_kfree_skb_any(card->evt_buf_list[i]);
643+ if (card->evt_buf_list[i]) {
644+ skb = card->evt_buf_list[i];
645+ pci_unmap_single(card->dev, card->evtbd_ring[i]->paddr,
646+ MAX_EVENT_SIZE, PCI_DMA_FROMDEVICE);
647+ dev_kfree_skb_any(skb);
648+ }
625649 card->evt_buf_list[i] = NULL;
626650 card->evtbd_ring[i]->paddr = 0;
627651 card->evtbd_ring[i]->len = 0;
@@ -629,11 +653,15 @@ static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter) · 1 unmodified line
629653 card->evtbd_ring[i] = NULL;
630654 }
631655
632− kfree(card->evtbd_ring_vbase);
656+ if (card->evtbd_ring_vbase)
657+ pci_free_consistent(card->dev, card->evtbd_ring_size,
658+ card->evtbd_ring_vbase,
659+ card->evtbd_ring_pbase);
633660 card->evtbd_wrptr = 0;
634661 card->evtbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND;
635662 card->evtbd_ring_size = 0;
636663 card->evtbd_ring_vbase = NULL;
664+ card->evtbd_ring_pbase = 0;
637665
638666 return 0;
639667 }
@@ -653,21 +681,12 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter) · 13 unmodified lines
653681 "Unable to allocate skb for command response data.\n");
654682 return -ENOMEM;
655683 }
656− mwifiex_update_sk_buff_pa(skb);
657684 skb_put(skb, MWIFIEX_UPLD_SIZE);
658− card->cmdrsp_buf = skb;
685+ if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
686+ PCI_DMA_FROMDEVICE))
687+ return -1;
659688
660− skb = NULL;
661− /* Allocate memory for sending command to firmware */
662− skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER);
663− if (!skb) {
664− dev_err(adapter->dev,
665− "Unable to allocate skb for command data.\n");
666− return -ENOMEM;
667− }
668− mwifiex_update_sk_buff_pa(skb);
669− skb_put(skb, MWIFIEX_SIZE_OF_CMD_BUFFER);
670− card->cmd_buf = skb;
689+ card->cmdrsp_buf = skb;
671690
672691 return 0;
673692 }
@@ -678,18 +697,26 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter) · 4 unmodified lines
678697 static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
679698 {
680699 struct pcie_service_card *card;
700+ dma_addr_t buf_pa;
681701
682702 if (!adapter)
683703 return 0;
684704
685705 card = adapter->card;
686706
687− if (card && card->cmdrsp_buf)
707+ if (card && card->cmdrsp_buf) {
708+ MWIFIEX_SKB_PACB(card->cmdrsp_buf, &buf_pa);
709+ pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
710+ PCI_DMA_FROMDEVICE);
688711 dev_kfree_skb_any(card->cmdrsp_buf);
712+ }
689713
690− if (card && card->cmd_buf)
714+ if (card && card->cmd_buf) {
715+ MWIFIEX_SKB_PACB(card->cmd_buf, &buf_pa);
716+ pci_unmap_single(card->dev, buf_pa, MWIFIEX_SIZE_OF_CMD_BUFFER,
717+ PCI_DMA_TODEVICE);
691718 dev_kfree_skb_any(card->cmd_buf);
692−
719+ }
693720 return 0;
694721 }
695722
@@ -698,27 +725,19 @@ static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter) · 2 unmodified lines
698725 */
699726 static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
700727 {
701− struct sk_buff *skb;
702728 struct pcie_service_card *card = adapter->card;
703729
704− /* Allocate memory for sleep cookie */
705− skb = dev_alloc_skb(sizeof(u32));
706− if (!skb) {
707− dev_err(adapter->dev,
708− "Unable to allocate skb for sleep cookie!\n");
730+ card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
731+ &card->sleep_cookie_pbase);
732+ if (!card->sleep_cookie_vbase) {
733+ dev_err(adapter->dev, "pci_alloc_consistent failed!\n");
709734 return -ENOMEM;
710735 }
711− mwifiex_update_sk_buff_pa(skb);
712− skb_put(skb, sizeof(u32));
713−
714736 /* Init val of Sleep Cookie */
715− *(u32 *)skb->data = FW_AWAKE_COOKIE;
737+ *(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
716738
717739 dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
718− *((u32 *)skb->data));
719−
720− /* Save the sleep cookie */
721− card->sleep_cookie = skb;
740+ *((u32 *)card->sleep_cookie_vbase));
722741
723742 return 0;
724743 }
@@ -735,24 +754,57 @@ static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter) · 10 unmodified lines
735754
736755 card = adapter->card;
737756
738− if (card && card->sleep_cookie) {
739− dev_kfree_skb_any(card->sleep_cookie);
740− card->sleep_cookie = NULL;
757+ if (card && card->sleep_cookie_vbase) {
758+ pci_free_consistent(card->dev, sizeof(u32),
759+ card->sleep_cookie_vbase,
760+ card->sleep_cookie_pbase);
761+ card->sleep_cookie_vbase = NULL;
741762 }
742763
743764 return 0;
744765 }
745766
767+/* This function flushes the TX buffer descriptor ring
768+ * This function defined as handler is also called while cleaning TXRX
769+ * during disconnect/ bss stop.
770+ */
771+static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
772+{
773+ struct pcie_service_card *card = adapter->card;
774+ u32 rdptr;
775+
776+ /* Read the TX ring read pointer set by firmware */
777+ if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) {
778+ dev_err(adapter->dev,
779+ "Flush TXBD: failed to read REG_TXBD_RDPTR\n");
780+ return -1;
781+ }
782+
783+ if (!mwifiex_pcie_txbd_empty(card, rdptr)) {
784+ card->txbd_flush = 1;
785+ /* write pointer already set at last send
786+ * send dnld-rdy intr again, wait for completion.
787+ */
788+ if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
789+ CPU_INTR_DNLD_RDY)) {
790+ dev_err(adapter->dev,
791+ "failed to assert dnld-rdy interrupt.\n");
792+ return -1;
793+ }
794+ }
795+ return 0;
796+}
797+
746798 /*
747− * This function sends data buffer to device
799+ * This function unmaps and frees downloaded data buffer
748800 */
749−static int
750−mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb)
801+static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
751802 {
803+ const u32 num_tx_buffs = MWIFIEX_MAX_TXRX_BD;
804+ struct sk_buff *skb;
805+ dma_addr_t buf_pa;
806+ u32 wrdoneidx, rdptr, unmap_count = 0;
752807 struct pcie_service_card *card = adapter->card;
753− u32 wrindx, rdptr;
754− phys_addr_t *buf_pa;
755− __le16 *tmp;
756808
757809 if (!mwifiex_pcie_ok_to_access_hw(adapter))
758810 mwifiex_pm_wakeup_card(adapter);
@@ -760,34 +812,112 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) · 1 unmodified line
760812 /* Read the TX ring read pointer set by firmware */
761813 if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) {
762814 dev_err(adapter->dev,
763− "SEND DATA: failed to read REG_TXBD_RDPTR\n");
815+ "SEND COMP: failed to read REG_TXBD_RDPTR\n");
764816 return -1;
765817 }
766818
767− wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK;
819+ dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
820+ card->txbd_rdptr, rdptr);
768821
769− dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n", rdptr,
770− card->txbd_wrptr);
771− if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) !=
772− (rdptr & MWIFIEX_TXBD_MASK)) ||
773− ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) !=
774− (rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) {
775− struct sk_buff *skb_data;
822+ /* free from previous txbd_rdptr to current txbd_rdptr */
823+ while (((card->txbd_rdptr & MWIFIEX_TXBD_MASK) !=
824+ (rdptr & MWIFIEX_TXBD_MASK)) ||
825+ ((card->txbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) !=
826+ (rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) {
827+ wrdoneidx = card->txbd_rdptr & MWIFIEX_TXBD_MASK;
828+
829+ skb = card->tx_buf_list[wrdoneidx];
830+ if (skb) {
831+ dev_dbg(adapter->dev,
832+ "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
833+ skb, wrdoneidx);
834+ MWIFIEX_SKB_PACB(skb, &buf_pa);
835+ pci_unmap_single(card->dev, buf_pa, skb->len,
836+ PCI_DMA_TODEVICE);
837+
838+ unmap_count++;
839+
840+ if (card->txbd_flush)
841+ mwifiex_write_data_complete(adapter, skb, 0,
842+ -1);
843+ else
844+ mwifiex_write_data_complete(adapter, skb, 0, 0);
845+ }
846+
847+ card->tx_buf_list[wrdoneidx] = NULL;
848+ card->txbd_ring[wrdoneidx]->paddr = 0;
849+ card->rxbd_ring[wrdoneidx]->len = 0;
850+ card->rxbd_ring[wrdoneidx]->flags = 0;
851+ card->txbd_rdptr++;
852+
853+ if ((card->txbd_rdptr & MWIFIEX_TXBD_MASK) == num_tx_buffs)
854+ card->txbd_rdptr = ((card->txbd_rdptr &
855+ MWIFIEX_BD_FLAG_ROLLOVER_IND) ^
856+ MWIFIEX_BD_FLAG_ROLLOVER_IND);
857+ }
858+
859+ if (unmap_count)
860+ adapter->data_sent = false;
861+
862+ if (card->txbd_flush) {
863+ if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) ==
864+ (card->txbd_rdptr & MWIFIEX_TXBD_MASK)) &&
865+ ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) !=
866+ (card->txbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND)))
867+ card->txbd_flush = 0;
868+ else
869+ mwifiex_clean_pcie_ring_buf(adapter);
870+ }
871+
872+ return 0;
873+}
874+
875+/* This function sends data buffer to device. First 4 bytes of payload
876+ * are filled with payload length and payload type. Then this payload
877+ * is mapped to PCI device memory. Tx ring pointers are advanced accordingly.
878+ * Download ready interrupt to FW is deffered if Tx ring is not full and
879+ * additional payload can be accomodated.
880+ */
881+static int
882+mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
883+ struct mwifiex_tx_param *tx_param)
884+{
885+ struct pcie_service_card *card = adapter->card;
886+ u32 wrindx;
887+ int ret;
888+ dma_addr_t buf_pa;
889+ __le16 *tmp;
890+
891+ if (!(skb->data && skb->len)) {
892+ dev_err(adapter->dev, "%s(): invalid parameter <%p, %#x>\n",
893+ __func__, skb->data, skb->len);
894+ return -1;
895+ }
896+
897+ if (!mwifiex_pcie_ok_to_access_hw(adapter))
898+ mwifiex_pm_wakeup_card(adapter);
899+
900+ dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
901+ card->txbd_rdptr, card->txbd_wrptr);
902+ if (mwifiex_pcie_txbd_not_full(card)) {
776903 u8 *payload;
777904
778905 adapter->data_sent = true;
779− skb_data = card->tx_buf_list[wrindx];
780− memcpy(skb_data->data, skb->data, skb->len);
781− payload = skb_data->data;
906+ payload = skb->data;
782907 tmp = (__le16 *)&payload[0];
783908 *tmp = cpu_to_le16((u16)skb->len);
784909 tmp = (__le16 *)&payload[2];
785910 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
786− skb_put(skb_data, MWIFIEX_RX_DATA_BUF_SIZE - skb_data->len);
787− skb_trim(skb_data, skb->len);
788− buf_pa = MWIFIEX_SKB_PACB(skb_data);
789− card->txbd_ring[wrindx]->paddr = *buf_pa;
790− card->txbd_ring[wrindx]->len = (u16)skb_data->len;
911+
912+ if (mwifiex_map_pci_memory(adapter, skb, skb->len ,
913+ PCI_DMA_TODEVICE))
914+ return -1;
915+
916+ wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK;
917+ MWIFIEX_SKB_PACB(skb, &buf_pa);
918+ card->tx_buf_list[wrindx] = skb;
919+ card->txbd_ring[wrindx]->paddr = buf_pa;
920+ card->txbd_ring[wrindx]->len = (u16)skb->len;
791921 card->txbd_ring[wrindx]->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
792922 MWIFIEX_BD_FLAG_LAST_DESC;
793923
@@ -802,19 +932,28 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) · 8 unmodified lines
802932 card->txbd_wrptr)) {
803933 dev_err(adapter->dev,
804934 "SEND DATA: failed to write REG_TXBD_WRPTR\n");
805− return 0;
935+ ret = -1;
936+ goto done_unmap;
806937 }
807−
808− /* Send the TX ready interrupt */
809− if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
810− CPU_INTR_DNLD_RDY)) {
811− dev_err(adapter->dev,
812− "SEND DATA: failed to assert door-bell intr\n");
813− return -1;
938+ if ((mwifiex_pcie_txbd_not_full(card)) &&
939+ tx_param->next_pkt_len) {
940+ /* have more packets and TxBD still can hold more */
941+ dev_dbg(adapter->dev,
942+ "SEND DATA: delay dnld-rdy interrupt.\n");
943+ adapter->data_sent = false;
944+ } else {
945+ /* Send the TX ready interrupt */
946+ if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
947+ CPU_INTR_DNLD_RDY)) {
948+ dev_err(adapter->dev,
949+ "SEND DATA: failed to assert dnld-rdy interrupt.\n");
950+ ret = -1;
951+ goto done_unmap;
952+ }
814953 }
815954 dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
816955 "%#x> and sent packet to firmware successfully\n",
817− rdptr, card->txbd_wrptr);
956+ card->txbd_rdptr, card->txbd_wrptr);
818957 } else {
819958 dev_dbg(adapter->dev,
820959 "info: TX Ring full, can't send packets to fw\n");
@@ -827,7 +966,15 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) · 6 unmodified lines
827966 return -EBUSY;
828967 }
829968
830− return 0;
969+ return -EINPROGRESS;
970+done_unmap:
971+ MWIFIEX_SKB_PACB(skb, &buf_pa);
972+ pci_unmap_single(card->dev, buf_pa, skb->len, PCI_DMA_TODEVICE);
973+ card->tx_buf_list[wrindx] = NULL;
974+ card->txbd_ring[wrindx]->paddr = 0;
975+ card->txbd_ring[wrindx]->len = 0;
976+ card->txbd_ring[wrindx]->flags = 0;
977+ return ret;
831978 }
832979
833980 /*
@@ -838,9 +985,13 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) · 4 unmodified lines
838985 {
839986 struct pcie_service_card *card = adapter->card;
840987 u32 wrptr, rd_index;
988+ dma_addr_t buf_pa;
841989 int ret = 0;
842990 struct sk_buff *skb_tmp = NULL;
843991
992+ if (!mwifiex_pcie_ok_to_access_hw(adapter))
993+ mwifiex_pm_wakeup_card(adapter);
994+
844995 /* Read the RX ring Write pointer set by firmware */
845996 if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) {
846997 dev_err(adapter->dev,
@@ -848,6 +999,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) · 1 unmodified line
848999 ret = -1;
8491000 goto done;
8501001 }
1002+ card->rxbd_wrptr = wrptr;
8511003
8521004 while (((wrptr & MWIFIEX_RXBD_MASK) !=
8531005 (card->rxbd_rdptr & MWIFIEX_RXBD_MASK)) ||
@@ -855,27 +1007,50 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) · 1 unmodified line
8551007 (card->rxbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) {
8561008 struct sk_buff *skb_data;
8571009 u16 rx_len;
1010+ __le16 pkt_len;
8581011
8591012 rd_index = card->rxbd_rdptr & MWIFIEX_RXBD_MASK;
8601013 skb_data = card->rx_buf_list[rd_index];
8611014
1015+ MWIFIEX_SKB_PACB(skb_data, &buf_pa);
1016+ pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE,
1017+ PCI_DMA_FROMDEVICE);
1018+ card->rx_buf_list[rd_index] = NULL;
1019+
8621020 /* Get data length from interface header -
863− first byte is len, second byte is type */
864− rx_len = *((u16 *)skb_data->data);
1021+ * first 2 bytes for len, next 2 bytes is for type
1022+ */
1023+ pkt_len = *((__le16 *)skb_data->data);
1024+ rx_len = le16_to_cpu(pkt_len);
1025+ skb_put(skb_data, rx_len);
8651026 dev_dbg(adapter->dev,
8661027 "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
8671028 card->rxbd_rdptr, wrptr, rx_len);
868− skb_tmp = dev_alloc_skb(rx_len);
1029+ skb_pull(skb_data, INTF_HEADER_LEN);
1030+ mwifiex_handle_rx_packet(adapter, skb_data);
1031+
1032+ skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
8691033 if (!skb_tmp) {
870− dev_dbg(adapter->dev,
871− "info: Failed to alloc skb for RX\n");
872− ret = -EBUSY;
873− goto done;
1034+ dev_err(adapter->dev,
1035+ "Unable to allocate skb.\n");
1036+ return -ENOMEM;
8741037 }
8751038
876− skb_put(skb_tmp, rx_len);
1039+ if (mwifiex_map_pci_memory(adapter, skb_tmp,
1040+ MWIFIEX_RX_DATA_BUF_SIZE,
1041+ PCI_DMA_FROMDEVICE))
1042+ return -1;
1043+
1044+ MWIFIEX_SKB_PACB(skb_tmp, &buf_pa);
1045+
1046+ dev_dbg(adapter->dev,
1047+ "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
1048+ skb_tmp, rd_index);
1049+ card->rx_buf_list[rd_index] = skb_tmp;
1050+ card->rxbd_ring[rd_index]->paddr = buf_pa;
1051+ card->rxbd_ring[rd_index]->len = skb_tmp->len;
1052+ card->rxbd_ring[rd_index]->flags = 0;
8771053
878− memcpy(skb_tmp->data, skb_data->data + INTF_HEADER_LEN, rx_len);
8791054 if ((++card->rxbd_rdptr & MWIFIEX_RXBD_MASK) ==
8801055 MWIFIEX_MAX_TXRX_BD) {
8811056 card->rxbd_rdptr = ((card->rxbd_rdptr &
@@ -903,12 +1078,10 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) · 21 unmodified lines
9031078 }
9041079 dev_dbg(adapter->dev,
9051080 "info: RECV DATA: Rcvd packet from fw successfully\n");
906− mwifiex_handle_rx_packet(adapter, skb_tmp);
1081+ card->rxbd_wrptr = wrptr;
9071082 }
9081083
9091084 done:
910− if (ret && skb_tmp)
911− dev_kfree_skb_any(skb_tmp);
9121085 return ret;
9131086 }
9141087
@@ -918,32 +1091,41 @@ done: · 3 unmodified lines
9181091 static int
9191092 mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
9201093 {
921− phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb);
1094+ dma_addr_t buf_pa;
1095+ struct pcie_service_card *card = adapter->card;
9221096
923− if (!(skb->data && skb->len && *buf_pa)) {
1097+ if (!(skb->data && skb->len)) {
9241098 dev_err(adapter->dev,
925− "Invalid parameter in %s <%p, %#x:%x, %x>\n",
926− __func__, skb->data, skb->len,
927− (u32)*buf_pa, (u32)((u64)*buf_pa >> 32));
1099+ "Invalid parameter in %s <%p. len %d>\n",
1100+ __func__, skb->data, skb->len);
9281101 return -1;
9291102 }
9301103
1104+ if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE))
1105+ return -1;
1106+
1107+ MWIFIEX_SKB_PACB(skb, &buf_pa);
1108+
9311109 /* Write the lower 32bits of the physical address to scratch
9321110 * register 0 */
933− if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)*buf_pa)) {
1111+ if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)buf_pa)) {
9341112 dev_err(adapter->dev,
9351113 "%s: failed to write download command to boot code.\n",
9361114 __func__);
1115+ pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1116+ PCI_DMA_TODEVICE);
9371117 return -1;
9381118 }
9391119
9401120 /* Write the upper 32bits of the physical address to scratch
9411121 * register 1 */
9421122 if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG,
943− (u32)((u64)*buf_pa >> 32))) {
1123+ (u32)((u64)buf_pa >> 32))) {
9441124 dev_err(adapter->dev,
9451125 "%s: failed to write download command to boot code.\n",
9461126 __func__);
1127+ pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1128+ PCI_DMA_TODEVICE);
9471129 return -1;
9481130 }
9491131
@@ -952,6 +1134,8 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) · 2 unmodified lines
9521134 dev_err(adapter->dev,
9531135 "%s: failed to write command len to scratch reg 2\n",
9541136 __func__);
1137+ pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1138+ PCI_DMA_TODEVICE);
9551139 return -1;
9561140 }
9571141
@@ -960,22 +1144,39 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) · 2 unmodified lines
9601144 CPU_INTR_DOOR_BELL)) {
9611145 dev_err(adapter->dev,
9621146 "%s: failed to assert door-bell intr\n", __func__);
1147+ pci_unmap_single(card->dev, buf_pa,
1148+ MWIFIEX_UPLD_SIZE, PCI_DMA_TODEVICE);
9631149 return -1;
9641150 }
9651151
9661152 return 0;
9671153 }
9681154
969−/*
970− * This function downloads commands to the device
1155+/* This function init rx port in firmware which in turn enables to receive data
1156+ * from device before transmitting any packet.
1157+ */
1158+static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
1159+{
1160+ struct pcie_service_card *card = adapter->card;
1161+
1162+ /* Write the RX ring read pointer in to REG_RXBD_RDPTR */
1163+ if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR, card->rxbd_rdptr | 0)) {
1164+ dev_err(adapter->dev,
1165+ "RECV DATA: failed to write REG_RXBD_RDPTR\n");
1166+ return -1;
1167+ }
1168+ return 0;
1169+}
1170+
1171+/* This function downloads commands to the device
9711172 */
9721173 static int
9731174 mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
9741175 {
9751176 struct pcie_service_card *card = adapter->card;
9761177 int ret = 0;
977− phys_addr_t *cmd_buf_pa;
978− phys_addr_t *cmdrsp_buf_pa;
1178+ dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
1179+ u8 *payload = (u8 *)skb->data;
9791180
9801181 if (!(skb->data && skb->len)) {
9811182 dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
@@ -990,17 +1191,18 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) · 8 unmodified lines
9901191 return -EBUSY;
9911192 }
9921193
993− /* Make sure a command buffer is available */
994− if (!card->cmd_buf) {
995− dev_err(adapter->dev, "Command buffer not available\n");
996− return -EBUSY;
997− }
1194+ if (!mwifiex_pcie_ok_to_access_hw(adapter))
1195+ mwifiex_pm_wakeup_card(adapter);
9981196
9991197 adapter->cmd_sent = true;
1000− /* Copy the given skb in to DMA accessable shared buffer */
1001− skb_put(card->cmd_buf, MWIFIEX_SIZE_OF_CMD_BUFFER - card->cmd_buf->len);
1002− skb_trim(card->cmd_buf, skb->len);
1003− memcpy(card->cmd_buf->data, skb->data, skb->len);
1198+
1199+ *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
1200+ *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);
1201+
1202+ if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1203+ return -1;
1204+
1205+ card->cmd_buf = skb;
10041206
10051207 /* To send a command, the driver will:
10061208 1. Write the 64bit physical address of the data buffer to
@@ -1013,11 +1215,11 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) · 6 unmodified lines
10131215 */
10141216
10151217 if (card->cmdrsp_buf) {
1016− cmdrsp_buf_pa = MWIFIEX_SKB_PACB(card->cmdrsp_buf);
1218+ MWIFIEX_SKB_PACB(card->cmdrsp_buf, &cmdrsp_buf_pa);
10171219 /* Write the lower 32bits of the cmdrsp buffer physical
10181220 address */
10191221 if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO,
1020− (u32)*cmdrsp_buf_pa)) {
1222+ (u32)cmdrsp_buf_pa)) {
10211223 dev_err(adapter->dev,
10221224 "Failed to write download cmd to boot code.\n");
10231225 ret = -1;
@@ -1026,7 +1228,7 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) · 2 unmodified lines
10261228 /* Write the upper 32bits of the cmdrsp buffer physical
10271229 address */
10281230 if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI,
1029− (u32)((u64)*cmdrsp_buf_pa >> 32))) {
1231+ (u32)((u64)cmdrsp_buf_pa >> 32))) {
10301232 dev_err(adapter->dev,
10311233 "Failed to write download cmd to boot code.\n");
10321234 ret = -1;
@@ -1034,9 +1236,9 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) · 1 unmodified line
10341236 }
10351237 }
10361238
1037− cmd_buf_pa = MWIFIEX_SKB_PACB(card->cmd_buf);
1239+ MWIFIEX_SKB_PACB(card->cmd_buf, &cmd_buf_pa);
10381240 /* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */
1039− if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, (u32)*cmd_buf_pa)) {
1241+ if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, (u32)cmd_buf_pa)) {
10401242 dev_err(adapter->dev,
10411243 "Failed to write download cmd to boot code.\n");
10421244 ret = -1;
@@ -1044,7 +1246,7 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) · 1 unmodified line
10441246 }
10451247 /* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */
10461248 if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI,
1047− (u32)((u64)*cmd_buf_pa >> 32))) {
1249+ (u32)((u64)cmd_buf_pa >> 32))) {
10481250 dev_err(adapter->dev,
10491251 "Failed to write download cmd to boot code.\n");
10501252 ret = -1;
@@ -1083,11 +1285,22 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) · 32 unmodified lines
10831285 struct pcie_service_card *card = adapter->card;
10841286 struct sk_buff *skb = card->cmdrsp_buf;
10851287 int count = 0;
1288+ u16 rx_len;
1289+ __le16 pkt_len;
1290+ dma_addr_t buf_pa;
10861291
10871292 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
10881293
1294+ MWIFIEX_SKB_PACB(skb, &buf_pa);
1295+ pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1296+ PCI_DMA_FROMDEVICE);
1297+
1298+ pkt_len = *((__le16 *)skb->data);
1299+ rx_len = le16_to_cpu(pkt_len);
1300+ skb_trim(skb, rx_len);
1301+ skb_pull(skb, INTF_HEADER_LEN);
1302+
10891303 if (!adapter->curr_cmd) {
1090− skb_pull(skb, INTF_HEADER_LEN);
10911304 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
10921305 mwifiex_process_sleep_confirm_resp(adapter, skb->data,
10931306 skb->len);
@@ -1100,9 +1313,12 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) · 6 unmodified lines
11001313 }
11011314 memcpy(adapter->upld_buf, skb->data,
11021315 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
1103− skb_push(skb, INTF_HEADER_LEN);
1316+ if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1317+ PCI_DMA_FROMDEVICE))
1318+ return -1;
1319+
1320+ MWIFIEX_SKB_PACB(skb, &buf_pa);
11041321 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
1105− skb_pull(skb, INTF_HEADER_LEN);
11061322 adapter->curr_cmd->resp_skb = skb;
11071323 adapter->cmd_resp_received = true;
11081324 /* Take the pointer and set it to CMD node and will
@@ -1136,10 +1352,23 @@ static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter, · 27 unmodified lines
11361352 struct sk_buff *skb)
11371353 {
11381354 struct pcie_service_card *card = adapter->card;
1355+ dma_addr_t buf_pa;
1356+ struct sk_buff *skb_tmp;
11391357
11401358 if (skb) {
11411359 card->cmdrsp_buf = skb;
11421360 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
1361+ if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1362+ PCI_DMA_FROMDEVICE))
1363+ return -1;
1364+ }
1365+
1366+ skb_tmp = card->cmd_buf;
1367+ if (skb_tmp) {
1368+ MWIFIEX_SKB_PACB(skb_tmp, &buf_pa);
1369+ pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1370+ PCI_DMA_FROMDEVICE);
1371+ card->cmd_buf = NULL;
11431372 }
11441373
11451374 return 0;
@@ -1153,6 +1382,10 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) · 7 unmodified lines
11531382 struct pcie_service_card *card = adapter->card;
11541383 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
11551384 u32 wrptr, event;
1385+ dma_addr_t buf_pa;
1386+
1387+ if (!mwifiex_pcie_ok_to_access_hw(adapter))
1388+ mwifiex_pm_wakeup_card(adapter);
11561389
11571390 if (adapter->event_received) {
11581391 dev_dbg(adapter->dev, "info: Event being processed, "
@@ -1184,6 +1417,10 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) · 25 unmodified lines
11841417
11851418 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
11861419 skb_cmd = card->evt_buf_list[rdptr];
1420+ MWIFIEX_SKB_PACB(skb_cmd, &buf_pa);
1421+ pci_unmap_single(card->dev, buf_pa, MAX_EVENT_SIZE,
1422+ PCI_DMA_FROMDEVICE);
1423+
11871424 /* Take the pointer and set it to event pointer in adapter
11881425 and will return back after event handling callback */
11891426 card->evt_buf_list[rdptr] = NULL;
@@ -1228,7 +1465,7 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, · 38 unmodified lines
12281465 int ret = 0;
12291466 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
12301467 u32 wrptr;
1231− phys_addr_t *buf_pa;
1468+ dma_addr_t buf_pa;
12321469
12331470 if (!skb)
12341471 return 0;
@@ -1248,9 +1485,14 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, · 13 unmodified lines
12481485
12491486 if (!card->evt_buf_list[rdptr]) {
12501487 skb_push(skb, INTF_HEADER_LEN);
1488+ if (mwifiex_map_pci_memory(adapter, skb,
1489+ MAX_EVENT_SIZE,
1490+ PCI_DMA_FROMDEVICE))
1491+ return -1;
1492+ MWIFIEX_SKB_PACB(skb, &buf_pa);
12511493 card->evt_buf_list[rdptr] = skb;
1252− buf_pa = MWIFIEX_SKB_PACB(skb);
1253− card->evtbd_ring[rdptr]->paddr = *buf_pa;
1494+ MWIFIEX_SKB_PACB(skb, &buf_pa);
1495+ card->evtbd_ring[rdptr]->paddr = buf_pa;
12541496 card->evtbd_ring[rdptr]->len = (u16)skb->len;
12551497 card->evtbd_ring[rdptr]->flags = 0;
12561498 skb = NULL;
@@ -1299,11 +1541,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, · 42 unmodified lines
12991541 struct sk_buff *skb;
13001542 u32 txlen, tx_blocks = 0, tries, len;
13011543 u32 block_retry_cnt = 0;
1302−
1303− if (!adapter) {
1304− pr_err("adapter structure is not valid\n");
1305− return -1;
1306− }
1544+ dma_addr_t buf_pa;
1545+ struct pcie_service_card *card = adapter->card;
13071546
13081547 if (!firmware || !firmware_len) {
13091548 dev_err(adapter->dev,
@@ -1325,7 +1564,6 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, · 15 unmodified lines
13251564 ret = -ENOMEM;
13261565 goto done;
13271566 }
1328− mwifiex_update_sk_buff_pa(skb);
13291567
13301568 /* Perform firmware data transfer */
13311569 do {
@@ -1400,6 +1638,9 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, · 68 unmodified lines
14001638 ret = -1;
14011639 goto done;
14021640 }
1641+
1642+ MWIFIEX_SKB_PACB(skb, &buf_pa);
1643+
14031644 /* Wait for the command done interrupt */
14041645 do {
14051646 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
@@ -1407,11 +1648,17 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, · 1 unmodified line
14071648 dev_err(adapter->dev, "%s: Failed to read "
14081649 "interrupt status during fw dnld.\n",
14091650 __func__);
1651+ pci_unmap_single(card->dev, buf_pa, skb->len,
1652+ PCI_DMA_TODEVICE);
14101653 ret = -1;
14111654 goto done;
14121655 }
14131656 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
14141657 CPU_INTR_DOOR_BELL);
1658+
1659+ pci_unmap_single(card->dev, buf_pa, skb->len,
1660+ PCI_DMA_TODEVICE);
1661+
14151662 offset += txlen;
14161663 } while (true);
14171664
@@ -1594,39 +1841,40 @@ exit: · 176 unmodified lines
15941841 static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
15951842 {
15961843 int ret;
1597− u32 pcie_ireg = 0;
1844+ u32 pcie_ireg;
15981845 unsigned long flags;
15991846
16001847 spin_lock_irqsave(&adapter->int_lock, flags);
16011848 /* Clear out unused interrupts */
1602− adapter->int_status &= HOST_INTR_MASK;
1849+ pcie_ireg = adapter->int_status;
1850+ adapter->int_status = 0;
16031851 spin_unlock_irqrestore(&adapter->int_lock, flags);
16041852
1605− while (adapter->int_status & HOST_INTR_MASK) {
1606− if (adapter->int_status & HOST_INTR_DNLD_DONE) {
1607− adapter->int_status &= ~HOST_INTR_DNLD_DONE;
1608− if (adapter->data_sent) {
1609− dev_dbg(adapter->dev, "info: DATA sent intr\n");
1610− adapter->data_sent = false;
1611− }
1853+ while (pcie_ireg & HOST_INTR_MASK) {
1854+ if (pcie_ireg & HOST_INTR_DNLD_DONE) {
1855+ pcie_ireg &= ~HOST_INTR_DNLD_DONE;
1856+ dev_dbg(adapter->dev, "info: TX DNLD Done\n");
1857+ ret = mwifiex_pcie_send_data_complete(adapter);
1858+ if (ret)
1859+ return ret;
16121860 }
1613− if (adapter->int_status & HOST_INTR_UPLD_RDY) {
1614− adapter->int_status &= ~HOST_INTR_UPLD_RDY;
1861+ if (pcie_ireg & HOST_INTR_UPLD_RDY) {
1862+ pcie_ireg &= ~HOST_INTR_UPLD_RDY;
16151863 dev_dbg(adapter->dev, "info: Rx DATA\n");
16161864 ret = mwifiex_pcie_process_recv_data(adapter);
16171865 if (ret)
16181866 return ret;
16191867 }
1620− if (adapter->int_status & HOST_INTR_EVENT_RDY) {
1621− adapter->int_status &= ~HOST_INTR_EVENT_RDY;
1868+ if (pcie_ireg & HOST_INTR_EVENT_RDY) {
1869+ pcie_ireg &= ~HOST_INTR_EVENT_RDY;
16221870 dev_dbg(adapter->dev, "info: Rx EVENT\n");
16231871 ret = mwifiex_pcie_process_event_ready(adapter);
16241872 if (ret)
16251873 return ret;
16261874 }
16271875
1628− if (adapter->int_status & HOST_INTR_CMD_DONE) {
1629− adapter->int_status &= ~HOST_INTR_CMD_DONE;
1876+ if (pcie_ireg & HOST_INTR_CMD_DONE) {
1877+ pcie_ireg &= ~HOST_INTR_CMD_DONE;
16301878 if (adapter->cmd_sent) {
16311879 dev_dbg(adapter->dev,
16321880 "info: CMD sent Interrupt\n");
@@ -1654,8 +1902,6 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) · 21 unmodified lines
16541902 "Write register failed\n");
16551903 return -1;
16561904 }
1657− adapter->int_status |= pcie_ireg;
1658− adapter->int_status &= HOST_INTR_MASK;
16591905 }
16601906
16611907 }
@@ -1687,7 +1933,7 @@ static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type, · 25 unmodified lines
16871933 }
16881934
16891935 if (type == MWIFIEX_TYPE_DATA)
1690− return mwifiex_pcie_send_data(adapter, skb);
1936+ return mwifiex_pcie_send_data(adapter, skb, tx_param);
16911937 else if (type == MWIFIEX_TYPE_CMD)
16921938 return mwifiex_pcie_send_cmd(adapter, skb);
16931939
@@ -1814,15 +2060,8 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter) · 120 unmodified lines
18142060 struct pcie_service_card *card = adapter->card;
18152061 struct pci_dev *pdev = card->dev;
18162062
1817− mwifiex_pcie_delete_sleep_cookie_buf(adapter);
1818− mwifiex_pcie_delete_cmdrsp_buf(adapter);
1819− mwifiex_pcie_delete_evtbd_ring(adapter);
1820− mwifiex_pcie_delete_rxbd_ring(adapter);
1821− mwifiex_pcie_delete_txbd_ring(adapter);
1822− card->cmdrsp_buf = NULL;
1823−
1824− dev_dbg(adapter->dev, "Clearing driver ready signature\n");
18252063 if (user_rmmod) {
2064+ dev_dbg(adapter->dev, "Clearing driver ready signature\n");
18262065 if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000))
18272066 dev_err(adapter->dev,
18282067 "Failed to write driver not-ready signature\n");
@@ -1879,6 +2118,13 @@ static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter) · 50 unmodified lines
18792118 if (card) {
18802119 dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__);
18812120 free_irq(card->dev->irq, card->dev);
2121+
2122+ mwifiex_pcie_delete_sleep_cookie_buf(adapter);
2123+ mwifiex_pcie_delete_cmdrsp_buf(adapter);
2124+ mwifiex_pcie_delete_evtbd_ring(adapter);
2125+ mwifiex_pcie_delete_rxbd_ring(adapter);
2126+ mwifiex_pcie_delete_txbd_ring(adapter);
2127+ card->cmdrsp_buf = NULL;
18822128 }
18832129 }
18842130
@@ -1900,6 +2146,8 @@ static struct mwifiex_if_ops pcie_ops = { · 15 unmodified lines
19002146 .event_complete = mwifiex_pcie_event_complete,
19012147 .update_mp_end_port = NULL,
19022148 .cleanup_mpa_buf = NULL,
2149+ .init_fw_port = mwifiex_pcie_init_fw_port,
2150+ .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
19032151 };
19042152
19052153 /*
drivers/net/wireless/mwifiex/pcie.h+29−4
@@ -114,11 +114,12 @@ struct pcie_service_card { · 113 unmodified lines
114114 struct pci_dev *dev;
115115 struct mwifiex_adapter *adapter;
116116
117+ u8 txbd_flush;
117118 u32 txbd_wrptr;
118119 u32 txbd_rdptr;
119120 u32 txbd_ring_size;
120121 u8 *txbd_ring_vbase;
121− phys_addr_t txbd_ring_pbase;
122+ dma_addr_t txbd_ring_pbase;
122123 struct mwifiex_pcie_buf_desc *txbd_ring[MWIFIEX_MAX_TXRX_BD];
123124 struct sk_buff *tx_buf_list[MWIFIEX_MAX_TXRX_BD];
124125
@@ -126,7 +127,7 @@ struct pcie_service_card { · 1 unmodified line
126127 u32 rxbd_rdptr;
127128 u32 rxbd_ring_size;
128129 u8 *rxbd_ring_vbase;
129− phys_addr_t rxbd_ring_pbase;
130+ dma_addr_t rxbd_ring_pbase;
130131 struct mwifiex_pcie_buf_desc *rxbd_ring[MWIFIEX_MAX_TXRX_BD];
131132 struct sk_buff *rx_buf_list[MWIFIEX_MAX_TXRX_BD];
132133
@@ -134,15 +135,39 @@ struct pcie_service_card { · 1 unmodified line
134135 u32 evtbd_rdptr;
135136 u32 evtbd_ring_size;
136137 u8 *evtbd_ring_vbase;
137− phys_addr_t evtbd_ring_pbase;
138+ dma_addr_t evtbd_ring_pbase;
138139 struct mwifiex_pcie_buf_desc *evtbd_ring[MWIFIEX_MAX_EVT_BD];
139140 struct sk_buff *evt_buf_list[MWIFIEX_MAX_EVT_BD];
140141
141142 struct sk_buff *cmd_buf;
142143 struct sk_buff *cmdrsp_buf;
143− struct sk_buff *sleep_cookie;
144+ u8 *sleep_cookie_vbase;
145+ dma_addr_t sleep_cookie_pbase;
144146 void __iomem *pci_mmap;
145147 void __iomem *pci_mmap1;
146148 };
147149
150+static inline int
151+mwifiex_pcie_txbd_empty(struct pcie_service_card *card, u32 rdptr)
152+{
153+ if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) ==
154+ (rdptr & MWIFIEX_TXBD_MASK)) &&
155+ ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) !=
156+ (rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND)))
157+ return 1;
158+
159+ return 0;
160+}
161+
162+static inline int
163+mwifiex_pcie_txbd_not_full(struct pcie_service_card *card)
164+{
165+ if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) !=
166+ (card->txbd_rdptr & MWIFIEX_TXBD_MASK)) ||
167+ ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) !=
168+ (card->txbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND)))
169+ return 1;
170+
171+ return 0;
172+}
148173 #endif /* _MWIFIEX_PCIE_H */
drivers/net/wireless/mwifiex/sta_cmd.c+5−5
@@ -931,7 +931,6 @@ mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv, · 930 unmodified lines
931931 struct host_cmd_ds_pcie_details *host_spec =
932932 &cmd->params.pcie_host_spec;
933933 struct pcie_service_card *card = priv->adapter->card;
934− phys_addr_t *buf_pa;
935934
936935 cmd->command = cpu_to_le16(HostCmd_CMD_PCIE_DESC_DETAILS);
937936 cmd->size = cpu_to_le16(sizeof(struct
@@ -953,10 +952,11 @@ mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv, · 15 unmodified lines
953952 host_spec->evtbd_addr_lo = (u32)(card->evtbd_ring_pbase);
954953 host_spec->evtbd_addr_hi = (u32)(((u64)card->evtbd_ring_pbase)>>32);
955954 host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD;
956− if (card->sleep_cookie) {
957− buf_pa = MWIFIEX_SKB_PACB(card->sleep_cookie);
958− host_spec->sleep_cookie_addr_lo = (u32) *buf_pa;
959− host_spec->sleep_cookie_addr_hi = (u32) (((u64)*buf_pa) >> 32);
955+ if (card->sleep_cookie_vbase) {
956+ host_spec->sleep_cookie_addr_lo =
957+ (u32)(card->sleep_cookie_pbase);
958+ host_spec->sleep_cookie_addr_hi =
959+ (u32)(((u64)(card->sleep_cookie_pbase)) >> 32);
960960 dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: 0x%x\n",
961961 host_spec->sleep_cookie_addr_lo);
962962 }
drivers/net/wireless/mwifiex/sta_ioctl.c+24−11
@@ -56,7 +56,6 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, · 55 unmodified lines
5656 */
5757 int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
5858 {
59− bool cancel_flag = false;
6059 int status;
6160 struct cmd_ctrl_node *cmd_queued;
6261
@@ -70,14 +69,11 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) · 7 unmodified lines
7069 atomic_inc(&adapter->cmd_pending);
7170
7271 /* Wait for completion */
73− wait_event_interruptible(adapter->cmd_wait_q.wait,
74− *(cmd_queued->condition));
75− if (!*(cmd_queued->condition))
76− cancel_flag = true;
77−
78− if (cancel_flag) {
79− mwifiex_cancel_pending_ioctl(adapter);
80− dev_dbg(adapter->dev, "cmd cancel\n");
72+ status = wait_event_interruptible(adapter->cmd_wait_q.wait,
73+ *(cmd_queued->condition));
74+ if (status) {
75+ dev_err(adapter->dev, "cmd_wait_q terminated: %d\n", status);
76+ return status;
8177 }
8278
8379 status = adapter->cmd_wait_q.status;
@@ -287,6 +283,20 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, · 203 unmodified lines
287283 if (ret)
288284 goto done;
289285
286+ if (bss_desc) {
287+ u8 config_bands = 0;
288+
289+ if (mwifiex_band_to_radio_type((u8) bss_desc->bss_band)
290+ == HostCmd_SCAN_RADIO_TYPE_BG)
291+ config_bands = BAND_B | BAND_G | BAND_GN;
292+ else
293+ config_bands = BAND_A | BAND_AN;
294+
295+ if (!((config_bands | adapter->fw_bands) &
296+ ~adapter->fw_bands))
297+ adapter->config_bands = config_bands;
298+ }
299+
290300 ret = mwifiex_check_network_compatibility(priv, bss_desc);
291301 if (ret)
292302 goto done;
@@ -496,8 +506,11 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) · 203 unmodified lines
496506 return false;
497507 }
498508
499− wait_event_interruptible(adapter->hs_activate_wait_q,
500− adapter->hs_activate_wait_q_woken);
509+ if (wait_event_interruptible(adapter->hs_activate_wait_q,
510+ adapter->hs_activate_wait_q_woken)) {
511+ dev_err(adapter->dev, "hs_activate_wait_q terminated\n");
512+ return false;
513+ }
501514
502515 return true;
503516 }
drivers/net/wireless/mwifiex/txrx.c+4−2
@@ -117,14 +117,16 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, · 116 unmodified lines
117117 dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
118118 break;
119119 case -1:
120− adapter->data_sent = false;
120+ if (adapter->iface_type != MWIFIEX_PCIE)
121+ adapter->data_sent = false;
121122 dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n",
122123 ret);
123124 adapter->dbg.num_tx_host_to_card_failure++;
124125 mwifiex_write_data_complete(adapter, skb, 0, ret);
125126 break;
126127 case -EINPROGRESS:
127− adapter->data_sent = false;
128+ if (adapter->iface_type != MWIFIEX_PCIE)
129+ adapter->data_sent = false;
128130 break;
129131 case 0:
130132 mwifiex_write_data_complete(adapter, skb, 0, ret);
drivers/net/wireless/mwifiex/uap_cmd.c+44−0
@@ -219,6 +219,7 @@ void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config) · 218 unmodified lines
219219 config->rts_threshold = 0x7FFF;
220220 config->frag_threshold = 0x7FFF;
221221 config->retry_limit = 0x7F;
222+ config->qos_info = 0xFF;
222223 }
223224
224225 /* This function parses BSS related parameters from structure
@@ -297,6 +298,38 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size) · 72 unmodified lines
297298 return;
298299 }
299300
301+/* This function parses WMM related parameters from cfg80211_ap_settings
302+ * structure and updates bss_config structure.
303+ */
304+void
305+mwifiex_set_wmm_params(struct mwifiex_private *priv,
306+ struct mwifiex_uap_bss_param *bss_cfg,
307+ struct cfg80211_ap_settings *params)
308+{
309+ const u8 *vendor_ie;
310+ struct ieee_types_header *wmm_ie;
311+ u8 wmm_oui[] = {0x00, 0x50, 0xf2, 0x02};
312+
313+ vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
314+ WLAN_OUI_TYPE_MICROSOFT_WMM,
315+ params->beacon.tail,
316+ params->beacon.tail_len);
317+ if (vendor_ie) {
318+ wmm_ie = (struct ieee_types_header *)vendor_ie;
319+ memcpy(&bss_cfg->wmm_info, wmm_ie + 1,
320+ sizeof(bss_cfg->wmm_info));
321+ priv->wmm_enabled = 1;
322+ } else {
323+ memset(&bss_cfg->wmm_info, 0, sizeof(bss_cfg->wmm_info));
324+ memcpy(&bss_cfg->wmm_info.oui, wmm_oui, sizeof(wmm_oui));
325+ bss_cfg->wmm_info.subtype = MWIFIEX_WMM_SUBTYPE;
326+ bss_cfg->wmm_info.version = MWIFIEX_WMM_VERSION;
327+ priv->wmm_enabled = 0;
328+ }
329+
330+ bss_cfg->qos_info = 0x00;
331+ return;
332+}
300333 /* This function parses BSS related parameters from structure
301334 * and prepares TLVs specific to WEP encryption.
302335 * These TLVs are appended to command buffer.
@@ -354,6 +387,7 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) · 51 unmodified lines
354387 struct host_cmd_tlv_rates *tlv_rates;
355388 struct host_cmd_tlv_ageout_timer *ao_timer, *ps_ao_timer;
356389 struct mwifiex_ie_types_htcap *htcap;
390+ struct mwifiex_ie_types_wmmcap *wmm_cap;
357391 struct mwifiex_uap_bss_param *bss_cfg = cmd_buf;
358392 int i;
359393 u16 cmd_size = *param_size;
@@ -507,6 +541,16 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) · 147 unmodified lines
507541 tlv += sizeof(struct mwifiex_ie_types_htcap);
508542 }
509543
544+ if (bss_cfg->wmm_info.qos_info != 0xFF) {
545+ wmm_cap = (struct mwifiex_ie_types_wmmcap *)tlv;
546+ wmm_cap->header.type = cpu_to_le16(WLAN_EID_VENDOR_SPECIFIC);
547+ wmm_cap->header.len = cpu_to_le16(sizeof(wmm_cap->wmm_info));
548+ memcpy(&wmm_cap->wmm_info, &bss_cfg->wmm_info,
549+ sizeof(wmm_cap->wmm_info));
550+ cmd_size += sizeof(struct mwifiex_ie_types_wmmcap);
551+ tlv += sizeof(struct mwifiex_ie_types_wmmcap);
552+ }
553+
510554 if (bss_cfg->sta_ao_timer) {
511555 ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv;
512556 ao_timer->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AO_TIMER);
drivers/net/wireless/mwifiex/usb.c+3−27
@@ -786,21 +786,6 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) · 785 unmodified lines
786786 return 0;
787787 }
788788
789−/* This function reads one block of firmware data. */
790−static int mwifiex_get_fw_data(struct mwifiex_adapter *adapter,
791− u32 offset, u32 len, u8 *buf)
792−{
793− if (!buf || !len)
794− return -1;
795−
796− if (offset + len > adapter->firmware->size)
797− return -1;
798−
799− memcpy(buf, adapter->firmware->data + offset, len);
800−
801− return 0;
802−}
803−
804789 static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
805790 struct mwifiex_fw_image *fw)
806791 {
@@ -836,23 +821,14 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, · 29 unmodified lines
836821 dlen = 0;
837822 } else {
838823 /* copy the header of the fw_data to get the length */
839− if (firmware)
840− memcpy(&fwdata->fw_hdr, &firmware[tlen],
841− sizeof(struct fw_header));
842− else
843− mwifiex_get_fw_data(adapter, tlen,
844− sizeof(struct fw_header),
845− (u8 *)&fwdata->fw_hdr);
824+ memcpy(&fwdata->fw_hdr, &firmware[tlen],
825+ sizeof(struct fw_header));
846826
847827 dlen = le32_to_cpu(fwdata->fw_hdr.data_len);
848828 dnld_cmd = le32_to_cpu(fwdata->fw_hdr.dnld_cmd);
849829 tlen += sizeof(struct fw_header);
850830
851− if (firmware)
852− memcpy(fwdata->data, &firmware[tlen], dlen);
853− else
854− mwifiex_get_fw_data(adapter, tlen, dlen,
855− (u8 *)fwdata->data);
831+ memcpy(fwdata->data, &firmware[tlen], dlen);
856832
857833 fwdata->seq_num = cpu_to_le32(fw_seqnum);
858834 tlen += dlen;
drivers/net/wireless/mwifiex/util.h+4−4
@@ -22,16 +22,16 @@ · 21 unmodified lines
2222
2323 static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb)
2424 {
25− return (struct mwifiex_rxinfo *)(skb->cb + sizeof(phys_addr_t));
25+ return (struct mwifiex_rxinfo *)(skb->cb + sizeof(dma_addr_t));
2626 }
2727
2828 static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb)
2929 {
30− return (struct mwifiex_txinfo *)(skb->cb + sizeof(phys_addr_t));
30+ return (struct mwifiex_txinfo *)(skb->cb + sizeof(dma_addr_t));
3131 }
3232
33−static inline phys_addr_t *MWIFIEX_SKB_PACB(struct sk_buff *skb)
33+static inline void MWIFIEX_SKB_PACB(struct sk_buff *skb, dma_addr_t *buf_pa)
3434 {
35− return (phys_addr_t *)skb->cb;
35+ memcpy(buf_pa, skb->cb, sizeof(dma_addr_t));
3636 }
3737 #endif /* !_MWIFIEX_UTIL_H_ */
drivers/net/wireless/mwifiex/wmm.c+6−2
@@ -568,6 +568,8 @@ mwifiex_clean_txrx(struct mwifiex_private *priv) · 567 unmodified lines
568568 mwifiex_wmm_delete_all_ralist(priv);
569569 memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid));
570570
571+ if (priv->adapter->if_ops.clean_pcie_ring)
572+ priv->adapter->if_ops.clean_pcie_ring(priv->adapter);
571573 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
572574 }
573575
@@ -1206,13 +1208,15 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv, · 632 unmodified lines
12061208 ra_list_flags);
12071209 break;
12081210 case -1:
1209− adapter->data_sent = false;
1211+ if (adapter->iface_type != MWIFIEX_PCIE)
1212+ adapter->data_sent = false;
12101213 dev_err(adapter->dev, "host_to_card failed: %#x\n", ret);
12111214 adapter->dbg.num_tx_host_to_card_failure++;
12121215 mwifiex_write_data_complete(adapter, skb, 0, ret);
12131216 break;
12141217 case -EINPROGRESS:
1215− adapter->data_sent = false;
1218+ if (adapter->iface_type != MWIFIEX_PCIE)
1219+ adapter->data_sent = false;
12161220 default:
12171221 break;
12181222 }
drivers/net/wireless/mwl8k.c+124−27
@@ -101,6 +101,18 @@ MODULE_PARM_DESC(ap_mode_default, · 100 unmodified lines
101101 #define MWL8K_MAX_TX_QUEUES (MWL8K_TX_WMM_QUEUES + MWL8K_MAX_AMPDU_QUEUES)
102102 #define mwl8k_tx_queues(priv) (MWL8K_TX_WMM_QUEUES + (priv)->num_ampdu_queues)
103103
104+/* txpriorities are mapped with hw queues.
105+ * Each hw queue has a txpriority.
106+ */
107+#define TOTAL_HW_TX_QUEUES 8
108+
109+/* Each HW queue can have one AMPDU stream.
110+ * But, because one of the hw queue is reserved,
111+ * maximum AMPDU queues that can be created are
112+ * one short of total tx queues.
113+ */
114+#define MWL8K_NUM_AMPDU_STREAMS (TOTAL_HW_TX_QUEUES - 1)
115+
104116 struct rxd_ops {
105117 int rxd_size;
106118 void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr);
@@ -160,7 +172,6 @@ struct mwl8k_ampdu_stream { · 53 unmodified lines
160172 u8 tid;
161173 u8 state;
162174 u8 idx;
163− u8 txq_idx; /* index of this stream in priv->txq */
164175 };
165176
166177 struct mwl8k_priv {
@@ -202,6 +213,8 @@ struct mwl8k_priv { · 35 unmodified lines
202213 int fw_mutex_depth;
203214 struct completion *hostcmd_wait;
204215
216+ atomic_t watchdog_event_pending;
217+
205218 /* lock held over TX and TX reap */
206219 spinlock_t tx_lock;
207220
@@ -1516,6 +1529,9 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) · 1308 unmodified lines
15161529 return -EBUSY;
15171530 }
15181531
1532+ if (atomic_read(&priv->watchdog_event_pending))
1533+ return 0;
1534+
15191535 /*
15201536 * The TX queues are stopped at this point, so this test
15211537 * doesn't need to take ->tx_lock.
@@ -1537,6 +1553,14 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) · 15 unmodified lines
15371553 spin_unlock_bh(&priv->tx_lock);
15381554 timeout = wait_for_completion_timeout(&tx_wait,
15391555 msecs_to_jiffies(MWL8K_TX_WAIT_TIMEOUT_MS));
1556+
1557+ if (atomic_read(&priv->watchdog_event_pending)) {
1558+ spin_lock_bh(&priv->tx_lock);
1559+ priv->tx_wait = NULL;
1560+ spin_unlock_bh(&priv->tx_lock);
1561+ return 0;
1562+ }
1563+
15401564 spin_lock_bh(&priv->tx_lock);
15411565
15421566 if (timeout) {
@@ -1564,6 +1588,7 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) · 21 unmodified lines
15641588
15651589 rc = -ETIMEDOUT;
15661590 }
1591+ priv->tx_wait = NULL;
15671592 spin_unlock_bh(&priv->tx_lock);
15681593
15691594 return rc;
@@ -1734,14 +1759,13 @@ mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid) · 164 unmodified lines
17341759 struct mwl8k_priv *priv = hw->priv;
17351760 int i;
17361761
1737− for (i = 0; i < priv->num_ampdu_queues; i++) {
1762+ for (i = 0; i < MWL8K_NUM_AMPDU_STREAMS; i++) {
17381763 stream = &priv->ampdu[i];
17391764 if (stream->state == AMPDU_NO_STREAM) {
17401765 stream->sta = sta;
17411766 stream->state = AMPDU_STREAM_NEW;
17421767 stream->tid = tid;
17431768 stream->idx = i;
1744− stream->txq_idx = MWL8K_TX_WMM_QUEUES + i;
17451769 wiphy_debug(hw->wiphy, "Added a new stream for %pM %d",
17461770 sta->addr, tid);
17471771 return stream;
@@ -1782,7 +1806,7 @@ mwl8k_lookup_stream(struct ieee80211_hw *hw, u8 *addr, u8 tid) · 34 unmodified lines
17821806 struct mwl8k_priv *priv = hw->priv;
17831807 int i;
17841808
1785− for (i = 0 ; i < priv->num_ampdu_queues; i++) {
1809+ for (i = 0; i < MWL8K_NUM_AMPDU_STREAMS; i++) {
17861810 struct mwl8k_ampdu_stream *stream;
17871811 stream = &priv->ampdu[i];
17881812 if (stream->state == AMPDU_NO_STREAM)
@@ -1829,6 +1853,13 @@ static inline void mwl8k_tx_count_packet(struct ieee80211_sta *sta, u8 tid) · 40 unmodified lines
18291853 tx_stats->pkts++;
18301854 }
18311855
1856+/* The hardware ampdu queues start from 5.
1857+ * txpriorities for ampdu queues are
1858+ * 5 6 7 0 1 2 3 4 ie., queue 5 is highest
1859+ * and queue 3 is lowest (queue 4 is reserved)
1860+ */
1861+#define BA_QUEUE 5
1862+
18321863 static void
18331864 mwl8k_txq_xmit(struct ieee80211_hw *hw,
18341865 int index,
@@ -1928,8 +1959,13 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, · 93 unmodified lines
19281959 stream = mwl8k_lookup_stream(hw, sta->addr, tid);
19291960 if (stream != NULL) {
19301961 if (stream->state == AMPDU_STREAM_ACTIVE) {
1931− txpriority = stream->txq_idx;
1932− index = stream->txq_idx;
1962+ WARN_ON(!(qos & MWL8K_QOS_ACK_POLICY_BLOCKACK));
1963+ txpriority = (BA_QUEUE + stream->idx) %
1964+ TOTAL_HW_TX_QUEUES;
1965+ if (stream->idx <= 1)
1966+ index = stream->idx +
1967+ MWL8K_TX_WMM_QUEUES;
1968+
19331969 } else if (stream->state == AMPDU_STREAM_NEW) {
19341970 /* We get here if the driver sends us packets
19351971 * after we've initiated a stream, but before
@@ -1971,6 +2007,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, · 35 unmodified lines
19712007 }
19722008 }
19732009 spin_unlock(&priv->stream_lock);
2010+ } else {
2011+ qos &= ~MWL8K_QOS_ACK_POLICY_MASK;
2012+ qos |= MWL8K_QOS_ACK_POLICY_NORMAL;
19742013 }
19752014
19762015 dma = pci_map_single(priv->pdev, skb->data,
@@ -3578,7 +3617,11 @@ static int mwl8k_cmd_get_watchdog_bitmap(struct ieee80211_hw *hw, u8 *bitmap) · 1601 unmodified lines
35783617 return rc;
35793618 }
35803619
3581−#define INVALID_BA 0xAA
3620+#define MWL8K_WMM_QUEUE_NUMBER 3
3621+
3622+static void mwl8k_destroy_ba(struct ieee80211_hw *hw,
3623+ u8 idx);
3624+
35823625 static void mwl8k_watchdog_ba_events(struct work_struct *work)
35833626 {
35843627 int rc;
@@ -3586,24 +3629,41 @@ static void mwl8k_watchdog_ba_events(struct work_struct *work) · 1 unmodified line
35863629 struct mwl8k_ampdu_stream *streams;
35873630 struct mwl8k_priv *priv =
35883631 container_of(work, struct mwl8k_priv, watchdog_ba_handle);
3632+ struct ieee80211_hw *hw = priv->hw;
3633+ int i;
3634+ u32 status = 0;
3635+
3636+ mwl8k_fw_lock(hw);
35893637
35903638 rc = mwl8k_cmd_get_watchdog_bitmap(priv->hw, &bitmap);
35913639 if (rc)
3592− return;
3640+ goto done;
35933641
3594− if (bitmap == INVALID_BA)
3595− return;
3642+ spin_lock(&priv->stream_lock);
35963643
35973644 /* the bitmap is the hw queue number. Map it to the ampdu queue. */
3598− stream_index = bitmap - MWL8K_TX_WMM_QUEUES;
3599−
3600− BUG_ON(stream_index >= priv->num_ampdu_queues);
3601−
3602− streams = &priv->ampdu[stream_index];
3603−
3604− if (streams->state == AMPDU_STREAM_ACTIVE)
3605− ieee80211_stop_tx_ba_session(streams->sta, streams->tid);
3645+ for (i = 0; i < TOTAL_HW_TX_QUEUES; i++) {
3646+ if (bitmap & (1 << i)) {
3647+ stream_index = (i + MWL8K_WMM_QUEUE_NUMBER) %
3648+ TOTAL_HW_TX_QUEUES;
3649+ streams = &priv->ampdu[stream_index];
3650+ if (streams->state == AMPDU_STREAM_ACTIVE) {
3651+ ieee80211_stop_tx_ba_session(streams->sta,
3652+ streams->tid);
3653+ spin_unlock(&priv->stream_lock);
3654+ mwl8k_destroy_ba(hw, stream_index);
3655+ spin_lock(&priv->stream_lock);
3656+ }
3657+ }
3658+ }
36063659
3660+ spin_unlock(&priv->stream_lock);
3661+done:
3662+ atomic_dec(&priv->watchdog_event_pending);
3663+ status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
3664+ iowrite32((status | MWL8K_A2H_INT_BA_WATCHDOG),
3665+ priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
3666+ mwl8k_fw_unlock(hw);
36073667 return;
36083668 }
36093669
@@ -3763,7 +3823,7 @@ mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, · 153 unmodified lines
37633823 }
37643824
37653825 static void mwl8k_destroy_ba(struct ieee80211_hw *hw,
3766− struct mwl8k_ampdu_stream *stream)
3826+ u8 idx)
37673827 {
37683828 struct mwl8k_cmd_bastream *cmd;
37693829
@@ -3775,10 +3835,10 @@ static void mwl8k_destroy_ba(struct ieee80211_hw *hw, · 5 unmodified lines
37753835 cmd->header.length = cpu_to_le16(sizeof(*cmd));
37763836 cmd->action = cpu_to_le32(MWL8K_BA_DESTROY);
37773837
3778− cmd->destroy_params.ba_context = cpu_to_le32(stream->idx);
3838+ cmd->destroy_params.ba_context = cpu_to_le32(idx);
37793839 mwl8k_post_cmd(hw, &cmd->header);
37803840
3781− wiphy_debug(hw->wiphy, "Deleted BA stream index %d\n", stream->idx);
3841+ wiphy_debug(hw->wiphy, "Deleted BA stream index %d\n", idx);
37823842
37833843 kfree(cmd);
37843844 }
@@ -3875,7 +3935,30 @@ static int mwl8k_cmd_set_new_stn_del(struct ieee80211_hw *hw, · 90 unmodified lines
38753935 struct ieee80211_vif *vif, u8 *addr)
38763936 {
38773937 struct mwl8k_cmd_set_new_stn *cmd;
3878− int rc;
3938+ struct mwl8k_priv *priv = hw->priv;
3939+ int rc, i;
3940+ u8 idx;
3941+
3942+ spin_lock(&priv->stream_lock);
3943+ /* Destroy any active ampdu streams for this sta */
3944+ for (i = 0; i < MWL8K_NUM_AMPDU_STREAMS; i++) {
3945+ struct mwl8k_ampdu_stream *s;
3946+ s = &priv->ampdu[i];
3947+ if (s->state != AMPDU_NO_STREAM) {
3948+ if (memcmp(s->sta->addr, addr, ETH_ALEN) == 0) {
3949+ if (s->state == AMPDU_STREAM_ACTIVE) {
3950+ idx = s->idx;
3951+ spin_unlock(&priv->stream_lock);
3952+ mwl8k_destroy_ba(hw, idx);
3953+ spin_lock(&priv->stream_lock);
3954+ } else if (s->state == AMPDU_STREAM_NEW) {
3955+ mwl8k_remove_stream(hw, s);
3956+ }
3957+ }
3958+ }
3959+ }
3960+
3961+ spin_unlock(&priv->stream_lock);
38793962
38803963 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
38813964 if (cmd == NULL)
@@ -4250,9 +4333,11 @@ static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw, · 368 unmodified lines
42504333 p->amsdu_enabled = 0;
42514334
42524335 rc = mwl8k_post_cmd(hw, &cmd->header);
4336+ if (!rc)
4337+ rc = p->station_id;
42534338 kfree(cmd);
42544339
4255− return rc ? rc : p->station_id;
4340+ return rc;
42564341 }
42574342
42584343 static int mwl8k_cmd_update_stadb_del(struct ieee80211_hw *hw,
@@ -4301,6 +4386,10 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id) · 42 unmodified lines
43014386 }
43024387
43034388 if (status & MWL8K_A2H_INT_BA_WATCHDOG) {
4389+ iowrite32(~MWL8K_A2H_INT_BA_WATCHDOG,
4390+ priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
4391+
4392+ atomic_inc(&priv->watchdog_event_pending);
43044393 status &= ~MWL8K_A2H_INT_BA_WATCHDOG;
43054394 ieee80211_queue_work(hw, &priv->watchdog_ba_handle);
43064395 }
@@ -4444,6 +4533,8 @@ static int mwl8k_start(struct ieee80211_hw *hw) · 137 unmodified lines
44444533 priv->irq = -1;
44454534 tasklet_disable(&priv->poll_tx_task);
44464535 tasklet_disable(&priv->poll_rx_task);
4536+ } else {
4537+ ieee80211_wake_queues(hw);
44474538 }
44484539
44494540 return rc;
@@ -5092,7 +5183,7 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, · 642 unmodified lines
50925183 int i, rc = 0;
50935184 struct mwl8k_priv *priv = hw->priv;
50945185 struct mwl8k_ampdu_stream *stream;
5095− u8 *addr = sta->addr;
5186+ u8 *addr = sta->addr, idx;
50965187 struct mwl8k_sta *sta_info = MWL8K_STA(sta);
50975188
50985189 if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
@@ -5175,8 +5266,9 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, · 76 unmodified lines
51755266 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
51765267 if (stream) {
51775268 if (stream->state == AMPDU_STREAM_ACTIVE) {
5269+ idx = stream->idx;
51785270 spin_unlock(&priv->stream_lock);
5179− mwl8k_destroy_ba(hw, stream);
5271+ mwl8k_destroy_ba(hw, idx);
51805272 spin_lock(&priv->stream_lock);
51815273 }
51825274 mwl8k_remove_stream(hw, stream);
@@ -5192,8 +5284,9 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, · 9 unmodified lines
51925284 if (!rc)
51935285 stream->state = AMPDU_STREAM_ACTIVE;
51945286 else {
5287+ idx = stream->idx;
51955288 spin_unlock(&priv->stream_lock);
5196− mwl8k_destroy_ba(hw, stream);
5289+ mwl8k_destroy_ba(hw, idx);
51975290 spin_lock(&priv->stream_lock);
51985291 wiphy_debug(hw->wiphy,
51995292 "Failed adding stream for sta %pM tid %d\n",
@@ -5256,7 +5349,7 @@ enum { · 56 unmodified lines
52565349 MWL8366,
52575350 };
52585351
5259−#define MWL8K_8366_AP_FW_API 2
5352+#define MWL8K_8366_AP_FW_API 3
52605353 #define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw"
52615354 #define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api)
52625355
@@ -5464,6 +5557,7 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw) · 201 unmodified lines
54645557 if (priv->rxd_ops == NULL) {
54655558 wiphy_err(hw->wiphy,
54665559 "Driver does not have AP firmware image support for this hardware\n");
5560+ rc = -ENOENT;
54675561 goto err_stop_firmware;
54685562 }
54695563 } else {
@@ -5473,6 +5567,7 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw) · 3 unmodified lines
54735567 priv->sniffer_enabled = false;
54745568 priv->wmm_enabled = false;
54755569 priv->pending_tx_pkts = 0;
5570+ atomic_set(&priv->watchdog_event_pending, 0);
54765571
54775572 rc = mwl8k_rxq_init(hw, 0);
54785573 if (rc)
@@ -5809,6 +5904,7 @@ static int mwl8k_probe(struct pci_dev *pdev, · 330 unmodified lines
58095904 priv->sram = pci_iomap(pdev, 0, 0x10000);
58105905 if (priv->sram == NULL) {
58115906 wiphy_err(hw->wiphy, "Cannot map device SRAM\n");
5907+ rc = -EIO;
58125908 goto err_iounmap;
58135909 }
58145910
@@ -5821,6 +5917,7 @@ static int mwl8k_probe(struct pci_dev *pdev, · 6 unmodified lines
58215917 priv->regs = pci_iomap(pdev, 2, 0x10000);
58225918 if (priv->regs == NULL) {
58235919 wiphy_err(hw->wiphy, "Cannot map device registers\n");
5920+ rc = -EIO;
58245921 goto err_iounmap;
58255922 }
58265923 }
drivers/net/wireless/p54/p54pci.c+5−2
@@ -559,6 +559,7 @@ static int p54p_probe(struct pci_dev *pdev, · 558 unmodified lines
559559 mem_len = pci_resource_len(pdev, 0);
560560 if (mem_len < sizeof(struct p54p_csr)) {
561561 dev_err(&pdev->dev, "Too short PCI resources\n");
562+ err = -ENODEV;
562563 goto err_disable_dev;
563564 }
564565
@@ -568,8 +569,10 @@ static int p54p_probe(struct pci_dev *pdev, · 3 unmodified lines
568569 goto err_disable_dev;
569570 }
570571
571− if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
572− pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
572+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
573+ if (!err)
574+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
575+ if (err) {
573576 dev_err(&pdev->dev, "No suitable DMA available\n");
574577 goto err_free_reg;
575578 }
drivers/net/wireless/p54/p54usb.c+4−0
@@ -47,6 +47,7 @@ static struct usb_device_id p54u_table[] = { · 46 unmodified lines
4747 {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */
4848 {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */
4949 {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */
50+ {USB_DEVICE(0x0675, 0x0530)}, /* DrayTek Vigor 530 */
5051 {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */
5152 {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */
5253 {USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */
@@ -82,6 +83,8 @@ static struct usb_device_id p54u_table[] = { · 29 unmodified lines
8283 {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */
8384 {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */
8485 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
86+ {USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */
87+ {USB_DEVICE(0x083a, 0x4503)}, /* T-Com Sinus 154 data II */
8588 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
8689 {USB_DEVICE(0x083a, 0xc501)}, /* Zoom Wireless-G 4410 */
8790 {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */
@@ -101,6 +104,7 @@ static struct usb_device_id p54u_table[] = { · 13 unmodified lines
101104 {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
102105 {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */
103106 {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
107+ /* {USB_DEVICE(0x15a9, 0x0002)}, * Also SparkLAN WL-682 with 3887 */
104108 {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */
105109 {USB_DEVICE(0x1740, 0x1000)}, /* Senao NUB-350 */
106110 {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
drivers/net/wireless/prism54/isl_ioctl.c+1−0
@@ -1503,6 +1503,7 @@ static int prism54_get_auth(struct net_device *ndev, · 1502 unmodified lines
15031503 case DOT11_AUTH_BOTH:
15041504 case DOT11_AUTH_SK:
15051505 param->value = IW_AUTH_ALG_SHARED_KEY;
1506+ break;
15061507 case DOT11_AUTH_NONE:
15071508 default:
15081509 param->value = 0;
drivers/net/wireless/ray_cs.c+14−5
@@ -1107,12 +1107,15 @@ static int ray_get_essid(struct net_device *dev, struct iw_request_info *info, · 1106 unmodified lines
11071107 union iwreq_data *wrqu, char *extra)
11081108 {
11091109 ray_dev_t *local = netdev_priv(dev);
1110+ UCHAR tmp[IW_ESSID_MAX_SIZE + 1];
11101111
11111112 /* Get the essid that was set */
11121113 memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE);
1114+ memcpy(tmp, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE);
1115+ tmp[IW_ESSID_MAX_SIZE] = '\0';
11131116
11141117 /* Push it out ! */
1115− wrqu->essid.length = strlen(extra);
1118+ wrqu->essid.length = strlen(tmp);
11161119 wrqu->essid.flags = 1; /* active */
11171120
11181121 return 0;
@@ -1842,6 +1845,8 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) · 723 unmodified lines
18421845 UCHAR tmp;
18431846 UCHAR cmd;
18441847 UCHAR status;
1848+ UCHAR memtmp[ESSID_SIZE + 1];
1849+
18451850
18461851 if (dev == NULL) /* Note that we want interrupts with dev->start == 0 */
18471852 return IRQ_NONE;
@@ -1901,17 +1906,21 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) · 53 unmodified lines
19011906 break;
19021907 case CCS_START_NETWORK:
19031908 case CCS_JOIN_NETWORK:
1909+ memcpy(memtmp, local->sparm.b4.a_current_ess_id,
1910+ ESSID_SIZE);
1911+ memtmp[ESSID_SIZE] = '\0';
1912+
19041913 if (status == CCS_COMMAND_COMPLETE) {
19051914 if (readb
19061915 (&pccs->var.start_network.net_initiated) ==
19071916 1) {
19081917 dev_dbg(&link->dev,
19091918 "ray_cs interrupt network \"%s\" started\n",
1910− local->sparm.b4.a_current_ess_id);
1919+ memtmp);
19111920 } else {
19121921 dev_dbg(&link->dev,
19131922 "ray_cs interrupt network \"%s\" joined\n",
1914− local->sparm.b4.a_current_ess_id);
1923+ memtmp);
19151924 }
19161925 memcpy_fromio(&local->bss_id,
19171926 pccs->var.start_network.bssid,
@@ -1939,12 +1948,12 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) · 21 unmodified lines
19391948 if (status == CCS_START_NETWORK) {
19401949 dev_dbg(&link->dev,
19411950 "ray_cs interrupt network \"%s\" start failed\n",
1942− local->sparm.b4.a_current_ess_id);
1951+ memtmp);
19431952 local->timer.function = start_net;
19441953 } else {
19451954 dev_dbg(&link->dev,
19461955 "ray_cs interrupt network \"%s\" join failed\n",
1947− local->sparm.b4.a_current_ess_id);
1956+ memtmp);
19481957 local->timer.function = join_net;
19491958 }
19501959 add_timer(&local->timer);
drivers/net/wireless/rt2x00/rt2800lib.c+432−378
@@ -1296,8 +1296,7 @@ void rt2800_config_filter(struct rt2x00_dev *rt2x00dev, · 1295 unmodified lines
12961296 !(filter_flags & FIF_CONTROL));
12971297 rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_PSPOLL,
12981298 !(filter_flags & FIF_PSPOLL));
1299− rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BA,
1300− !(filter_flags & FIF_CONTROL));
1299+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BA, 0);
13011300 rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BAR,
13021301 !(filter_flags & FIF_CONTROL));
13031302 rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CNTL,
@@ -3866,6 +3865,400 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, · 2562 unmodified lines
38663865 return rfcsr24;
38673866 }
38683867
3868+static void rt2800_init_rfcsr_305x_soc(struct rt2x00_dev *rt2x00dev)
3869+{
3870+ rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
3871+ rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
3872+ rt2800_rfcsr_write(rt2x00dev, 2, 0xf7);
3873+ rt2800_rfcsr_write(rt2x00dev, 3, 0x75);
3874+ rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
3875+ rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
3876+ rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
3877+ rt2800_rfcsr_write(rt2x00dev, 7, 0x50);
3878+ rt2800_rfcsr_write(rt2x00dev, 8, 0x39);
3879+ rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
3880+ rt2800_rfcsr_write(rt2x00dev, 10, 0x60);
3881+ rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
3882+ rt2800_rfcsr_write(rt2x00dev, 12, 0x75);
3883+ rt2800_rfcsr_write(rt2x00dev, 13, 0x75);
3884+ rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
3885+ rt2800_rfcsr_write(rt2x00dev, 15, 0x58);
3886+ rt2800_rfcsr_write(rt2x00dev, 16, 0xb3);
3887+ rt2800_rfcsr_write(rt2x00dev, 17, 0x92);
3888+ rt2800_rfcsr_write(rt2x00dev, 18, 0x2c);
3889+ rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
3890+ rt2800_rfcsr_write(rt2x00dev, 20, 0xba);
3891+ rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
3892+ rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
3893+ rt2800_rfcsr_write(rt2x00dev, 23, 0x31);
3894+ rt2800_rfcsr_write(rt2x00dev, 24, 0x08);
3895+ rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
3896+ rt2800_rfcsr_write(rt2x00dev, 26, 0x25);
3897+ rt2800_rfcsr_write(rt2x00dev, 27, 0x23);
3898+ rt2800_rfcsr_write(rt2x00dev, 28, 0x13);
3899+ rt2800_rfcsr_write(rt2x00dev, 29, 0x83);
3900+ rt2800_rfcsr_write(rt2x00dev, 30, 0x00);
3901+ rt2800_rfcsr_write(rt2x00dev, 31, 0x00);
3902+}
3903+
3904+static void rt2800_init_rfcsr_30xx(struct rt2x00_dev *rt2x00dev)
3905+{
3906+ rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
3907+ rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
3908+ rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
3909+ rt2800_rfcsr_write(rt2x00dev, 7, 0x60);
3910+ rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
3911+ rt2800_rfcsr_write(rt2x00dev, 10, 0x41);
3912+ rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
3913+ rt2800_rfcsr_write(rt2x00dev, 12, 0x7b);
3914+ rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
3915+ rt2800_rfcsr_write(rt2x00dev, 15, 0x58);
3916+ rt2800_rfcsr_write(rt2x00dev, 16, 0xb3);
3917+ rt2800_rfcsr_write(rt2x00dev, 17, 0x92);
3918+ rt2800_rfcsr_write(rt2x00dev, 18, 0x2c);
3919+ rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
3920+ rt2800_rfcsr_write(rt2x00dev, 20, 0xba);
3921+ rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
3922+ rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
3923+ rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
3924+ rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
3925+}
3926+
3927+static void rt2800_init_rfcsr_3290(struct rt2x00_dev *rt2x00dev)
3928+{
3929+ rt2800_rfcsr_write(rt2x00dev, 1, 0x0f);
3930+ rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
3931+ rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
3932+ rt2800_rfcsr_write(rt2x00dev, 4, 0x00);
3933+ rt2800_rfcsr_write(rt2x00dev, 6, 0xa0);
3934+ rt2800_rfcsr_write(rt2x00dev, 8, 0xf3);
3935+ rt2800_rfcsr_write(rt2x00dev, 9, 0x02);
3936+ rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
3937+ rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
3938+ rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
3939+ rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
3940+ rt2800_rfcsr_write(rt2x00dev, 18, 0x02);
3941+ rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
3942+ rt2800_rfcsr_write(rt2x00dev, 25, 0x83);
3943+ rt2800_rfcsr_write(rt2x00dev, 26, 0x82);
3944+ rt2800_rfcsr_write(rt2x00dev, 27, 0x09);
3945+ rt2800_rfcsr_write(rt2x00dev, 29, 0x10);
3946+ rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
3947+ rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
3948+ rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
3949+ rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
3950+ rt2800_rfcsr_write(rt2x00dev, 34, 0x05);
3951+ rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
3952+ rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
3953+ rt2800_rfcsr_write(rt2x00dev, 38, 0x85);
3954+ rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
3955+ rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
3956+ rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
3957+ rt2800_rfcsr_write(rt2x00dev, 42, 0xd5);
3958+ rt2800_rfcsr_write(rt2x00dev, 43, 0x7b);
3959+ rt2800_rfcsr_write(rt2x00dev, 44, 0x0e);
3960+ rt2800_rfcsr_write(rt2x00dev, 45, 0xa2);
3961+ rt2800_rfcsr_write(rt2x00dev, 46, 0x73);
3962+ rt2800_rfcsr_write(rt2x00dev, 47, 0x00);
3963+ rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
3964+ rt2800_rfcsr_write(rt2x00dev, 49, 0x98);
3965+ rt2800_rfcsr_write(rt2x00dev, 52, 0x38);
3966+ rt2800_rfcsr_write(rt2x00dev, 53, 0x00);
3967+ rt2800_rfcsr_write(rt2x00dev, 54, 0x78);
3968+ rt2800_rfcsr_write(rt2x00dev, 55, 0x43);
3969+ rt2800_rfcsr_write(rt2x00dev, 56, 0x02);
3970+ rt2800_rfcsr_write(rt2x00dev, 57, 0x80);
3971+ rt2800_rfcsr_write(rt2x00dev, 58, 0x7f);
3972+ rt2800_rfcsr_write(rt2x00dev, 59, 0x09);
3973+ rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
3974+ rt2800_rfcsr_write(rt2x00dev, 61, 0xc1);
3975+}
3976+
3977+static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev)
3978+{
3979+ rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
3980+ rt2800_rfcsr_write(rt2x00dev, 1, 0x23);
3981+ rt2800_rfcsr_write(rt2x00dev, 2, 0x50);
3982+ rt2800_rfcsr_write(rt2x00dev, 3, 0x18);
3983+ rt2800_rfcsr_write(rt2x00dev, 4, 0x00);
3984+ rt2800_rfcsr_write(rt2x00dev, 5, 0x00);
3985+ rt2800_rfcsr_write(rt2x00dev, 6, 0x33);
3986+ rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
3987+ rt2800_rfcsr_write(rt2x00dev, 8, 0xf1);
3988+ rt2800_rfcsr_write(rt2x00dev, 9, 0x02);
3989+ rt2800_rfcsr_write(rt2x00dev, 10, 0xd2);
3990+ rt2800_rfcsr_write(rt2x00dev, 11, 0x42);
3991+ rt2800_rfcsr_write(rt2x00dev, 12, 0x1c);
3992+ rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
3993+ rt2800_rfcsr_write(rt2x00dev, 14, 0x5a);
3994+ rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
3995+ rt2800_rfcsr_write(rt2x00dev, 16, 0x01);
3996+ rt2800_rfcsr_write(rt2x00dev, 18, 0x45);
3997+ rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
3998+ rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
3999+ rt2800_rfcsr_write(rt2x00dev, 21, 0x00);
4000+ rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
4001+ rt2800_rfcsr_write(rt2x00dev, 23, 0x00);
4002+ rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
4003+ rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
4004+ rt2800_rfcsr_write(rt2x00dev, 26, 0x00);
4005+ rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
4006+ rt2800_rfcsr_write(rt2x00dev, 28, 0x03);
4007+ rt2800_rfcsr_write(rt2x00dev, 29, 0x00);
4008+ rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
4009+ rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
4010+ rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
4011+ rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
4012+ rt2800_rfcsr_write(rt2x00dev, 34, 0x01);
4013+ rt2800_rfcsr_write(rt2x00dev, 35, 0x03);
4014+ rt2800_rfcsr_write(rt2x00dev, 36, 0xbd);
4015+ rt2800_rfcsr_write(rt2x00dev, 37, 0x3c);
4016+ rt2800_rfcsr_write(rt2x00dev, 38, 0x5f);
4017+ rt2800_rfcsr_write(rt2x00dev, 39, 0xc5);
4018+ rt2800_rfcsr_write(rt2x00dev, 40, 0x33);
4019+ rt2800_rfcsr_write(rt2x00dev, 41, 0x5b);
4020+ rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
4021+ rt2800_rfcsr_write(rt2x00dev, 43, 0xdb);
4022+ rt2800_rfcsr_write(rt2x00dev, 44, 0xdb);
4023+ rt2800_rfcsr_write(rt2x00dev, 45, 0xdb);
4024+ rt2800_rfcsr_write(rt2x00dev, 46, 0xdd);
4025+ rt2800_rfcsr_write(rt2x00dev, 47, 0x0d);
4026+ rt2800_rfcsr_write(rt2x00dev, 48, 0x14);
4027+ rt2800_rfcsr_write(rt2x00dev, 49, 0x00);
4028+ rt2800_rfcsr_write(rt2x00dev, 50, 0x2d);
4029+ rt2800_rfcsr_write(rt2x00dev, 51, 0x7f);
4030+ rt2800_rfcsr_write(rt2x00dev, 52, 0x00);
4031+ rt2800_rfcsr_write(rt2x00dev, 53, 0x52);
4032+ rt2800_rfcsr_write(rt2x00dev, 54, 0x1b);
4033+ rt2800_rfcsr_write(rt2x00dev, 55, 0x7f);
4034+ rt2800_rfcsr_write(rt2x00dev, 56, 0x00);
4035+ rt2800_rfcsr_write(rt2x00dev, 57, 0x52);
4036+ rt2800_rfcsr_write(rt2x00dev, 58, 0x1b);
4037+ rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
4038+ rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
4039+ rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
4040+ rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
4041+ rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
4042+}
4043+
4044+static void rt2800_init_rfcsr_3390(struct rt2x00_dev *rt2x00dev)
4045+{
4046+ rt2800_rfcsr_write(rt2x00dev, 0, 0xa0);
4047+ rt2800_rfcsr_write(rt2x00dev, 1, 0xe1);
4048+ rt2800_rfcsr_write(rt2x00dev, 2, 0xf1);
4049+ rt2800_rfcsr_write(rt2x00dev, 3, 0x62);
4050+ rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
4051+ rt2800_rfcsr_write(rt2x00dev, 5, 0x8b);
4052+ rt2800_rfcsr_write(rt2x00dev, 6, 0x42);
4053+ rt2800_rfcsr_write(rt2x00dev, 7, 0x34);
4054+ rt2800_rfcsr_write(rt2x00dev, 8, 0x00);
4055+ rt2800_rfcsr_write(rt2x00dev, 9, 0xc0);
4056+ rt2800_rfcsr_write(rt2x00dev, 10, 0x61);
4057+ rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
4058+ rt2800_rfcsr_write(rt2x00dev, 12, 0x3b);
4059+ rt2800_rfcsr_write(rt2x00dev, 13, 0xe0);
4060+ rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
4061+ rt2800_rfcsr_write(rt2x00dev, 15, 0x53);
4062+ rt2800_rfcsr_write(rt2x00dev, 16, 0xe0);
4063+ rt2800_rfcsr_write(rt2x00dev, 17, 0x94);
4064+ rt2800_rfcsr_write(rt2x00dev, 18, 0x5c);
4065+ rt2800_rfcsr_write(rt2x00dev, 19, 0x4a);
4066+ rt2800_rfcsr_write(rt2x00dev, 20, 0xb2);
4067+ rt2800_rfcsr_write(rt2x00dev, 21, 0xf6);
4068+ rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
4069+ rt2800_rfcsr_write(rt2x00dev, 23, 0x14);
4070+ rt2800_rfcsr_write(rt2x00dev, 24, 0x08);
4071+ rt2800_rfcsr_write(rt2x00dev, 25, 0x3d);
4072+ rt2800_rfcsr_write(rt2x00dev, 26, 0x85);
4073+ rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
4074+ rt2800_rfcsr_write(rt2x00dev, 28, 0x41);
4075+ rt2800_rfcsr_write(rt2x00dev, 29, 0x8f);
4076+ rt2800_rfcsr_write(rt2x00dev, 30, 0x20);
4077+ rt2800_rfcsr_write(rt2x00dev, 31, 0x0f);
4078+}
4079+
4080+static void rt2800_init_rfcsr_3572(struct rt2x00_dev *rt2x00dev)
4081+{
4082+ rt2800_rfcsr_write(rt2x00dev, 0, 0x70);
4083+ rt2800_rfcsr_write(rt2x00dev, 1, 0x81);
4084+ rt2800_rfcsr_write(rt2x00dev, 2, 0xf1);
4085+ rt2800_rfcsr_write(rt2x00dev, 3, 0x02);
4086+ rt2800_rfcsr_write(rt2x00dev, 4, 0x4c);
4087+ rt2800_rfcsr_write(rt2x00dev, 5, 0x05);
4088+ rt2800_rfcsr_write(rt2x00dev, 6, 0x4a);
4089+ rt2800_rfcsr_write(rt2x00dev, 7, 0xd8);
4090+ rt2800_rfcsr_write(rt2x00dev, 9, 0xc3);
4091+ rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
4092+ rt2800_rfcsr_write(rt2x00dev, 11, 0xb9);
4093+ rt2800_rfcsr_write(rt2x00dev, 12, 0x70);
4094+ rt2800_rfcsr_write(rt2x00dev, 13, 0x65);
4095+ rt2800_rfcsr_write(rt2x00dev, 14, 0xa0);
4096+ rt2800_rfcsr_write(rt2x00dev, 15, 0x53);
4097+ rt2800_rfcsr_write(rt2x00dev, 16, 0x4c);
4098+ rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
4099+ rt2800_rfcsr_write(rt2x00dev, 18, 0xac);
4100+ rt2800_rfcsr_write(rt2x00dev, 19, 0x93);
4101+ rt2800_rfcsr_write(rt2x00dev, 20, 0xb3);
4102+ rt2800_rfcsr_write(rt2x00dev, 21, 0xd0);
4103+ rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
4104+ rt2800_rfcsr_write(rt2x00dev, 23, 0x3c);
4105+ rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
4106+ rt2800_rfcsr_write(rt2x00dev, 25, 0x15);
4107+ rt2800_rfcsr_write(rt2x00dev, 26, 0x85);
4108+ rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
4109+ rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
4110+ rt2800_rfcsr_write(rt2x00dev, 29, 0x9b);
4111+ rt2800_rfcsr_write(rt2x00dev, 30, 0x09);
4112+ rt2800_rfcsr_write(rt2x00dev, 31, 0x10);
4113+}
4114+
4115+static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
4116+{
4117+ rt2800_rfcsr_write(rt2x00dev, 1, 0x0f);
4118+ rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
4119+ rt2800_rfcsr_write(rt2x00dev, 3, 0x88);
4120+ rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
4121+ if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
4122+ rt2800_rfcsr_write(rt2x00dev, 6, 0xe0);
4123+ else
4124+ rt2800_rfcsr_write(rt2x00dev, 6, 0xa0);
4125+ rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
4126+ rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
4127+ rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
4128+ rt2800_rfcsr_write(rt2x00dev, 12, 0xc6);
4129+ rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
4130+ rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
4131+ rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
4132+ rt2800_rfcsr_write(rt2x00dev, 16, 0x00);
4133+ rt2800_rfcsr_write(rt2x00dev, 18, 0x03);
4134+ rt2800_rfcsr_write(rt2x00dev, 19, 0x00);
4135+
4136+ rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
4137+ rt2800_rfcsr_write(rt2x00dev, 21, 0x00);
4138+ rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
4139+ rt2800_rfcsr_write(rt2x00dev, 23, 0x00);
4140+ rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
4141+ if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
4142+ rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
4143+ else
4144+ rt2800_rfcsr_write(rt2x00dev, 25, 0xc0);
4145+ rt2800_rfcsr_write(rt2x00dev, 26, 0x00);
4146+ rt2800_rfcsr_write(rt2x00dev, 27, 0x09);
4147+ rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
4148+ rt2800_rfcsr_write(rt2x00dev, 29, 0x10);
4149+
4150+ rt2800_rfcsr_write(rt2x00dev, 30, 0x00);
4151+ rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
4152+ rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
4153+ rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
4154+ rt2800_rfcsr_write(rt2x00dev, 34, 0x07);
4155+ rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
4156+ rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
4157+ rt2800_rfcsr_write(rt2x00dev, 37, 0x08);
4158+ rt2800_rfcsr_write(rt2x00dev, 38, 0x85);
4159+ rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
4160+
4161+ if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
4162+ rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
4163+ else
4164+ rt2800_rfcsr_write(rt2x00dev, 40, 0x4b);
4165+ rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
4166+ rt2800_rfcsr_write(rt2x00dev, 42, 0xd2);
4167+ rt2800_rfcsr_write(rt2x00dev, 43, 0x9a);
4168+ rt2800_rfcsr_write(rt2x00dev, 44, 0x0e);
4169+ rt2800_rfcsr_write(rt2x00dev, 45, 0xa2);
4170+ if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
4171+ rt2800_rfcsr_write(rt2x00dev, 46, 0x73);
4172+ else
4173+ rt2800_rfcsr_write(rt2x00dev, 46, 0x7b);
4174+ rt2800_rfcsr_write(rt2x00dev, 47, 0x00);
4175+ rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
4176+ rt2800_rfcsr_write(rt2x00dev, 49, 0x94);
4177+
4178+ rt2800_rfcsr_write(rt2x00dev, 52, 0x38);
4179+ if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
4180+ rt2800_rfcsr_write(rt2x00dev, 53, 0x00);
4181+ else
4182+ rt2800_rfcsr_write(rt2x00dev, 53, 0x84);
4183+ rt2800_rfcsr_write(rt2x00dev, 54, 0x78);
4184+ rt2800_rfcsr_write(rt2x00dev, 55, 0x44);
4185+ rt2800_rfcsr_write(rt2x00dev, 56, 0x22);
4186+ rt2800_rfcsr_write(rt2x00dev, 57, 0x80);
4187+ rt2800_rfcsr_write(rt2x00dev, 58, 0x7f);
4188+ rt2800_rfcsr_write(rt2x00dev, 59, 0x63);
4189+
4190+ rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
4191+ if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
4192+ rt2800_rfcsr_write(rt2x00dev, 61, 0xd1);
4193+ else
4194+ rt2800_rfcsr_write(rt2x00dev, 61, 0xdd);
4195+ rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
4196+ rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
4197+}
4198+
4199+static void rt2800_init_rfcsr_5392(struct rt2x00_dev *rt2x00dev)
4200+{
4201+ rt2800_rfcsr_write(rt2x00dev, 1, 0x17);
4202+ rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
4203+ rt2800_rfcsr_write(rt2x00dev, 3, 0x88);
4204+ rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
4205+ rt2800_rfcsr_write(rt2x00dev, 6, 0xe0);
4206+ rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
4207+ rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
4208+ rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
4209+ rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
4210+ rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
4211+ rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
4212+ rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
4213+ rt2800_rfcsr_write(rt2x00dev, 16, 0x00);
4214+ rt2800_rfcsr_write(rt2x00dev, 18, 0x03);
4215+ rt2800_rfcsr_write(rt2x00dev, 19, 0x4d);
4216+ rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
4217+ rt2800_rfcsr_write(rt2x00dev, 21, 0x8d);
4218+ rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
4219+ rt2800_rfcsr_write(rt2x00dev, 23, 0x0b);
4220+ rt2800_rfcsr_write(rt2x00dev, 24, 0x44);
4221+ rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
4222+ rt2800_rfcsr_write(rt2x00dev, 26, 0x82);
4223+ rt2800_rfcsr_write(rt2x00dev, 27, 0x09);
4224+ rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
4225+ rt2800_rfcsr_write(rt2x00dev, 29, 0x10);
4226+ rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
4227+ rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
4228+ rt2800_rfcsr_write(rt2x00dev, 32, 0x20);
4229+ rt2800_rfcsr_write(rt2x00dev, 33, 0xC0);
4230+ rt2800_rfcsr_write(rt2x00dev, 34, 0x07);
4231+ rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
4232+ rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
4233+ rt2800_rfcsr_write(rt2x00dev, 37, 0x08);
4234+ rt2800_rfcsr_write(rt2x00dev, 38, 0x89);
4235+ rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
4236+ rt2800_rfcsr_write(rt2x00dev, 40, 0x0f);
4237+ rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
4238+ rt2800_rfcsr_write(rt2x00dev, 42, 0xd5);
4239+ rt2800_rfcsr_write(rt2x00dev, 43, 0x9b);
4240+ rt2800_rfcsr_write(rt2x00dev, 44, 0x0e);
4241+ rt2800_rfcsr_write(rt2x00dev, 45, 0xa2);
4242+ rt2800_rfcsr_write(rt2x00dev, 46, 0x73);
4243+ rt2800_rfcsr_write(rt2x00dev, 47, 0x0c);
4244+ rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
4245+ rt2800_rfcsr_write(rt2x00dev, 49, 0x94);
4246+ rt2800_rfcsr_write(rt2x00dev, 50, 0x94);
4247+ rt2800_rfcsr_write(rt2x00dev, 51, 0x3a);
4248+ rt2800_rfcsr_write(rt2x00dev, 52, 0x48);
4249+ rt2800_rfcsr_write(rt2x00dev, 53, 0x44);
4250+ rt2800_rfcsr_write(rt2x00dev, 54, 0x38);
4251+ rt2800_rfcsr_write(rt2x00dev, 55, 0x43);
4252+ rt2800_rfcsr_write(rt2x00dev, 56, 0xa1);
4253+ rt2800_rfcsr_write(rt2x00dev, 57, 0x00);
4254+ rt2800_rfcsr_write(rt2x00dev, 58, 0x39);
4255+ rt2800_rfcsr_write(rt2x00dev, 59, 0x07);
4256+ rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
4257+ rt2800_rfcsr_write(rt2x00dev, 61, 0x91);
4258+ rt2800_rfcsr_write(rt2x00dev, 62, 0x39);
4259+ rt2800_rfcsr_write(rt2x00dev, 63, 0x07);
4260+}
4261+
38694262 static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
38704263 {
38714264 struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
@@ -3889,6 +4282,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) · 17 unmodified lines
38894282 /*
38904283 * Init RF calibration.
38914284 */
4285+
38924286 if (rt2x00_rt(rt2x00dev, RT3290) ||
38934287 rt2x00_rt(rt2x00dev, RT5390) ||
38944288 rt2x00_rt(rt2x00dev, RT5392)) {
@@ -3907,379 +4301,35 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) · 12 unmodified lines
39074301 rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
39084302 }
39094303
3910− if (rt2x00_rt(rt2x00dev, RT3070) ||
3911− rt2x00_rt(rt2x00dev, RT3071) ||
3912− rt2x00_rt(rt2x00dev, RT3090)) {
3913− rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
3914− rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
3915− rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
3916− rt2800_rfcsr_write(rt2x00dev, 7, 0x60);
3917− rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
3918− rt2800_rfcsr_write(rt2x00dev, 10, 0x41);
3919− rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
3920− rt2800_rfcsr_write(rt2x00dev, 12, 0x7b);
3921− rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
3922− rt2800_rfcsr_write(rt2x00dev, 15, 0x58);
3923− rt2800_rfcsr_write(rt2x00dev, 16, 0xb3);
3924− rt2800_rfcsr_write(rt2x00dev, 17, 0x92);
3925− rt2800_rfcsr_write(rt2x00dev, 18, 0x2c);
3926− rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
3927− rt2800_rfcsr_write(rt2x00dev, 20, 0xba);
3928− rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
3929− rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
3930− rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
3931− rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
3932− } else if (rt2x00_rt(rt2x00dev, RT3290)) {
3933− rt2800_rfcsr_write(rt2x00dev, 1, 0x0f);
3934− rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
3935− rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
3936− rt2800_rfcsr_write(rt2x00dev, 4, 0x00);
3937− rt2800_rfcsr_write(rt2x00dev, 6, 0xa0);
3938− rt2800_rfcsr_write(rt2x00dev, 8, 0xf3);
3939− rt2800_rfcsr_write(rt2x00dev, 9, 0x02);
3940− rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
3941− rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
3942− rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
3943− rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
3944− rt2800_rfcsr_write(rt2x00dev, 18, 0x02);
3945− rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
3946− rt2800_rfcsr_write(rt2x00dev, 25, 0x83);
3947− rt2800_rfcsr_write(rt2x00dev, 26, 0x82);
3948− rt2800_rfcsr_write(rt2x00dev, 27, 0x09);
3949− rt2800_rfcsr_write(rt2x00dev, 29, 0x10);
3950− rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
3951− rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
3952− rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
3953− rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
3954− rt2800_rfcsr_write(rt2x00dev, 34, 0x05);
3955− rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
3956− rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
3957− rt2800_rfcsr_write(rt2x00dev, 38, 0x85);
3958− rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
3959− rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
3960− rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
3961− rt2800_rfcsr_write(rt2x00dev, 42, 0xd5);
3962− rt2800_rfcsr_write(rt2x00dev, 43, 0x7b);
3963− rt2800_rfcsr_write(rt2x00dev, 44, 0x0e);
3964− rt2800_rfcsr_write(rt2x00dev, 45, 0xa2);
3965− rt2800_rfcsr_write(rt2x00dev, 46, 0x73);
3966− rt2800_rfcsr_write(rt2x00dev, 47, 0x00);
3967− rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
3968− rt2800_rfcsr_write(rt2x00dev, 49, 0x98);
3969− rt2800_rfcsr_write(rt2x00dev, 52, 0x38);
3970− rt2800_rfcsr_write(rt2x00dev, 53, 0x00);
3971− rt2800_rfcsr_write(rt2x00dev, 54, 0x78);
3972− rt2800_rfcsr_write(rt2x00dev, 55, 0x43);
3973− rt2800_rfcsr_write(rt2x00dev, 56, 0x02);
3974− rt2800_rfcsr_write(rt2x00dev, 57, 0x80);
3975− rt2800_rfcsr_write(rt2x00dev, 58, 0x7f);
3976− rt2800_rfcsr_write(rt2x00dev, 59, 0x09);
3977− rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
3978− rt2800_rfcsr_write(rt2x00dev, 61, 0xc1);
3979− } else if (rt2x00_rt(rt2x00dev, RT3390)) {
3980− rt2800_rfcsr_write(rt2x00dev, 0, 0xa0);
3981− rt2800_rfcsr_write(rt2x00dev, 1, 0xe1);
3982− rt2800_rfcsr_write(rt2x00dev, 2, 0xf1);
3983− rt2800_rfcsr_write(rt2x00dev, 3, 0x62);
3984− rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
3985− rt2800_rfcsr_write(rt2x00dev, 5, 0x8b);
3986− rt2800_rfcsr_write(rt2x00dev, 6, 0x42);
3987− rt2800_rfcsr_write(rt2x00dev, 7, 0x34);
3988− rt2800_rfcsr_write(rt2x00dev, 8, 0x00);
3989− rt2800_rfcsr_write(rt2x00dev, 9, 0xc0);
3990− rt2800_rfcsr_write(rt2x00dev, 10, 0x61);
3991− rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
3992− rt2800_rfcsr_write(rt2x00dev, 12, 0x3b);
3993− rt2800_rfcsr_write(rt2x00dev, 13, 0xe0);
3994− rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
3995− rt2800_rfcsr_write(rt2x00dev, 15, 0x53);
3996− rt2800_rfcsr_write(rt2x00dev, 16, 0xe0);
3997− rt2800_rfcsr_write(rt2x00dev, 17, 0x94);
3998− rt2800_rfcsr_write(rt2x00dev, 18, 0x5c);
3999− rt2800_rfcsr_write(rt2x00dev, 19, 0x4a);
4000− rt2800_rfcsr_write(rt2x00dev, 20, 0xb2);
4001− rt2800_rfcsr_write(rt2x00dev, 21, 0xf6);
4002− rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
4003− rt2800_rfcsr_write(rt2x00dev, 23, 0x14);
4004− rt2800_rfcsr_write(rt2x00dev, 24, 0x08);
4005− rt2800_rfcsr_write(rt2x00dev, 25, 0x3d);
4006− rt2800_rfcsr_write(rt2x00dev, 26, 0x85);
4007− rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
4008− rt2800_rfcsr_write(rt2x00dev, 28, 0x41);
4009− rt2800_rfcsr_write(rt2x00dev, 29, 0x8f);
4010− rt2800_rfcsr_write(rt2x00dev, 30, 0x20);
4011− rt2800_rfcsr_write(rt2x00dev, 31, 0x0f);
4012− } else if (rt2x00_rt(rt2x00dev, RT3572)) {
4013− rt2800_rfcsr_write(rt2x00dev, 0, 0x70);
4014− rt2800_rfcsr_write(rt2x00dev, 1, 0x81);
4015− rt2800_rfcsr_write(rt2x00dev, 2, 0xf1);
4016− rt2800_rfcsr_write(rt2x00dev, 3, 0x02);
4017− rt2800_rfcsr_write(rt2x00dev, 4, 0x4c);
4018− rt2800_rfcsr_write(rt2x00dev, 5, 0x05);
4019− rt2800_rfcsr_write(rt2x00dev, 6, 0x4a);
4020− rt2800_rfcsr_write(rt2x00dev, 7, 0xd8);
4021− rt2800_rfcsr_write(rt2x00dev, 9, 0xc3);
4022− rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
4023− rt2800_rfcsr_write(rt2x00dev, 11, 0xb9);
4024− rt2800_rfcsr_write(rt2x00dev, 12, 0x70);
4025− rt2800_rfcsr_write(rt2x00dev, 13, 0x65);
4026− rt2800_rfcsr_write(rt2x00dev, 14, 0xa0);
4027− rt2800_rfcsr_write(rt2x00dev, 15, 0x53);
4028− rt2800_rfcsr_write(rt2x00dev, 16, 0x4c);
4029− rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
4030− rt2800_rfcsr_write(rt2x00dev, 18, 0xac);
4031− rt2800_rfcsr_write(rt2x00dev, 19, 0x93);
4032− rt2800_rfcsr_write(rt2x00dev, 20, 0xb3);
4033− rt2800_rfcsr_write(rt2x00dev, 21, 0xd0);
4034− rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
4035− rt2800_rfcsr_write(rt2x00dev, 23, 0x3c);
4036− rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
4037− rt2800_rfcsr_write(rt2x00dev, 25, 0x15);
4038− rt2800_rfcsr_write(rt2x00dev, 26, 0x85);
4039− rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
4040− rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
4041− rt2800_rfcsr_write(rt2x00dev, 29, 0x9b);
4042− rt2800_rfcsr_write(rt2x00dev, 30, 0x09);
4043− rt2800_rfcsr_write(rt2x00dev, 31, 0x10);
4044− } else if (rt2800_is_305x_soc(rt2x00dev)) {
4045− rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
4046− rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
4047− rt2800_rfcsr_write(rt2x00dev, 2, 0xf7);
4048− rt2800_rfcsr_write(rt2x00dev, 3, 0x75);
4049− rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
4050− rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
4051− rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
4052− rt2800_rfcsr_write(rt2x00dev, 7, 0x50);
4053− rt2800_rfcsr_write(rt2x00dev, 8, 0x39);
4054− rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
4055− rt2800_rfcsr_write(rt2x00dev, 10, 0x60);
4056− rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
4057− rt2800_rfcsr_write(rt2x00dev, 12, 0x75);
4058− rt2800_rfcsr_write(rt2x00dev, 13, 0x75);
4059− rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
4060− rt2800_rfcsr_write(rt2x00dev, 15, 0x58);
4061− rt2800_rfcsr_write(rt2x00dev, 16, 0xb3);
4062− rt2800_rfcsr_write(rt2x00dev, 17, 0x92);
4063− rt2800_rfcsr_write(rt2x00dev, 18, 0x2c);
4064− rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
4065− rt2800_rfcsr_write(rt2x00dev, 20, 0xba);
4066− rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
4067− rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
4068− rt2800_rfcsr_write(rt2x00dev, 23, 0x31);
4069− rt2800_rfcsr_write(rt2x00dev, 24, 0x08);
4070− rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
4071− rt2800_rfcsr_write(rt2x00dev, 26, 0x25);
4072− rt2800_rfcsr_write(rt2x00dev, 27, 0x23);
4073− rt2800_rfcsr_write(rt2x00dev, 28, 0x13);
4074− rt2800_rfcsr_write(rt2x00dev, 29, 0x83);
4075− rt2800_rfcsr_write(rt2x00dev, 30, 0x00);
4076− rt2800_rfcsr_write(rt2x00dev, 31, 0x00);
4304+ if (rt2800_is_305x_soc(rt2x00dev)) {
4305+ rt2800_init_rfcsr_305x_soc(rt2x00dev);
40774306 return 0;
4078− } else if (rt2x00_rt(rt2x00dev, RT3352)) {
4079− rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
4080− rt2800_rfcsr_write(rt2x00dev, 1, 0x23);
4081− rt2800_rfcsr_write(rt2x00dev, 2, 0x50);
4082− rt2800_rfcsr_write(rt2x00dev, 3, 0x18);
4083− rt2800_rfcsr_write(rt2x00dev, 4, 0x00);
4084− rt2800_rfcsr_write(rt2x00dev, 5, 0x00);
4085− rt2800_rfcsr_write(rt2x00dev, 6, 0x33);
4086− rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
4087− rt2800_rfcsr_write(rt2x00dev, 8, 0xf1);
4088− rt2800_rfcsr_write(rt2x00dev, 9, 0x02);
4089− rt2800_rfcsr_write(rt2x00dev, 10, 0xd2);
4090− rt2800_rfcsr_write(rt2x00dev, 11, 0x42);
4091− rt2800_rfcsr_write(rt2x00dev, 12, 0x1c);
4092− rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
4093− rt2800_rfcsr_write(rt2x00dev, 14, 0x5a);
4094− rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
4095− rt2800_rfcsr_write(rt2x00dev, 16, 0x01);
4096− rt2800_rfcsr_write(rt2x00dev, 18, 0x45);
4097− rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
4098− rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
4099− rt2800_rfcsr_write(rt2x00dev, 21, 0x00);
4100− rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
4101− rt2800_rfcsr_write(rt2x00dev, 23, 0x00);
4102− rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
4103− rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
4104− rt2800_rfcsr_write(rt2x00dev, 26, 0x00);
4105− rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
4106− rt2800_rfcsr_write(rt2x00dev, 28, 0x03);
4107− rt2800_rfcsr_write(rt2x00dev, 29, 0x00);
4108− rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
4109− rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
4110− rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
4111− rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
4112− rt2800_rfcsr_write(rt2x00dev, 34, 0x01);
4113− rt2800_rfcsr_write(rt2x00dev, 35, 0x03);
4114− rt2800_rfcsr_write(rt2x00dev, 36, 0xbd);
4115− rt2800_rfcsr_write(rt2x00dev, 37, 0x3c);
4116− rt2800_rfcsr_write(rt2x00dev, 38, 0x5f);
4117− rt2800_rfcsr_write(rt2x00dev, 39, 0xc5);
4118− rt2800_rfcsr_write(rt2x00dev, 40, 0x33);
4119− rt2800_rfcsr_write(rt2x00dev, 41, 0x5b);
4120− rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
4121− rt2800_rfcsr_write(rt2x00dev, 43, 0xdb);
4122− rt2800_rfcsr_write(rt2x00dev, 44, 0xdb);
4123− rt2800_rfcsr_write(rt2x00dev, 45, 0xdb);
4124− rt2800_rfcsr_write(rt2x00dev, 46, 0xdd);
4125− rt2800_rfcsr_write(rt2x00dev, 47, 0x0d);
4126− rt2800_rfcsr_write(rt2x00dev, 48, 0x14);
4127− rt2800_rfcsr_write(rt2x00dev, 49, 0x00);
4128− rt2800_rfcsr_write(rt2x00dev, 50, 0x2d);
4129− rt2800_rfcsr_write(rt2x00dev, 51, 0x7f);
4130− rt2800_rfcsr_write(rt2x00dev, 52, 0x00);
4131− rt2800_rfcsr_write(rt2x00dev, 53, 0x52);
4132− rt2800_rfcsr_write(rt2x00dev, 54, 0x1b);
4133− rt2800_rfcsr_write(rt2x00dev, 55, 0x7f);
4134− rt2800_rfcsr_write(rt2x00dev, 56, 0x00);
4135− rt2800_rfcsr_write(rt2x00dev, 57, 0x52);
4136− rt2800_rfcsr_write(rt2x00dev, 58, 0x1b);
4137− rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
4138− rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
4139− rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
4140− rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
4141− rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
4142− } else if (rt2x00_rt(rt2x00dev, RT5390)) {
4143− rt2800_rfcsr_write(rt2x00dev, 1, 0x0f);
4144− rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
4145− rt2800_rfcsr_write(rt2x00dev, 3, 0x88);
4146− rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
4147− if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
4148− rt2800_rfcsr_write(rt2x00dev, 6, 0xe0);
4149− else
4150− rt2800_rfcsr_write(rt2x00dev, 6, 0xa0);
4151− rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
4152− rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
4153− rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
4154− rt2800_rfcsr_write(rt2x00dev, 12, 0xc6);
4155− rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
4156− rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
4157− rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
4158− rt2800_rfcsr_write(rt2x00dev, 16, 0x00);
4159− rt2800_rfcsr_write(rt2x00dev, 18, 0x03);
4160− rt2800_rfcsr_write(rt2x00dev, 19, 0x00);
4161−
4162− rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
4163− rt2800_rfcsr_write(rt2x00dev, 21, 0x00);
4164− rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
4165− rt2800_rfcsr_write(rt2x00dev, 23, 0x00);
4166− rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
4167− if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
4168− rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
4169− else
4170− rt2800_rfcsr_write(rt2x00dev, 25, 0xc0);
4171− rt2800_rfcsr_write(rt2x00dev, 26, 0x00);
4172− rt2800_rfcsr_write(rt2x00dev, 27, 0x09);
4173− rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
4174− rt2800_rfcsr_write(rt2x00dev, 29, 0x10);
4175−
4176− rt2800_rfcsr_write(rt2x00dev, 30, 0x00);
4177− rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
4178− rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
4179− rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
4180− rt2800_rfcsr_write(rt2x00dev, 34, 0x07);
4181− rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
4182− rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
4183− rt2800_rfcsr_write(rt2x00dev, 37, 0x08);
4184− rt2800_rfcsr_write(rt2x00dev, 38, 0x85);
4185− rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
4186−
4187− if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
4188− rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
4189− else
4190− rt2800_rfcsr_write(rt2x00dev, 40, 0x4b);
4191− rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
4192− rt2800_rfcsr_write(rt2x00dev, 42, 0xd2);
4193− rt2800_rfcsr_write(rt2x00dev, 43, 0x9a);
4194− rt2800_rfcsr_write(rt2x00dev, 44, 0x0e);
4195− rt2800_rfcsr_write(rt2x00dev, 45, 0xa2);
4196− if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
4197− rt2800_rfcsr_write(rt2x00dev, 46, 0x73);
4198− else
4199− rt2800_rfcsr_write(rt2x00dev, 46, 0x7b);
4200− rt2800_rfcsr_write(rt2x00dev, 47, 0x00);
4201− rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
4202− rt2800_rfcsr_write(rt2x00dev, 49, 0x94);
4203−
4204− rt2800_rfcsr_write(rt2x00dev, 52, 0x38);
4205− if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
4206− rt2800_rfcsr_write(rt2x00dev, 53, 0x00);
4207− else
4208− rt2800_rfcsr_write(rt2x00dev, 53, 0x84);
4209− rt2800_rfcsr_write(rt2x00dev, 54, 0x78);
4210− rt2800_rfcsr_write(rt2x00dev, 55, 0x44);
4211− rt2800_rfcsr_write(rt2x00dev, 56, 0x22);
4212− rt2800_rfcsr_write(rt2x00dev, 57, 0x80);
4213− rt2800_rfcsr_write(rt2x00dev, 58, 0x7f);
4214− rt2800_rfcsr_write(rt2x00dev, 59, 0x63);
4215−
4216− rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
4217− if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
4218− rt2800_rfcsr_write(rt2x00dev, 61, 0xd1);
4219− else
4220− rt2800_rfcsr_write(rt2x00dev, 61, 0xdd);
4221− rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
4222− rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
4223− } else if (rt2x00_rt(rt2x00dev, RT5392)) {
4224− rt2800_rfcsr_write(rt2x00dev, 1, 0x17);
4225− rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
4226− rt2800_rfcsr_write(rt2x00dev, 3, 0x88);
4227− rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
4228− rt2800_rfcsr_write(rt2x00dev, 6, 0xe0);
4229− rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
4230− rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
4231− rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
4232− rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
4233− rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
4234− rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
4235− rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
4236− rt2800_rfcsr_write(rt2x00dev, 16, 0x00);
4237− rt2800_rfcsr_write(rt2x00dev, 18, 0x03);
4238− rt2800_rfcsr_write(rt2x00dev, 19, 0x4d);
4239− rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
4240− rt2800_rfcsr_write(rt2x00dev, 21, 0x8d);
4241− rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
4242− rt2800_rfcsr_write(rt2x00dev, 23, 0x0b);
4243− rt2800_rfcsr_write(rt2x00dev, 24, 0x44);
4244− rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
4245− rt2800_rfcsr_write(rt2x00dev, 26, 0x82);
4246− rt2800_rfcsr_write(rt2x00dev, 27, 0x09);
4247− rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
4248− rt2800_rfcsr_write(rt2x00dev, 29, 0x10);
4249− rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
4250− rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
4251− rt2800_rfcsr_write(rt2x00dev, 32, 0x20);
4252− rt2800_rfcsr_write(rt2x00dev, 33, 0xC0);
4253− rt2800_rfcsr_write(rt2x00dev, 34, 0x07);
4254− rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
4255− rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
4256− rt2800_rfcsr_write(rt2x00dev, 37, 0x08);
4257− rt2800_rfcsr_write(rt2x00dev, 38, 0x89);
4258− rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
4259− rt2800_rfcsr_write(rt2x00dev, 40, 0x0f);
4260− rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
4261− rt2800_rfcsr_write(rt2x00dev, 42, 0xd5);
4262− rt2800_rfcsr_write(rt2x00dev, 43, 0x9b);
4263− rt2800_rfcsr_write(rt2x00dev, 44, 0x0e);
4264− rt2800_rfcsr_write(rt2x00dev, 45, 0xa2);
4265− rt2800_rfcsr_write(rt2x00dev, 46, 0x73);
4266− rt2800_rfcsr_write(rt2x00dev, 47, 0x0c);
4267− rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
4268− rt2800_rfcsr_write(rt2x00dev, 49, 0x94);
4269− rt2800_rfcsr_write(rt2x00dev, 50, 0x94);
4270− rt2800_rfcsr_write(rt2x00dev, 51, 0x3a);
4271− rt2800_rfcsr_write(rt2x00dev, 52, 0x48);
4272− rt2800_rfcsr_write(rt2x00dev, 53, 0x44);
4273− rt2800_rfcsr_write(rt2x00dev, 54, 0x38);
4274− rt2800_rfcsr_write(rt2x00dev, 55, 0x43);
4275− rt2800_rfcsr_write(rt2x00dev, 56, 0xa1);
4276− rt2800_rfcsr_write(rt2x00dev, 57, 0x00);
4277− rt2800_rfcsr_write(rt2x00dev, 58, 0x39);
4278− rt2800_rfcsr_write(rt2x00dev, 59, 0x07);
4279− rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
4280− rt2800_rfcsr_write(rt2x00dev, 61, 0x91);
4281− rt2800_rfcsr_write(rt2x00dev, 62, 0x39);
4282− rt2800_rfcsr_write(rt2x00dev, 63, 0x07);
4307+ }
4308+
4309+ switch (rt2x00dev->chip.rt) {
4310+ case RT3070:
4311+ case RT3071:
4312+ case RT3090:
4313+ rt2800_init_rfcsr_30xx(rt2x00dev);
4314+ break;
4315+ case RT3290:
4316+ rt2800_init_rfcsr_3290(rt2x00dev);
4317+ break;
4318+ case RT3352:
4319+ rt2800_init_rfcsr_3352(rt2x00dev);
4320+ break;
4321+ case RT3390:
4322+ rt2800_init_rfcsr_3390(rt2x00dev);
4323+ break;
4324+ case RT3572:
4325+ rt2800_init_rfcsr_3572(rt2x00dev);
4326+ break;
4327+ case RT5390:
4328+ rt2800_init_rfcsr_5390(rt2x00dev);
4329+ break;
4330+ case RT5392:
4331+ rt2800_init_rfcsr_5392(rt2x00dev);
4332+ break;
42834333 }
42844334
42854335 if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) {
@@ -4620,12 +4670,14 @@ static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i) · 334 unmodified lines
46204670 mutex_unlock(&rt2x00dev->csr_mutex);
46214671 }
46224672
4623−void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
4673+int rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
46244674 {
46254675 unsigned int i;
46264676
46274677 for (i = 0; i < EEPROM_SIZE / sizeof(u16); i += 8)
46284678 rt2800_efuse_read(rt2x00dev, i);
4679+
4680+ return 0;
46294681 }
46304682 EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse);
46314683
@@ -4635,11 +4687,14 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) · 3 unmodified lines
46354687 u16 word;
46364688 u8 *mac;
46374689 u8 default_lna_gain;
4690+ int retval;
46384691
46394692 /*
46404693 * Read the EEPROM.
46414694 */
4642− rt2800_read_eeprom(rt2x00dev);
4695+ retval = rt2800_read_eeprom(rt2x00dev);
4696+ if (retval)
4697+ return retval;
46434698
46444699 /*
46454700 * Start validation of the data that has been read.
@@ -5090,8 +5145,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) · 444 unmodified lines
50905145 IEEE80211_HW_SUPPORTS_PS |
50915146 IEEE80211_HW_PS_NULLFUNC_STACK |
50925147 IEEE80211_HW_AMPDU_AGGREGATION |
5093− IEEE80211_HW_REPORTS_TX_ACK_STATUS |
5094− IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL;
5148+ IEEE80211_HW_REPORTS_TX_ACK_STATUS;
50955149
50965150 /*
50975151 * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices
drivers/net/wireless/rt2x00/rt2800lib.h+4−4
@@ -43,7 +43,7 @@ struct rt2800_ops { · 42 unmodified lines
4343 const unsigned int offset,
4444 const struct rt2x00_field32 field, u32 *reg);
4545
46− void (*read_eeprom)(struct rt2x00_dev *rt2x00dev);
46+ int (*read_eeprom)(struct rt2x00_dev *rt2x00dev);
4747 bool (*hwcrypt_disabled)(struct rt2x00_dev *rt2x00dev);
4848
4949 int (*drv_write_firmware)(struct rt2x00_dev *rt2x00dev,
@@ -117,11 +117,11 @@ static inline int rt2800_regbusy_read(struct rt2x00_dev *rt2x00dev, · 67 unmodified lines
117117 return rt2800ops->regbusy_read(rt2x00dev, offset, field, reg);
118118 }
119119
120−static inline void rt2800_read_eeprom(struct rt2x00_dev *rt2x00dev)
120+static inline int rt2800_read_eeprom(struct rt2x00_dev *rt2x00dev)
121121 {
122122 const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
123123
124− rt2800ops->read_eeprom(rt2x00dev);
124+ return rt2800ops->read_eeprom(rt2x00dev);
125125 }
126126
127127 static inline bool rt2800_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev)
@@ -207,7 +207,7 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev); · 79 unmodified lines
207207 void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev);
208208
209209 int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev);
210−void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev);
210+int rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev);
211211
212212 int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev);
213213
drivers/net/wireless/rt2x00/rt2800pci.c+24−11
@@ -90,17 +90,22 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token) · 89 unmodified lines
9090 }
9191
9292 #if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
93−static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
93+static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
9494 {
9595 void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
9696
97+ if (!base_addr)
98+ return -ENOMEM;
99+
97100 memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE);
98101
99102 iounmap(base_addr);
103+ return 0;
100104 }
101105 #else
102−static inline void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
106+static inline int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
103107 {
108+ return -ENOMEM;
104109 }
105110 #endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
106111
@@ -135,7 +140,7 @@ static void rt2800pci_eepromregister_write(struct eeprom_93cx6 *eeprom) · 28 unmodified lines
135140 rt2x00pci_register_write(rt2x00dev, E2PROM_CSR, reg);
136141 }
137142
138−static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev)
143+static int rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev)
139144 {
140145 struct eeprom_93cx6 eeprom;
141146 u32 reg;
@@ -164,6 +169,8 @@ static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) · 22 unmodified lines
164169
165170 eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom,
166171 EEPROM_SIZE / sizeof(u16));
172+
173+ return 0;
167174 }
168175
169176 static int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev)
@@ -171,13 +178,14 @@ static int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) · 1 unmodified line
171178 return rt2800_efuse_detect(rt2x00dev);
172179 }
173180
174−static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
181+static inline int rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
175182 {
176− rt2800_read_eeprom_efuse(rt2x00dev);
183+ return rt2800_read_eeprom_efuse(rt2x00dev);
177184 }
178185 #else
179−static inline void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev)
186+static inline int rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev)
180187 {
188+ return -EOPNOTSUPP;
181189 }
182190
183191 static inline int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev)
@@ -185,8 +193,9 @@ static inline int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) · 1 unmodified line
185193 return 0;
186194 }
187195
188−static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
196+static inline int rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
189197 {
198+ return -EOPNOTSUPP;
190199 }
191200 #endif /* CONFIG_PCI */
192201
@@ -970,14 +979,18 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) · 777 unmodified lines
970979 /*
971980 * Device probe functions.
972981 */
973−static void rt2800pci_read_eeprom(struct rt2x00_dev *rt2x00dev)
982+static int rt2800pci_read_eeprom(struct rt2x00_dev *rt2x00dev)
974983 {
984+ int retval;
985+
975986 if (rt2x00_is_soc(rt2x00dev))
976− rt2800pci_read_eeprom_soc(rt2x00dev);
987+ retval = rt2800pci_read_eeprom_soc(rt2x00dev);
977988 else if (rt2800pci_efuse_detect(rt2x00dev))
978− rt2800pci_read_eeprom_efuse(rt2x00dev);
989+ retval = rt2800pci_read_eeprom_efuse(rt2x00dev);
979990 else
980− rt2800pci_read_eeprom_pci(rt2x00dev);
991+ retval = rt2800pci_read_eeprom_pci(rt2x00dev);
992+
993+ return retval;
981994 }
982995
983996 static const struct ieee80211_ops rt2800pci_mac80211_ops = {
drivers/net/wireless/rt2x00/rt2800usb.c+8−4
@@ -735,13 +735,17 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, · 734 unmodified lines
735735 /*
736736 * Device probe functions.
737737 */
738−static void rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev)
738+static int rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev)
739739 {
740+ int retval;
741+
740742 if (rt2800_efuse_detect(rt2x00dev))
741− rt2800_read_eeprom_efuse(rt2x00dev);
743+ retval = rt2800_read_eeprom_efuse(rt2x00dev);
742744 else
743− rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom,
744− EEPROM_SIZE);
745+ retval = rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom,
746+ EEPROM_SIZE);
747+
748+ return retval;
745749 }
746750
747751 static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
drivers/net/wireless/rt2x00/rt2x00.h+20−0
@@ -1016,6 +1016,26 @@ struct rt2x00_dev { · 1015 unmodified lines
10161016 * Protect the interrupt mask register.
10171017 */
10181018 spinlock_t irqmask_lock;
1019+
1020+ /*
1021+ * List of BlockAckReq TX entries that need driver BlockAck processing.
1022+ */
1023+ struct list_head bar_list;
1024+ spinlock_t bar_list_lock;
1025+};
1026+
1027+struct rt2x00_bar_list_entry {
1028+ struct list_head list;
1029+ struct rcu_head head;
1030+
1031+ struct queue_entry *entry;
1032+ int block_acked;
1033+
1034+ /* Relevant parts of the IEEE80211 BAR header */
1035+ __u8 ra[6];
1036+ __u8 ta[6];
1037+ __le16 control;
1038+ __le16 start_seq_num;
10191039 };
10201040
10211041 /*
drivers/net/wireless/rt2x00/rt2x00dev.c+100−1
@@ -271,6 +271,50 @@ void rt2x00lib_dmadone(struct queue_entry *entry) · 270 unmodified lines
271271 }
272272 EXPORT_SYMBOL_GPL(rt2x00lib_dmadone);
273273
274+static inline int rt2x00lib_txdone_bar_status(struct queue_entry *entry)
275+{
276+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
277+ struct ieee80211_bar *bar = (void *) entry->skb->data;
278+ struct rt2x00_bar_list_entry *bar_entry;
279+ int ret;
280+
281+ if (likely(!ieee80211_is_back_req(bar->frame_control)))
282+ return 0;
283+
284+ /*
285+ * Unlike all other frames, the status report for BARs does
286+ * not directly come from the hardware as it is incapable of
287+ * matching a BA to a previously send BAR. The hardware will
288+ * report all BARs as if they weren't acked at all.
289+ *
290+ * Instead the RX-path will scan for incoming BAs and set the
291+ * block_acked flag if it sees one that was likely caused by
292+ * a BAR from us.
293+ *
294+ * Remove remaining BARs here and return their status for
295+ * TX done processing.
296+ */
297+ ret = 0;
298+ rcu_read_lock();
299+ list_for_each_entry_rcu(bar_entry, &rt2x00dev->bar_list, list) {
300+ if (bar_entry->entry != entry)
301+ continue;
302+
303+ spin_lock_bh(&rt2x00dev->bar_list_lock);
304+ /* Return whether this BAR was blockacked or not */
305+ ret = bar_entry->block_acked;
306+ /* Remove the BAR from our checklist */
307+ list_del_rcu(&bar_entry->list);
308+ spin_unlock_bh(&rt2x00dev->bar_list_lock);
309+ kfree_rcu(bar_entry, head);
310+
311+ break;
312+ }
313+ rcu_read_unlock();
314+
315+ return ret;
316+}
317+
274318 void rt2x00lib_txdone(struct queue_entry *entry,
275319 struct txdone_entry_desc *txdesc)
276320 {
@@ -324,9 +368,12 @@ void rt2x00lib_txdone(struct queue_entry *entry, · 47 unmodified lines
324368 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry->skb);
325369
326370 /*
327− * Determine if the frame has been successfully transmitted.
371+ * Determine if the frame has been successfully transmitted and
372+ * remove BARs from our check list while checking for their
373+ * TX status.
328374 */
329375 success =
376+ rt2x00lib_txdone_bar_status(entry) ||
330377 test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
331378 test_bit(TXDONE_UNKNOWN, &txdesc->flags);
332379
@@ -491,6 +538,50 @@ static void rt2x00lib_sleep(struct work_struct *work) · 158 unmodified lines
491538 IEEE80211_CONF_CHANGE_PS);
492539 }
493540
541+static void rt2x00lib_rxdone_check_ba(struct rt2x00_dev *rt2x00dev,
542+ struct sk_buff *skb,
543+ struct rxdone_entry_desc *rxdesc)
544+{
545+ struct rt2x00_bar_list_entry *entry;
546+ struct ieee80211_bar *ba = (void *)skb->data;
547+
548+ if (likely(!ieee80211_is_back(ba->frame_control)))
549+ return;
550+
551+ if (rxdesc->size < sizeof(*ba) + FCS_LEN)
552+ return;
553+
554+ rcu_read_lock();
555+ list_for_each_entry_rcu(entry, &rt2x00dev->bar_list, list) {
556+
557+ if (ba->start_seq_num != entry->start_seq_num)
558+ continue;
559+
560+#define TID_CHECK(a, b) ( \
561+ ((a) & cpu_to_le16(IEEE80211_BAR_CTRL_TID_INFO_MASK)) == \
562+ ((b) & cpu_to_le16(IEEE80211_BAR_CTRL_TID_INFO_MASK))) \
563+
564+ if (!TID_CHECK(ba->control, entry->control))
565+ continue;
566+
567+#undef TID_CHECK
568+
569+ if (compare_ether_addr(ba->ra, entry->ta))
570+ continue;
571+
572+ if (compare_ether_addr(ba->ta, entry->ra))
573+ continue;
574+
575+ /* Mark BAR since we received the according BA */
576+ spin_lock_bh(&rt2x00dev->bar_list_lock);
577+ entry->block_acked = 1;
578+ spin_unlock_bh(&rt2x00dev->bar_list_lock);
579+ break;
580+ }
581+ rcu_read_unlock();
582+
583+}
584+
494585 static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev,
495586 struct sk_buff *skb,
496587 struct rxdone_entry_desc *rxdesc)
@@ -673,6 +764,12 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp) · 176 unmodified lines
673764 */
674765 rt2x00lib_rxdone_check_ps(rt2x00dev, entry->skb, &rxdesc);
675766
767+ /*
768+ * Check for incoming BlockAcks to match to the BlockAckReqs
769+ * we've send out.
770+ */
771+ rt2x00lib_rxdone_check_ba(rt2x00dev, entry->skb, &rxdesc);
772+
676773 /*
677774 * Update extra components
678775 */
@@ -1183,6 +1280,8 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) · 504 unmodified lines
11831280
11841281 spin_lock_init(&rt2x00dev->irqmask_lock);
11851282 mutex_init(&rt2x00dev->csr_mutex);
1283+ INIT_LIST_HEAD(&rt2x00dev->bar_list);
1284+ spin_lock_init(&rt2x00dev->bar_list_lock);
11861285
11871286 set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
11881287
drivers/net/wireless/rt2x00/rt2x00queue.c+47−0
@@ -582,6 +582,48 @@ static void rt2x00queue_kick_tx_queue(struct data_queue *queue, · 581 unmodified lines
582582 queue->rt2x00dev->ops->lib->kick_queue(queue);
583583 }
584584
585+static void rt2x00queue_bar_check(struct queue_entry *entry)
586+{
587+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
588+ struct ieee80211_bar *bar = (void *) (entry->skb->data +
589+ rt2x00dev->ops->extra_tx_headroom);
590+ struct rt2x00_bar_list_entry *bar_entry;
591+
592+ if (likely(!ieee80211_is_back_req(bar->frame_control)))
593+ return;
594+
595+ bar_entry = kmalloc(sizeof(*bar_entry), GFP_ATOMIC);
596+
597+ /*
598+ * If the alloc fails we still send the BAR out but just don't track
599+ * it in our bar list. And as a result we will report it to mac80211
600+ * back as failed.
601+ */
602+ if (!bar_entry)
603+ return;
604+
605+ bar_entry->entry = entry;
606+ bar_entry->block_acked = 0;
607+
608+ /*
609+ * Copy the relevant parts of the 802.11 BAR into out check list
610+ * such that we can use RCU for less-overhead in the RX path since
611+ * sending BARs and processing the according BlockAck should be
612+ * the exception.
613+ */
614+ memcpy(bar_entry->ra, bar->ra, sizeof(bar->ra));
615+ memcpy(bar_entry->ta, bar->ta, sizeof(bar->ta));
616+ bar_entry->control = bar->control;
617+ bar_entry->start_seq_num = bar->start_seq_num;
618+
619+ /*
620+ * Insert BAR into our BAR check list.
621+ */
622+ spin_lock_bh(&rt2x00dev->bar_list_lock);
623+ list_add_tail_rcu(&bar_entry->list, &rt2x00dev->bar_list);
624+ spin_unlock_bh(&rt2x00dev->bar_list_lock);
625+}
626+
585627 int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
586628 bool local)
587629 {
@@ -680,6 +722,11 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, · 92 unmodified lines
680722 goto out;
681723 }
682724
725+ /*
726+ * Put BlockAckReqs into our check list for driver BA processing.
727+ */
728+ rt2x00queue_bar_check(entry);
729+
683730 set_bit(ENTRY_DATA_PENDING, &entry->flags);
684731
685732 rt2x00queue_index_inc(entry, Q_INDEX);
drivers/net/wireless/rtlwifi/Kconfig+2−2
@@ -57,12 +57,12 @@ config RTL8192CU · 56 unmodified lines
5757
5858 config RTLWIFI
5959 tristate
60− depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE
60+ depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE || RTL8723AE
6161 default m
6262
6363 config RTLWIFI_DEBUG
6464 bool "Additional debugging output"
65− depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE
65+ depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE || RTL8723AE
6666 default y
6767
6868 config RTL8192C_COMMON
drivers/net/wireless/rtlwifi/pci.c+6−0
@@ -743,6 +743,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) · 742 unmodified lines
743743
744744 done:
745745 bufferaddress = (*((dma_addr_t *)skb->cb));
746+ if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress))
747+ return;
746748 tmp_one = 1;
747749 rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false,
748750 HW_DESC_RXBUFF_ADDR,
@@ -1115,6 +1117,10 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw) · 366 unmodified lines
11151117 PCI_DMA_FROMDEVICE);
11161118
11171119 bufferaddress = (*((dma_addr_t *)skb->cb));
1120+ if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress)) {
1121+ dev_kfree_skb_any(skb);
1122+ return 1;
1123+ }
11181124 rtlpriv->cfg->ops->set_desc((u8 *)entry, false,
11191125 HW_DESC_RXBUFF_ADDR,
11201126 (u8 *)&bufferaddress);
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c+1−1
@@ -692,7 +692,7 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) · 691 unmodified lines
692692 if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
693693 rtl92c_phy_sw_chnl_callback(hw);
694694 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
695− "sw_chnl_inprogress false schdule workitem\n");
695+ "sw_chnl_inprogress false schedule workitem\n");
696696 rtlphy->sw_chnl_inprogress = false;
697697 } else {
698698 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
drivers/net/wireless/rtlwifi/rtl8192ce/trx.c+11−0
@@ -611,8 +611,14 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, · 610 unmodified lines
611611 dma_addr_t mapping = pci_map_single(rtlpci->pdev,
612612 skb->data, skb->len,
613613 PCI_DMA_TODEVICE);
614+
614615 u8 bw_40 = 0;
615616
617+ if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
618+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
619+ "DMA mapping error");
620+ return;
621+ }
616622 rcu_read_lock();
617623 sta = get_sta(hw, mac->vif, mac->bssid);
618624 if (mac->opmode == NL80211_IFTYPE_STATION) {
@@ -774,6 +780,11 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, · 155 unmodified lines
774780 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
775781 __le16 fc = hdr->frame_control;
776782
783+ if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
784+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
785+ "DMA mapping error");
786+ return;
787+ }
777788 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
778789
779790 if (firstseg)
drivers/net/wireless/rtlwifi/rtl8192de/trx.c+11−1
@@ -452,7 +452,7 @@ static void _rtl92de_translate_rx_signal_stuff(struct ieee80211_hw *hw, · 451 unmodified lines
452452 u8 *praddr;
453453 u16 type, cfc;
454454 __le16 fc;
455− bool packet_matchbssid, packet_toself, packet_beacon;
455+ bool packet_matchbssid, packet_toself, packet_beacon = false;
456456
457457 tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
458458 hdr = (struct ieee80211_hdr *)tmp_buf;
@@ -587,6 +587,11 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, · 128 unmodified lines
587587 buf_len = skb->len;
588588 mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
589589 PCI_DMA_TODEVICE);
590+ if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
591+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
592+ "DMA mapping error");
593+ return;
594+ }
590595 CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92d));
591596 if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
592597 firstseg = true;
@@ -740,6 +745,11 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, · 147 unmodified lines
740745 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
741746 __le16 fc = hdr->frame_control;
742747
748+ if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
749+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
750+ "DMA mapping error");
751+ return;
752+ }
743753 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
744754 if (firstseg)
745755 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
drivers/net/wireless/rtlwifi/rtl8192se/trx.c+13−2
@@ -480,7 +480,7 @@ static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw, · 479 unmodified lines
480480 u8 *praddr;
481481 __le16 fc;
482482 u16 type, cfc;
483− bool packet_matchbssid, packet_toself, packet_beacon;
483+ bool packet_matchbssid, packet_toself, packet_beacon = false;
484484
485485 tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
486486
@@ -611,6 +611,11 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, · 124 unmodified lines
611611 PCI_DMA_TODEVICE);
612612 u8 bw_40 = 0;
613613
614+ if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
615+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
616+ "DMA mapping error");
617+ return;
618+ }
614619 if (mac->opmode == NL80211_IFTYPE_STATION) {
615620 bw_40 = mac->bw_40;
616621 } else if (mac->opmode == NL80211_IFTYPE_AP ||
@@ -763,6 +768,7 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, · 146 unmodified lines
763768 void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
764769 bool firstseg, bool lastseg, struct sk_buff *skb)
765770 {
771+ struct rtl_priv *rtlpriv = rtl_priv(hw);
766772 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
767773 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
768774 struct rtl_tcb_desc *tcb_desc = (struct rtl_tcb_desc *)(skb->cb);
@@ -770,7 +776,12 @@ void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, · 1 unmodified line
770776 dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
771777 PCI_DMA_TODEVICE);
772778
773− /* Clear all status */
779+ if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
780+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
781+ "DMA mapping error");
782+ return;
783+ }
784+ /* Clear all status */
774785 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_CMDDESC_SIZE_RTL8192S);
775786
776787 /* This bit indicate this packet is used for FW download. */
drivers/net/wireless/rtlwifi/rtl8723ae/phy.c+1−1
@@ -1106,7 +1106,7 @@ u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw) · 1105 unmodified lines
11061106 if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
11071107 rtl8723ae_phy_sw_chnl_callback(hw);
11081108 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1109− "sw_chnl_inprogress false schdule workitem\n");
1109+ "sw_chnl_inprogress false schedule workitem\n");
11101110 rtlphy->sw_chnl_inprogress = false;
11111111 } else {
11121112 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
drivers/net/wireless/rtlwifi/rtl8723ae/trx.c+11−1
@@ -247,7 +247,7 @@ static void _rtl8723ae_translate_rx_signal_stuff(struct ieee80211_hw *hw, · 246 unmodified lines
247247 u8 *psaddr;
248248 __le16 fc;
249249 u16 type;
250− bool packet_matchbssid, packet_toself, packet_beacon;
250+ bool packet_matchbssid, packet_toself, packet_beacon = false;
251251
252252 tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift;
253253
@@ -387,6 +387,11 @@ void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw, · 133 unmodified lines
387387 PCI_DMA_TODEVICE);
388388 u8 bw_40 = 0;
389389
390+ if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
391+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
392+ "DMA mapping error");
393+ return;
394+ }
390395 if (mac->opmode == NL80211_IFTYPE_STATION) {
391396 bw_40 = mac->bw_40;
392397 } else if (mac->opmode == NL80211_IFTYPE_AP ||
@@ -542,6 +547,11 @@ void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw, · 149 unmodified lines
542547 PCI_DMA_TODEVICE);
543548 __le16 fc = hdr->frame_control;
544549
550+ if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
551+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
552+ "DMA mapping error");
553+ return;
554+ }
545555 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
546556
547557 if (firstseg)
drivers/net/wireless/rtlwifi/usb.c+4−4
@@ -210,17 +210,16 @@ static void _usb_writeN_sync(struct rtl_priv *rtlpriv, u32 addr, void *data, · 209 unmodified lines
210210 u16 index = REALTEK_USB_VENQT_CMD_IDX;
211211 int pipe = usb_sndctrlpipe(udev, 0); /* write_out */
212212 u8 *buffer;
213− dma_addr_t dma_addr;
214213
215− wvalue = (u16)(addr&0x0000ffff);
216− buffer = usb_alloc_coherent(udev, (size_t)len, GFP_ATOMIC, &dma_addr);
214+ wvalue = (u16)(addr & 0x0000ffff);
215+ buffer = kmalloc(len, GFP_ATOMIC);
217216 if (!buffer)
218217 return;
219218 memcpy(buffer, data, len);
220219 usb_control_msg(udev, pipe, request, reqtype, wvalue,
221220 index, buffer, len, 50);
222221
223− usb_free_coherent(udev, (size_t)len, buffer, dma_addr);
222+ kfree(buffer);
224223 }
225224
226225 static void _rtl_usb_io_handler_init(struct device *dev,
@@ -640,6 +639,7 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw) · 413 unmodified lines
640639 RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
641640 "Failed to prep_rx_urb!!\n");
642641 err = PTR_ERR(skb);
642+ usb_free_urb(urb);
643643 goto err_out;
644644 }
645645
drivers/nfc/Kconfig+2−13
@@ -5,19 +5,6 @@ · 4 unmodified lines
55 menu "Near Field Communication (NFC) devices"
66 depends on NFC
77
8−config PN544_HCI_NFC
9− tristate "HCI PN544 NFC driver"
10− depends on I2C && NFC_HCI && NFC_SHDLC
11− select CRC_CCITT
12− default n
13− ---help---
14− NXP PN544 i2c driver.
15− This is a driver based on the SHDLC and HCI NFC kernel layers and
16− will thus not work with NXP libnfc library.
17−
18− To compile this driver as a module, choose m here. The module will
19− be called pn544_hci.
20−
218 config NFC_PN533
229 tristate "NXP PN533 USB driver"
2310 depends on USB
@@ -39,4 +26,6 @@ config NFC_WILINK · 15 unmodified lines
3926 Say Y here to compile support for Texas Instrument's NFC WiLink driver
4027 into the kernel or say M to compile it as module.
4128
29+source "drivers/nfc/pn544/Kconfig"
30+
4231 endmenu
drivers/nfc/Makefile+1−1
@@ -2,7 +2,7 @@ · 1 unmodified line
22 # Makefile for nfc devices
33 #
44
5−obj-$(CONFIG_PN544_HCI_NFC) += pn544/
5+obj-$(CONFIG_NFC_PN544) += pn544/
66 obj-$(CONFIG_NFC_PN533) += pn533.o
77 obj-$(CONFIG_NFC_WILINK) += nfcwilink.o
88
drivers/nfc/nfcwilink.c+3−7
@@ -526,7 +526,7 @@ static int nfcwilink_probe(struct platform_device *pdev) · 525 unmodified lines
526526
527527 nfc_dev_dbg(&pdev->dev, "probe entry");
528528
529− drv = kzalloc(sizeof(struct nfcwilink), GFP_KERNEL);
529+ drv = devm_kzalloc(&pdev->dev, sizeof(struct nfcwilink), GFP_KERNEL);
530530 if (!drv) {
531531 rc = -ENOMEM;
532532 goto exit;
@@ -542,12 +542,13 @@ static int nfcwilink_probe(struct platform_device *pdev) · 9 unmodified lines
542542
543543 drv->ndev = nci_allocate_device(&nfcwilink_ops,
544544 protocols,
545+ NFC_SE_NONE,
545546 NFCWILINK_HDR_LEN,
546547 0);
547548 if (!drv->ndev) {
548549 nfc_dev_err(&pdev->dev, "nci_allocate_device failed");
549550 rc = -ENOMEM;
550− goto free_exit;
551+ goto exit;
551552 }
552553
553554 nci_set_parent_dev(drv->ndev, &pdev->dev);
@@ -566,9 +567,6 @@ static int nfcwilink_probe(struct platform_device *pdev) · 12 unmodified lines
566567 free_dev_exit:
567568 nci_free_device(drv->ndev);
568569
569−free_exit:
570− kfree(drv);
571−
572570 exit:
573571 return rc;
574572 }
@@ -588,8 +586,6 @@ static int nfcwilink_remove(struct platform_device *pdev) · 13 unmodified lines
588586 nci_unregister_device(ndev);
589587 nci_free_device(ndev);
590588
591− kfree(drv);
592−
593589 dev_set_drvdata(&pdev->dev, NULL);
594590
595591 return 0;
drivers/nfc/pn533.c+836−757
@@ -41,11 +41,6 @@ · 40 unmodified lines
4141 #define SONY_VENDOR_ID 0x054c
4242 #define PASORI_PRODUCT_ID 0x02e1
4343
44−#define PN533_QUIRKS_TYPE_A BIT(0)
45−#define PN533_QUIRKS_TYPE_F BIT(1)
46−#define PN533_QUIRKS_DEP BIT(2)
47−#define PN533_QUIRKS_RAW_EXCHANGE BIT(3)
48−
4944 #define PN533_DEVICE_STD 0x1
5045 #define PN533_DEVICE_PASORI 0x2
5146
@@ -84,14 +79,18 @@ MODULE_DEVICE_TABLE(usb, pn533_table); · 32 unmodified lines
8479 #define PN533_LISTEN_TIME 2
8580
8681 /* frame definitions */
87−#define PN533_NORMAL_FRAME_MAX_LEN 262 /* 6 (PREAMBLE, SOF, LEN, LCS, TFI)
88− 254 (DATA)
89− 2 (DCS, postamble) */
90−
91−#define PN533_FRAME_TAIL_SIZE 2
92−#define PN533_FRAME_SIZE(f) (sizeof(struct pn533_frame) + f->datalen + \
93− PN533_FRAME_TAIL_SIZE)
94−#define PN533_FRAME_ACK_SIZE (sizeof(struct pn533_frame) + 1)
82+#define PN533_FRAME_HEADER_LEN (sizeof(struct pn533_frame) \
83+ + 2) /* data[0] TFI, data[1] CC */
84+#define PN533_FRAME_TAIL_LEN 2 /* data[len] DCS, data[len + 1] postamble*/
85+
86+/*
87+ * Max extended frame payload len, excluding TFI and CC
88+ * which are already in PN533_FRAME_HEADER_LEN.
89+ */
90+#define PN533_FRAME_MAX_PAYLOAD_LEN 263
91+
92+#define PN533_FRAME_ACK_SIZE 6 /* Preamble (1), SoPC (2), ACK Code (2),
93+ Postamble (1) */
9594 #define PN533_FRAME_CHECKSUM(f) (f->data[f->datalen])
9695 #define PN533_FRAME_POSTAMBLE(f) (f->data[f->datalen + 1])
9796
@@ -105,8 +104,6 @@ MODULE_DEVICE_TABLE(usb, pn533_table); · 7 unmodified lines
105104
106105 /* PN533 Commands */
107106 #define PN533_FRAME_CMD(f) (f->data[1])
108−#define PN533_FRAME_CMD_PARAMS_PTR(f) (&f->data[2])
109−#define PN533_FRAME_CMD_PARAMS_LEN(f) (f->datalen - 2)
110107
111108 #define PN533_CMD_GET_FIRMWARE_VERSION 0x02
112109 #define PN533_CMD_RF_CONFIGURATION 0x32
@@ -120,6 +117,7 @@ MODULE_DEVICE_TABLE(usb, pn533_table); · 7 unmodified lines
120117 #define PN533_CMD_TG_INIT_AS_TARGET 0x8c
121118 #define PN533_CMD_TG_GET_DATA 0x86
122119 #define PN533_CMD_TG_SET_DATA 0x8e
120+#define PN533_CMD_UNDEF 0xff
123121
124122 #define PN533_CMD_RESPONSE(cmd) (cmd + 1)
125123
@@ -128,13 +126,12 @@ MODULE_DEVICE_TABLE(usb, pn533_table); · 2 unmodified lines
128126 #define PN533_CMD_MI_MASK 0x40
129127 #define PN533_CMD_RET_SUCCESS 0x00
130128
131−/* PN533 status codes */
132−#define PN533_STATUS_TARGET_RELEASED 0x29
133−
134129 struct pn533;
135130
136−typedef int (*pn533_cmd_complete_t) (struct pn533 *dev, void *arg,
137− u8 *params, int params_len);
131+typedef int (*pn533_cmd_complete_t) (struct pn533 *dev, void *arg, int status);
132+
133+typedef int (*pn533_send_async_complete_t) (struct pn533 *dev, void *arg,
134+ struct sk_buff *resp);
138135
139136 /* structs for pn533 commands */
140137
@@ -282,11 +279,6 @@ const struct pn533_poll_modulations poll_mod[] = { · 141 unmodified lines
282279
283280 /* PN533_CMD_IN_ATR */
284281
285−struct pn533_cmd_activate_param {
286− u8 tg;
287− u8 next;
288−} __packed;
289−
290282 struct pn533_cmd_activate_response {
291283 u8 status;
292284 u8 nfcid3t[10];
@@ -299,14 +291,6 @@ struct pn533_cmd_activate_response { · 6 unmodified lines
299291 u8 gt[];
300292 } __packed;
301293
302−/* PN533_CMD_IN_JUMP_FOR_DEP */
303−struct pn533_cmd_jump_dep {
304− u8 active;
305− u8 baud;
306− u8 next;
307− u8 data[];
308−} __packed;
309−
310294 struct pn533_cmd_jump_dep_response {
311295 u8 status;
312296 u8 tg;
@@ -329,32 +313,13 @@ struct pn533_cmd_jump_dep_response { · 16 unmodified lines
329313 #define PN533_INIT_TARGET_RESP_ACTIVE 0x1
330314 #define PN533_INIT_TARGET_RESP_DEP 0x4
331315
332−struct pn533_cmd_init_target {
333− u8 mode;
334− u8 mifare[6];
335− u8 felica[18];
336− u8 nfcid3[10];
337− u8 gb_len;
338− u8 gb[];
339−} __packed;
340−
341−struct pn533_cmd_init_target_response {
342− u8 mode;
343− u8 cmd[];
344−} __packed;
345−
346316 struct pn533 {
347317 struct usb_device *udev;
348318 struct usb_interface *interface;
349319 struct nfc_dev *nfc_dev;
350320
351321 struct urb *out_urb;
352− int out_maxlen;
353− struct pn533_frame *out_frame;
354−
355322 struct urb *in_urb;
356− int in_maxlen;
357− struct pn533_frame *in_frame;
358323
359324 struct sk_buff_head resp_q;
360325
@@ -365,12 +330,12 @@ struct pn533 { · 4 unmodified lines
365330 struct work_struct mi_work;
366331 struct work_struct tg_work;
367332 struct timer_list listen_timer;
368− struct pn533_frame *wq_in_frame;
369333 int wq_in_error;
370334 int cancel_listen;
371335
372336 pn533_cmd_complete_t cmd_complete;
373337 void *cmd_complete_arg;
338+ void *cmd_complete_mi_arg;
374339 struct mutex cmd_lock;
375340 u8 cmd;
376341
@@ -391,16 +356,17 @@ struct pn533 { · 14 unmodified lines
391356
392357 struct list_head cmd_queue;
393358 u8 cmd_pending;
359+
360+ struct pn533_frame_ops *ops;
394361 };
395362
396363 struct pn533_cmd {
397364 struct list_head queue;
398− struct pn533_frame *out_frame;
399− struct pn533_frame *in_frame;
400− int in_frame_len;
401− pn533_cmd_complete_t cmd_complete;
365+ u8 cmd_code;
366+ struct sk_buff *req;
367+ struct sk_buff *resp;
368+ int resp_len;
402369 void *arg;
403− gfp_t flags;
404370 };
405371
406372 struct pn533_frame {
@@ -411,6 +377,22 @@ struct pn533_frame { · 4 unmodified lines
411377 u8 data[];
412378 } __packed;
413379
380+struct pn533_frame_ops {
381+ void (*tx_frame_init)(void *frame, u8 cmd_code);
382+ void (*tx_frame_finish)(void *frame);
383+ void (*tx_update_payload_len)(void *frame, int len);
384+ int tx_header_len;
385+ int tx_tail_len;
386+
387+ bool (*rx_is_frame_valid)(void *frame);
388+ int (*rx_frame_size)(void *frame);
389+ int rx_header_len;
390+ int rx_tail_len;
391+
392+ int max_payload_len;
393+ u8 (*get_cmd_code)(void *frame);
394+};
395+
414396 /* The rule: value + checksum = 0 */
415397 static inline u8 pn533_checksum(u8 value)
416398 {
@@ -429,37 +411,21 @@ static u8 pn533_data_checksum(u8 *data, int datalen) · 12 unmodified lines
429411 return pn533_checksum(sum);
430412 }
431413
432−/**
433− * pn533_tx_frame_ack - create a ack frame
434− * @frame: The frame to be set as ack
435− *
436− * Ack is different type of standard frame. As a standard frame, it has
437− * preamble and start_frame. However the checksum of this frame must fail,
438− * i.e. datalen + datalen_checksum must NOT be zero. When the checksum test
439− * fails and datalen = 0 and datalen_checksum = 0xFF, the frame is a ack.
440− * After datalen_checksum field, the postamble is placed.
441− */
442−static void pn533_tx_frame_ack(struct pn533_frame *frame)
414+static void pn533_tx_frame_init(void *_frame, u8 cmd_code)
443415 {
444− frame->preamble = 0;
445− frame->start_frame = cpu_to_be16(PN533_SOF);
446− frame->datalen = 0;
447− frame->datalen_checksum = 0xFF;
448− /* data[0] is used as postamble */
449− frame->data[0] = 0;
450−}
416+ struct pn533_frame *frame = _frame;
451417
452−static void pn533_tx_frame_init(struct pn533_frame *frame, u8 cmd)
453−{
454418 frame->preamble = 0;
455419 frame->start_frame = cpu_to_be16(PN533_SOF);
456420 PN533_FRAME_IDENTIFIER(frame) = PN533_DIR_OUT;
457− PN533_FRAME_CMD(frame) = cmd;
421+ PN533_FRAME_CMD(frame) = cmd_code;
458422 frame->datalen = 2;
459423 }
460424
461−static void pn533_tx_frame_finish(struct pn533_frame *frame)
425+static void pn533_tx_frame_finish(void *_frame)
462426 {
427+ struct pn533_frame *frame = _frame;
428+
463429 frame->datalen_checksum = pn533_checksum(frame->datalen);
464430
465431 PN533_FRAME_CHECKSUM(frame) =
@@ -468,9 +434,17 @@ static void pn533_tx_frame_finish(struct pn533_frame *frame) · 2 unmodified lines
468434 PN533_FRAME_POSTAMBLE(frame) = 0;
469435 }
470436
471−static bool pn533_rx_frame_is_valid(struct pn533_frame *frame)
437+static void pn533_tx_update_payload_len(void *_frame, int len)
438+{
439+ struct pn533_frame *frame = _frame;
440+
441+ frame->datalen += len;
442+}
443+
444+static bool pn533_rx_frame_is_valid(void *_frame)
472445 {
473446 u8 checksum;
447+ struct pn533_frame *frame = _frame;
474448
475449 if (frame->start_frame != cpu_to_be16(PN533_SOF))
476450 return false;
@@ -497,28 +471,48 @@ static bool pn533_rx_frame_is_ack(struct pn533_frame *frame) · 20 unmodified lines
497471 return true;
498472 }
499473
500−static bool pn533_rx_frame_is_cmd_response(struct pn533_frame *frame, u8 cmd)
474+static inline int pn533_rx_frame_size(void *frame)
475+{
476+ struct pn533_frame *f = frame;
477+
478+ return sizeof(struct pn533_frame) + f->datalen + PN533_FRAME_TAIL_LEN;
479+}
480+
481+static u8 pn533_get_cmd_code(void *frame)
482+{
483+ struct pn533_frame *f = frame;
484+
485+ return PN533_FRAME_CMD(f);
486+}
487+
488+struct pn533_frame_ops pn533_std_frame_ops = {
489+ .tx_frame_init = pn533_tx_frame_init,
490+ .tx_frame_finish = pn533_tx_frame_finish,
491+ .tx_update_payload_len = pn533_tx_update_payload_len,
492+ .tx_header_len = PN533_FRAME_HEADER_LEN,
493+ .tx_tail_len = PN533_FRAME_TAIL_LEN,
494+
495+ .rx_is_frame_valid = pn533_rx_frame_is_valid,
496+ .rx_frame_size = pn533_rx_frame_size,
497+ .rx_header_len = PN533_FRAME_HEADER_LEN,
498+ .rx_tail_len = PN533_FRAME_TAIL_LEN,
499+
500+ .max_payload_len = PN533_FRAME_MAX_PAYLOAD_LEN,
501+ .get_cmd_code = pn533_get_cmd_code,
502+};
503+
504+static bool pn533_rx_frame_is_cmd_response(struct pn533 *dev, void *frame)
501505 {
502− return (PN533_FRAME_CMD(frame) == PN533_CMD_RESPONSE(cmd));
506+ return (dev->ops->get_cmd_code(frame) == PN533_CMD_RESPONSE(dev->cmd));
503507 }
504508
505509
506510 static void pn533_wq_cmd_complete(struct work_struct *work)
507511 {
508512 struct pn533 *dev = container_of(work, struct pn533, cmd_complete_work);
509− struct pn533_frame *in_frame;
510513 int rc;
511514
512− in_frame = dev->wq_in_frame;
513−
514− if (dev->wq_in_error)
515− rc = dev->cmd_complete(dev, dev->cmd_complete_arg, NULL,
516− dev->wq_in_error);
517− else
518− rc = dev->cmd_complete(dev, dev->cmd_complete_arg,
519− PN533_FRAME_CMD_PARAMS_PTR(in_frame),
520− PN533_FRAME_CMD_PARAMS_LEN(in_frame));
521−
515+ rc = dev->cmd_complete(dev, dev->cmd_complete_arg, dev->wq_in_error);
522516 if (rc != -EINPROGRESS)
523517 queue_work(dev->wq, &dev->cmd_work);
524518 }
@@ -526,46 +520,47 @@ static void pn533_wq_cmd_complete(struct work_struct *work) · 1 unmodified line
526520 static void pn533_recv_response(struct urb *urb)
527521 {
528522 struct pn533 *dev = urb->context;
529− struct pn533_frame *in_frame;
530−
531− dev->wq_in_frame = NULL;
523+ u8 *in_frame;
532524
533525 switch (urb->status) {
534526 case 0:
535− /* success */
536− break;
527+ break; /* success */
537528 case -ECONNRESET:
538529 case -ENOENT:
539− case -ESHUTDOWN:
540− nfc_dev_dbg(&dev->interface->dev, "Urb shutting down with"
541− " status: %d", urb->status);
530+ nfc_dev_dbg(&dev->interface->dev,
531+ "The urb has been canceled (status %d)",
532+ urb->status);
542533 dev->wq_in_error = urb->status;
543534 goto sched_wq;
535+ break;
536+ case -ESHUTDOWN:
544537 default:
545− nfc_dev_err(&dev->interface->dev, "Nonzero urb status received:"
546− " %d", urb->status);
538+ nfc_dev_err(&dev->interface->dev,
539+ "Urb failure (status %d)", urb->status);
547540 dev->wq_in_error = urb->status;
548541 goto sched_wq;
549542 }
550543
551544 in_frame = dev->in_urb->transfer_buffer;
552545
553− if (!pn533_rx_frame_is_valid(in_frame)) {
546+ nfc_dev_dbg(&dev->interface->dev, "Received a frame.");
547+ print_hex_dump(KERN_DEBUG, "PN533 RX: ", DUMP_PREFIX_NONE, 16, 1,
548+ in_frame, dev->ops->rx_frame_size(in_frame), false);
549+
550+ if (!dev->ops->rx_is_frame_valid(in_frame)) {
554551 nfc_dev_err(&dev->interface->dev, "Received an invalid frame");
555552 dev->wq_in_error = -EIO;
556553 goto sched_wq;
557554 }
558555
559− if (!pn533_rx_frame_is_cmd_response(in_frame, dev->cmd)) {
560− nfc_dev_err(&dev->interface->dev, "The received frame is not "
561− "response to the last command");
556+ if (!pn533_rx_frame_is_cmd_response(dev, in_frame)) {
557+ nfc_dev_err(&dev->interface->dev,
558+ "It it not the response to the last command");
562559 dev->wq_in_error = -EIO;
563560 goto sched_wq;
564561 }
565562
566− nfc_dev_dbg(&dev->interface->dev, "Received a valid frame");
567563 dev->wq_in_error = 0;
568− dev->wq_in_frame = in_frame;
569564
570565 sched_wq:
571566 queue_work(dev->wq, &dev->cmd_complete_work);
@@ -586,18 +581,19 @@ static void pn533_recv_ack(struct urb *urb) · 14 unmodified lines
586581
587582 switch (urb->status) {
588583 case 0:
589− /* success */
590− break;
584+ break; /* success */
591585 case -ECONNRESET:
592586 case -ENOENT:
593− case -ESHUTDOWN:
594− nfc_dev_dbg(&dev->interface->dev, "Urb shutting down with"
595− " status: %d", urb->status);
587+ nfc_dev_dbg(&dev->interface->dev,
588+ "The urb has been stopped (status %d)",
589+ urb->status);
596590 dev->wq_in_error = urb->status;
597591 goto sched_wq;
592+ break;
593+ case -ESHUTDOWN:
598594 default:
599− nfc_dev_err(&dev->interface->dev, "Nonzero urb status received:"
600− " %d", urb->status);
595+ nfc_dev_err(&dev->interface->dev,
596+ "Urb failure (status %d)", urb->status);
601597 dev->wq_in_error = urb->status;
602598 goto sched_wq;
603599 }
@@ -610,12 +606,10 @@ static void pn533_recv_ack(struct urb *urb) · 6 unmodified lines
610606 goto sched_wq;
611607 }
612608
613− nfc_dev_dbg(&dev->interface->dev, "Received a valid ack");
614−
615609 rc = pn533_submit_urb_for_response(dev, GFP_ATOMIC);
616610 if (rc) {
617− nfc_dev_err(&dev->interface->dev, "usb_submit_urb failed with"
618− " result %d", rc);
611+ nfc_dev_err(&dev->interface->dev,
612+ "usb_submit_urb failed with result %d", rc);
619613 dev->wq_in_error = rc;
620614 goto sched_wq;
621615 }
@@ -623,7 +617,6 @@ static void pn533_recv_ack(struct urb *urb) · 1 unmodified line
623617 return;
624618
625619 sched_wq:
626− dev->wq_in_frame = NULL;
627620 queue_work(dev->wq, &dev->cmd_complete_work);
628621 }
629622
@@ -636,47 +629,46 @@ static int pn533_submit_urb_for_ack(struct pn533 *dev, gfp_t flags) · 6 unmodified lines
636629
637630 static int pn533_send_ack(struct pn533 *dev, gfp_t flags)
638631 {
632+ u8 ack[PN533_FRAME_ACK_SIZE] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00};
633+ /* spec 7.1.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */
639634 int rc;
640635
641636 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
642637
643− pn533_tx_frame_ack(dev->out_frame);
644−
645− dev->out_urb->transfer_buffer = dev->out_frame;
646− dev->out_urb->transfer_buffer_length = PN533_FRAME_ACK_SIZE;
638+ dev->out_urb->transfer_buffer = ack;
639+ dev->out_urb->transfer_buffer_length = sizeof(ack);
647640 rc = usb_submit_urb(dev->out_urb, flags);
648641
649642 return rc;
650643 }
651644
652−static int __pn533_send_cmd_frame_async(struct pn533 *dev,
653− struct pn533_frame *out_frame,
654− struct pn533_frame *in_frame,
655− int in_frame_len,
645+static int __pn533_send_frame_async(struct pn533 *dev,
646+ struct sk_buff *out,
647+ struct sk_buff *in,
648+ int in_len,
656649 pn533_cmd_complete_t cmd_complete,
657− void *arg, gfp_t flags)
650+ void *arg)
658651 {
659652 int rc;
660653
661− nfc_dev_dbg(&dev->interface->dev, "Sending command 0x%x",
662− PN533_FRAME_CMD(out_frame));
663−
664− dev->cmd = PN533_FRAME_CMD(out_frame);
654+ dev->cmd = dev->ops->get_cmd_code(out->data);
665655 dev->cmd_complete = cmd_complete;
666656 dev->cmd_complete_arg = arg;
667657
668− dev->out_urb->transfer_buffer = out_frame;
669− dev->out_urb->transfer_buffer_length =
670− PN533_FRAME_SIZE(out_frame);
658+ dev->out_urb->transfer_buffer = out->data;
659+ dev->out_urb->transfer_buffer_length = out->len;
671660
672− dev->in_urb->transfer_buffer = in_frame;
673− dev->in_urb->transfer_buffer_length = in_frame_len;
661+ dev->in_urb->transfer_buffer = in->data;
662+ dev->in_urb->transfer_buffer_length = in_len;
674663
675− rc = usb_submit_urb(dev->out_urb, flags);
664+ print_hex_dump(KERN_DEBUG, "PN533 TX: ", DUMP_PREFIX_NONE, 16, 1,
665+ out->data, out->len, false);
666+
667+ rc = usb_submit_urb(dev->out_urb, GFP_KERNEL);
676668 if (rc)
677669 return rc;
678670
679− rc = pn533_submit_urb_for_ack(dev, flags);
671+ rc = pn533_submit_urb_for_ack(dev, GFP_KERNEL);
680672 if (rc)
681673 goto error;
682674
@@ -687,146 +679,325 @@ error: · 4 unmodified lines
687679 return rc;
688680 }
689681
690−static void pn533_wq_cmd(struct work_struct *work)
682+static void pn533_build_cmd_frame(struct pn533 *dev, u8 cmd_code,
683+ struct sk_buff *skb)
691684 {
692− struct pn533 *dev = container_of(work, struct pn533, cmd_work);
693− struct pn533_cmd *cmd;
685+ /* payload is already there, just update datalen */
686+ int payload_len = skb->len;
687+ struct pn533_frame_ops *ops = dev->ops;
694688
695− mutex_lock(&dev->cmd_lock);
696689
697− if (list_empty(&dev->cmd_queue)) {
698− dev->cmd_pending = 0;
699− mutex_unlock(&dev->cmd_lock);
700− return;
701− }
690+ skb_push(skb, ops->tx_header_len);
691+ skb_put(skb, ops->tx_tail_len);
702692
703− cmd = list_first_entry(&dev->cmd_queue, struct pn533_cmd, queue);
693+ ops->tx_frame_init(skb->data, cmd_code);
694+ ops->tx_update_payload_len(skb->data, payload_len);
695+ ops->tx_frame_finish(skb->data);
696+}
704697
705− list_del(&cmd->queue);
698+struct pn533_send_async_complete_arg {
699+ pn533_send_async_complete_t complete_cb;
700+ void *complete_cb_context;
701+ struct sk_buff *resp;
702+ struct sk_buff *req;
703+};
706704
707− mutex_unlock(&dev->cmd_lock);
705+static int pn533_send_async_complete(struct pn533 *dev, void *_arg, int status)
706+{
707+ struct pn533_send_async_complete_arg *arg = _arg;
708708
709− __pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame,
710− cmd->in_frame_len, cmd->cmd_complete,
711− cmd->arg, cmd->flags);
709+ struct sk_buff *req = arg->req;
710+ struct sk_buff *resp = arg->resp;
712711
713− kfree(cmd);
712+ int rc;
713+
714+ dev_kfree_skb(req);
715+
716+ if (status < 0) {
717+ arg->complete_cb(dev, arg->complete_cb_context,
718+ ERR_PTR(status));
719+ dev_kfree_skb(resp);
720+ kfree(arg);
721+ return status;
722+ }
723+
724+ skb_put(resp, dev->ops->rx_frame_size(resp->data));
725+ skb_pull(resp, dev->ops->rx_header_len);
726+ skb_trim(resp, resp->len - dev->ops->rx_tail_len);
727+
728+ rc = arg->complete_cb(dev, arg->complete_cb_context, resp);
729+
730+ kfree(arg);
731+ return rc;
714732 }
715733
716−static int pn533_send_cmd_frame_async(struct pn533 *dev,
717− struct pn533_frame *out_frame,
718− struct pn533_frame *in_frame,
719− int in_frame_len,
720− pn533_cmd_complete_t cmd_complete,
721− void *arg, gfp_t flags)
734+static int __pn533_send_async(struct pn533 *dev, u8 cmd_code,
735+ struct sk_buff *req, struct sk_buff *resp,
736+ int resp_len,
737+ pn533_send_async_complete_t complete_cb,
738+ void *complete_cb_context)
722739 {
723740 struct pn533_cmd *cmd;
741+ struct pn533_send_async_complete_arg *arg;
724742 int rc = 0;
725743
726− nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
744+ nfc_dev_dbg(&dev->interface->dev, "Sending command 0x%x", cmd_code);
745+
746+ arg = kzalloc(sizeof(*arg), GFP_KERNEL);
747+ if (!arg)
748+ return -ENOMEM;
749+
750+ arg->complete_cb = complete_cb;
751+ arg->complete_cb_context = complete_cb_context;
752+ arg->resp = resp;
753+ arg->req = req;
754+
755+ pn533_build_cmd_frame(dev, cmd_code, req);
727756
728757 mutex_lock(&dev->cmd_lock);
729758
730759 if (!dev->cmd_pending) {
731− rc = __pn533_send_cmd_frame_async(dev, out_frame, in_frame,
732− in_frame_len, cmd_complete,
733− arg, flags);
734− if (!rc)
735− dev->cmd_pending = 1;
760+ rc = __pn533_send_frame_async(dev, req, resp, resp_len,
761+ pn533_send_async_complete, arg);
762+ if (rc)
763+ goto error;
736764
765+ dev->cmd_pending = 1;
737766 goto unlock;
738767 }
739768
740− nfc_dev_dbg(&dev->interface->dev, "%s Queueing command", __func__);
769+ nfc_dev_dbg(&dev->interface->dev, "%s Queueing command 0x%x", __func__,
770+ cmd_code);
741771
742− cmd = kzalloc(sizeof(struct pn533_cmd), flags);
772+ cmd = kzalloc(sizeof(struct pn533_cmd), GFP_KERNEL);
743773 if (!cmd) {
744774 rc = -ENOMEM;
745− goto unlock;
775+ goto error;
746776 }
747777
748778 INIT_LIST_HEAD(&cmd->queue);
749− cmd->out_frame = out_frame;
750− cmd->in_frame = in_frame;
751− cmd->in_frame_len = in_frame_len;
752− cmd->cmd_complete = cmd_complete;
779+ cmd->cmd_code = cmd_code;
780+ cmd->req = req;
781+ cmd->resp = resp;
782+ cmd->resp_len = resp_len;
753783 cmd->arg = arg;
754− cmd->flags = flags;
755784
756785 list_add_tail(&cmd->queue, &dev->cmd_queue);
757786
787+ goto unlock;
788+
789+error:
790+ kfree(arg);
758791 unlock:
759792 mutex_unlock(&dev->cmd_lock);
793+ return rc;
794+}
795+
796+static int pn533_send_data_async(struct pn533 *dev, u8 cmd_code,
797+ struct sk_buff *req,
798+ pn533_send_async_complete_t complete_cb,
799+ void *complete_cb_context)
800+{
801+ struct sk_buff *resp;
802+ int rc;
803+ int resp_len = dev->ops->rx_header_len +
804+ dev->ops->max_payload_len +
805+ dev->ops->rx_tail_len;
806+
807+ resp = nfc_alloc_recv_skb(resp_len, GFP_KERNEL);
808+ if (!resp)
809+ return -ENOMEM;
810+
811+ rc = __pn533_send_async(dev, cmd_code, req, resp, resp_len, complete_cb,
812+ complete_cb_context);
813+ if (rc)
814+ dev_kfree_skb(resp);
760815
761816 return rc;
762817 }
763818
764−struct pn533_sync_cmd_response {
819+static int pn533_send_cmd_async(struct pn533 *dev, u8 cmd_code,
820+ struct sk_buff *req,
821+ pn533_send_async_complete_t complete_cb,
822+ void *complete_cb_context)
823+{
824+ struct sk_buff *resp;
765825 int rc;
766− struct completion done;
767−};
826+ int resp_len = dev->ops->rx_header_len +
827+ dev->ops->max_payload_len +
828+ dev->ops->rx_tail_len;
829+
830+ resp = alloc_skb(resp_len, GFP_KERNEL);
831+ if (!resp)
832+ return -ENOMEM;
833+
834+ rc = __pn533_send_async(dev, cmd_code, req, resp, resp_len, complete_cb,
835+ complete_cb_context);
836+ if (rc)
837+ dev_kfree_skb(resp);
768838
769−static int pn533_sync_cmd_complete(struct pn533 *dev, void *_arg,
770− u8 *params, int params_len)
839+ return rc;
840+}
841+
842+/*
843+ * pn533_send_cmd_direct_async
844+ *
845+ * The function sends a piority cmd directly to the chip omiting the cmd
846+ * queue. It's intended to be used by chaining mechanism of received responses
847+ * where the host has to request every single chunk of data before scheduling
848+ * next cmd from the queue.
849+ */
850+static int pn533_send_cmd_direct_async(struct pn533 *dev, u8 cmd_code,
851+ struct sk_buff *req,
852+ pn533_send_async_complete_t complete_cb,
853+ void *complete_cb_context)
771854 {
772− struct pn533_sync_cmd_response *arg = _arg;
855+ struct pn533_send_async_complete_arg *arg;
856+ struct sk_buff *resp;
857+ int rc;
858+ int resp_len = dev->ops->rx_header_len +
859+ dev->ops->max_payload_len +
860+ dev->ops->rx_tail_len;
773861
774− nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
862+ resp = alloc_skb(resp_len, GFP_KERNEL);
863+ if (!resp)
864+ return -ENOMEM;
865+
866+ arg = kzalloc(sizeof(*arg), GFP_KERNEL);
867+ if (!arg) {
868+ dev_kfree_skb(resp);
869+ return -ENOMEM;
870+ }
775871
776− arg->rc = 0;
872+ arg->complete_cb = complete_cb;
873+ arg->complete_cb_context = complete_cb_context;
874+ arg->resp = resp;
875+ arg->req = req;
777876
778− if (params_len < 0) /* error */
779− arg->rc = params_len;
877+ pn533_build_cmd_frame(dev, cmd_code, req);
780878
879+ rc = __pn533_send_frame_async(dev, req, resp, resp_len,
880+ pn533_send_async_complete, arg);
881+ if (rc < 0) {
882+ dev_kfree_skb(resp);
883+ kfree(arg);
884+ }
885+
886+ return rc;
887+}
888+
889+static void pn533_wq_cmd(struct work_struct *work)
890+{
891+ struct pn533 *dev = container_of(work, struct pn533, cmd_work);
892+ struct pn533_cmd *cmd;
893+
894+ mutex_lock(&dev->cmd_lock);
895+
896+ if (list_empty(&dev->cmd_queue)) {
897+ dev->cmd_pending = 0;
898+ mutex_unlock(&dev->cmd_lock);
899+ return;
900+ }
901+
902+ cmd = list_first_entry(&dev->cmd_queue, struct pn533_cmd, queue);
903+
904+ list_del(&cmd->queue);
905+
906+ mutex_unlock(&dev->cmd_lock);
907+
908+ __pn533_send_frame_async(dev, cmd->req, cmd->resp, cmd->resp_len,
909+ pn533_send_async_complete, cmd->arg);
910+
911+ kfree(cmd);
912+}
913+
914+struct pn533_sync_cmd_response {
915+ struct sk_buff *resp;
916+ struct completion done;
917+};
918+
919+static int pn533_send_sync_complete(struct pn533 *dev, void *_arg,
920+ struct sk_buff *resp)
921+{
922+ struct pn533_sync_cmd_response *arg = _arg;
923+
924+ arg->resp = resp;
781925 complete(&arg->done);
782926
783927 return 0;
784928 }
785929
786−static int pn533_send_cmd_frame_sync(struct pn533 *dev,
787− struct pn533_frame *out_frame,
788− struct pn533_frame *in_frame,
789− int in_frame_len)
930+/* pn533_send_cmd_sync
931+ *
932+ * Please note the req parameter is freed inside the function to
933+ * limit a number of return value interpretations by the caller.
934+ *
935+ * 1. negative in case of error during TX path -> req should be freed
936+ *
937+ * 2. negative in case of error during RX path -> req should not be freed
938+ * as it's been already freed at the begining of RX path by
939+ * async_complete_cb.
940+ *
941+ * 3. valid pointer in case of succesfult RX path
942+ *
943+ * A caller has to check a return value with IS_ERR macro. If the test pass,
944+ * the returned pointer is valid.
945+ *
946+ * */
947+static struct sk_buff *pn533_send_cmd_sync(struct pn533 *dev, u8 cmd_code,
948+ struct sk_buff *req)
790949 {
791950 int rc;
792951 struct pn533_sync_cmd_response arg;
793952
794− nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
795−
796953 init_completion(&arg.done);
797954
798− rc = pn533_send_cmd_frame_async(dev, out_frame, in_frame, in_frame_len,
799− pn533_sync_cmd_complete, &arg, GFP_KERNEL);
800− if (rc)
801− return rc;
955+ rc = pn533_send_cmd_async(dev, cmd_code, req,
956+ pn533_send_sync_complete, &arg);
957+ if (rc) {
958+ dev_kfree_skb(req);
959+ return ERR_PTR(rc);
960+ }
802961
803962 wait_for_completion(&arg.done);
804963
805− return arg.rc;
964+ return arg.resp;
806965 }
807966
808967 static void pn533_send_complete(struct urb *urb)
809968 {
810969 struct pn533 *dev = urb->context;
811970
812− nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
813−
814971 switch (urb->status) {
815972 case 0:
816− /* success */
817− break;
973+ break; /* success */
818974 case -ECONNRESET:
819975 case -ENOENT:
820− case -ESHUTDOWN:
821− nfc_dev_dbg(&dev->interface->dev, "Urb shutting down with"
822− " status: %d", urb->status);
976+ nfc_dev_dbg(&dev->interface->dev,
977+ "The urb has been stopped (status %d)",
978+ urb->status);
823979 break;
980+ case -ESHUTDOWN:
824981 default:
825− nfc_dev_dbg(&dev->interface->dev, "Nonzero urb status received:"
826− " %d", urb->status);
982+ nfc_dev_err(&dev->interface->dev,
983+ "Urb failure (status %d)", urb->status);
827984 }
828985 }
829986
987+static struct sk_buff *pn533_alloc_skb(struct pn533 *dev, unsigned int size)
988+{
989+ struct sk_buff *skb;
990+
991+ skb = alloc_skb(dev->ops->tx_header_len +
992+ size +
993+ dev->ops->tx_tail_len, GFP_KERNEL);
994+
995+ if (skb)
996+ skb_reserve(skb, dev->ops->tx_header_len);
997+
998+ return skb;
999+}
1000+
8301001 struct pn533_target_type_a {
8311002 __be16 sens_res;
8321003 u8 sel_res;
@@ -867,9 +1038,9 @@ static bool pn533_target_type_a_is_valid(struct pn533_target_type_a *type_a, · 34 unmodified lines
8671038 platconf = PN533_TYPE_A_SENS_RES_PLATCONF(type_a->sens_res);
8681039
8691040 if ((ssd == PN533_TYPE_A_SENS_RES_SSD_JEWEL &&
870− platconf != PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL) ||
871− (ssd != PN533_TYPE_A_SENS_RES_SSD_JEWEL &&
872− platconf == PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL))
1041+ platconf != PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL) ||
1042+ (ssd != PN533_TYPE_A_SENS_RES_SSD_JEWEL &&
1043+ platconf == PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL))
8731044 return false;
8741045
8751046 /* Requirements 4.8.2.1, 4.8.2.3, 4.8.2.5 and 4.8.2.7 from NFC Forum */
@@ -884,7 +1055,7 @@ static int pn533_target_found_type_a(struct nfc_target *nfc_tgt, u8 *tgt_data, · 8 unmodified lines
8841055 {
8851056 struct pn533_target_type_a *tgt_type_a;
8861057
887− tgt_type_a = (struct pn533_target_type_a *) tgt_data;
1058+ tgt_type_a = (struct pn533_target_type_a *)tgt_data;
8881059
8891060 if (!pn533_target_type_a_is_valid(tgt_type_a, tgt_data_len))
8901061 return -EPROTO;
@@ -942,14 +1113,13 @@ static int pn533_target_found_felica(struct nfc_target *nfc_tgt, u8 *tgt_data, · 51 unmodified lines
9421113 {
9431114 struct pn533_target_felica *tgt_felica;
9441115
945− tgt_felica = (struct pn533_target_felica *) tgt_data;
1116+ tgt_felica = (struct pn533_target_felica *)tgt_data;
9461117
9471118 if (!pn533_target_felica_is_valid(tgt_felica, tgt_data_len))
9481119 return -EPROTO;
9491120
950− if (tgt_felica->nfcid2[0] == PN533_FELICA_SENSF_NFCID2_DEP_B1 &&
951− tgt_felica->nfcid2[1] ==
952− PN533_FELICA_SENSF_NFCID2_DEP_B2)
1121+ if ((tgt_felica->nfcid2[0] == PN533_FELICA_SENSF_NFCID2_DEP_B1) &&
1122+ (tgt_felica->nfcid2[1] == PN533_FELICA_SENSF_NFCID2_DEP_B2))
9531123 nfc_tgt->supported_protocols = NFC_PROTO_NFC_DEP_MASK;
9541124 else
9551125 nfc_tgt->supported_protocols = NFC_PROTO_FELICA_MASK;
@@ -979,9 +1149,9 @@ static bool pn533_target_jewel_is_valid(struct pn533_target_jewel *jewel, · 23 unmodified lines
9791149 platconf = PN533_TYPE_A_SENS_RES_PLATCONF(jewel->sens_res);
9801150
9811151 if ((ssd == PN533_TYPE_A_SENS_RES_SSD_JEWEL &&
982− platconf != PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL) ||
983− (ssd != PN533_TYPE_A_SENS_RES_SSD_JEWEL &&
984− platconf == PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL))
1152+ platconf != PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL) ||
1153+ (ssd != PN533_TYPE_A_SENS_RES_SSD_JEWEL &&
1154+ platconf == PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL))
9851155 return false;
9861156
9871157 return true;
@@ -992,7 +1162,7 @@ static int pn533_target_found_jewel(struct nfc_target *nfc_tgt, u8 *tgt_data, · 4 unmodified lines
9921162 {
9931163 struct pn533_target_jewel *tgt_jewel;
9941164
995− tgt_jewel = (struct pn533_target_jewel *) tgt_data;
1165+ tgt_jewel = (struct pn533_target_jewel *)tgt_data;
9961166
9971167 if (!pn533_target_jewel_is_valid(tgt_jewel, tgt_data_len))
9981168 return -EPROTO;
@@ -1051,7 +1221,7 @@ static int pn533_target_found_type_b(struct nfc_target *nfc_tgt, u8 *tgt_data, · 52 unmodified lines
10511221 {
10521222 struct pn533_target_type_b *tgt_type_b;
10531223
1054− tgt_type_b = (struct pn533_target_type_b *) tgt_data;
1224+ tgt_type_b = (struct pn533_target_type_b *)tgt_data;
10551225
10561226 if (!pn533_target_type_b_is_valid(tgt_type_b, tgt_data_len))
10571227 return -EPROTO;
@@ -1061,50 +1231,37 @@ static int pn533_target_found_type_b(struct nfc_target *nfc_tgt, u8 *tgt_data, · 3 unmodified lines
10611231 return 0;
10621232 }
10631233
1064−struct pn533_poll_response {
1065− u8 nbtg;
1066− u8 tg;
1067− u8 target_data[];
1068−} __packed;
1069−
1070−static int pn533_target_found(struct pn533 *dev,
1071− struct pn533_poll_response *resp, int resp_len)
1234+static int pn533_target_found(struct pn533 *dev, u8 tg, u8 *tgdata,
1235+ int tgdata_len)
10721236 {
1073− int target_data_len;
10741237 struct nfc_target nfc_tgt;
10751238 int rc;
10761239
10771240 nfc_dev_dbg(&dev->interface->dev, "%s - modulation=%d", __func__,
1078− dev->poll_mod_curr);
1241+ dev->poll_mod_curr);
10791242
1080− if (resp->tg != 1)
1243+ if (tg != 1)
10811244 return -EPROTO;
10821245
10831246 memset(&nfc_tgt, 0, sizeof(struct nfc_target));
10841247
1085− target_data_len = resp_len - sizeof(struct pn533_poll_response);
1086−
10871248 switch (dev->poll_mod_curr) {
10881249 case PN533_POLL_MOD_106KBPS_A:
1089− rc = pn533_target_found_type_a(&nfc_tgt, resp->target_data,
1090− target_data_len);
1250+ rc = pn533_target_found_type_a(&nfc_tgt, tgdata, tgdata_len);
10911251 break;
10921252 case PN533_POLL_MOD_212KBPS_FELICA:
10931253 case PN533_POLL_MOD_424KBPS_FELICA:
1094− rc = pn533_target_found_felica(&nfc_tgt, resp->target_data,
1095− target_data_len);
1254+ rc = pn533_target_found_felica(&nfc_tgt, tgdata, tgdata_len);
10961255 break;
10971256 case PN533_POLL_MOD_106KBPS_JEWEL:
1098− rc = pn533_target_found_jewel(&nfc_tgt, resp->target_data,
1099− target_data_len);
1257+ rc = pn533_target_found_jewel(&nfc_tgt, tgdata, tgdata_len);
11001258 break;
11011259 case PN533_POLL_MOD_847KBPS_B:
1102− rc = pn533_target_found_type_b(&nfc_tgt, resp->target_data,
1103− target_data_len);
1260+ rc = pn533_target_found_type_b(&nfc_tgt, tgdata, tgdata_len);
11041261 break;
11051262 default:
1106− nfc_dev_err(&dev->interface->dev, "Unknown current poll"
1107− " modulation");
1263+ nfc_dev_err(&dev->interface->dev,
1264+ "Unknown current poll modulation");
11081265 return -EPROTO;
11091266 }
11101267
@@ -1112,13 +1269,14 @@ static int pn533_target_found(struct pn533 *dev, · 1 unmodified line
11121269 return rc;
11131270
11141271 if (!(nfc_tgt.supported_protocols & dev->poll_protocols)) {
1115− nfc_dev_dbg(&dev->interface->dev, "The target found does not"
1116− " have the desired protocol");
1272+ nfc_dev_dbg(&dev->interface->dev,
1273+ "The Tg found doesn't have the desired protocol");
11171274 return -EAGAIN;
11181275 }
11191276
1120− nfc_dev_dbg(&dev->interface->dev, "Target found - supported protocols: "
1121− "0x%x", nfc_tgt.supported_protocols);
1277+ nfc_dev_dbg(&dev->interface->dev,
1278+ "Target found - supported protocols: 0x%x",
1279+ nfc_tgt.supported_protocols);
11221280
11231281 dev->tgt_available_prots = nfc_tgt.supported_protocols;
11241282
@@ -1140,7 +1298,7 @@ static void pn533_poll_reset_mod_list(struct pn533 *dev) · 15 unmodified lines
11401298 static void pn533_poll_add_mod(struct pn533 *dev, u8 mod_index)
11411299 {
11421300 dev->poll_mod_active[dev->poll_mod_count] =
1143− (struct pn533_poll_modulations *) &poll_mod[mod_index];
1301+ (struct pn533_poll_modulations *)&poll_mod[mod_index];
11441302 dev->poll_mod_count++;
11451303 }
11461304
@@ -1149,13 +1307,13 @@ static void pn533_poll_create_mod_list(struct pn533 *dev, · 2 unmodified lines
11491307 {
11501308 pn533_poll_reset_mod_list(dev);
11511309
1152− if (im_protocols & NFC_PROTO_MIFARE_MASK
1153− || im_protocols & NFC_PROTO_ISO14443_MASK
1154− || im_protocols & NFC_PROTO_NFC_DEP_MASK)
1310+ if ((im_protocols & NFC_PROTO_MIFARE_MASK) ||
1311+ (im_protocols & NFC_PROTO_ISO14443_MASK) ||
1312+ (im_protocols & NFC_PROTO_NFC_DEP_MASK))
11551313 pn533_poll_add_mod(dev, PN533_POLL_MOD_106KBPS_A);
11561314
1157− if (im_protocols & NFC_PROTO_FELICA_MASK
1158− || im_protocols & NFC_PROTO_NFC_DEP_MASK) {
1315+ if (im_protocols & NFC_PROTO_FELICA_MASK ||
1316+ im_protocols & NFC_PROTO_NFC_DEP_MASK) {
11591317 pn533_poll_add_mod(dev, PN533_POLL_MOD_212KBPS_FELICA);
11601318 pn533_poll_add_mod(dev, PN533_POLL_MOD_424KBPS_FELICA);
11611319 }
@@ -1170,16 +1328,20 @@ static void pn533_poll_create_mod_list(struct pn533 *dev, · 8 unmodified lines
11701328 pn533_poll_add_mod(dev, PN533_LISTEN_MOD);
11711329 }
11721330
1173−static int pn533_start_poll_complete(struct pn533 *dev, u8 *params, int params_len)
1331+static int pn533_start_poll_complete(struct pn533 *dev, struct sk_buff *resp)
11741332 {
1175− struct pn533_poll_response *resp;
1176− int rc;
1333+ u8 nbtg, tg, *tgdata;
1334+ int rc, tgdata_len;
11771335
11781336 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
11791337
1180− resp = (struct pn533_poll_response *) params;
1181− if (resp->nbtg) {
1182− rc = pn533_target_found(dev, resp, params_len);
1338+ nbtg = resp->data[0];
1339+ tg = resp->data[1];
1340+ tgdata = &resp->data[2];
1341+ tgdata_len = resp->len - 2; /* nbtg + tg */
1342+
1343+ if (nbtg) {
1344+ rc = pn533_target_found(dev, tg, tgdata, tgdata_len);
11831345
11841346 /* We must stop the poll after a valid target found */
11851347 if (rc == 0) {
@@ -1191,158 +1353,134 @@ static int pn533_start_poll_complete(struct pn533 *dev, u8 *params, int params_l · 5 unmodified lines
11911353 return -EAGAIN;
11921354 }
11931355
1194−static int pn533_init_target_frame(struct pn533_frame *frame,
1195− u8 *gb, size_t gb_len)
1356+static struct sk_buff *pn533_alloc_poll_tg_frame(struct pn533 *dev)
11961357 {
1197− struct pn533_cmd_init_target *cmd;
1198− size_t cmd_len;
1358+ struct sk_buff *skb;
1359+ u8 *felica, *nfcid3, *gb;
1360+
1361+ u8 *gbytes = dev->gb;
1362+ size_t gbytes_len = dev->gb_len;
1363+
11991364 u8 felica_params[18] = {0x1, 0xfe, /* DEP */
12001365 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* random */
12011366 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
12021367 0xff, 0xff}; /* System code */
1368+
12031369 u8 mifare_params[6] = {0x1, 0x1, /* SENS_RES */
12041370 0x0, 0x0, 0x0,
12051371 0x40}; /* SEL_RES for DEP */
12061372
1207− cmd_len = sizeof(struct pn533_cmd_init_target) + gb_len + 1;
1208− cmd = kzalloc(cmd_len, GFP_KERNEL);
1209− if (cmd == NULL)
1210− return -ENOMEM;
1373+ unsigned int skb_len = 36 + /* mode (1), mifare (6),
1374+ felica (18), nfcid3 (10), gb_len (1) */
1375+ gbytes_len +
1376+ 1; /* len Tk*/
12111377
1212− pn533_tx_frame_init(frame, PN533_CMD_TG_INIT_AS_TARGET);
1378+ skb = pn533_alloc_skb(dev, skb_len);
1379+ if (!skb)
1380+ return NULL;
12131381
12141382 /* DEP support only */
1215− cmd->mode |= PN533_INIT_TARGET_DEP;
1383+ *skb_put(skb, 1) |= PN533_INIT_TARGET_DEP;
1384+
1385+ /* MIFARE params */
1386+ memcpy(skb_put(skb, 6), mifare_params, 6);
12161387
12171388 /* Felica params */
1218− memcpy(cmd->felica, felica_params, 18);
1219− get_random_bytes(cmd->felica + 2, 6);
1389+ felica = skb_put(skb, 18);
1390+ memcpy(felica, felica_params, 18);
1391+ get_random_bytes(felica + 2, 6);
12201392
12211393 /* NFCID3 */
1222− memset(cmd->nfcid3, 0, 10);
1223− memcpy(cmd->nfcid3, cmd->felica, 8);
1224−
1225− /* MIFARE params */
1226− memcpy(cmd->mifare, mifare_params, 6);
1394+ nfcid3 = skb_put(skb, 10);
1395+ memset(nfcid3, 0, 10);
1396+ memcpy(nfcid3, felica, 8);
12271397
12281398 /* General bytes */
1229− cmd->gb_len = gb_len;
1230− memcpy(cmd->gb, gb, gb_len);
1231−
1232− /* Len Tk */
1233− cmd->gb[gb_len] = 0;
1234−
1235− memcpy(PN533_FRAME_CMD_PARAMS_PTR(frame), cmd, cmd_len);
1399+ *skb_put(skb, 1) = gbytes_len;
12361400
1237− frame->datalen += cmd_len;
1401+ gb = skb_put(skb, gbytes_len);
1402+ memcpy(gb, gbytes, gbytes_len);
12381403
1239− pn533_tx_frame_finish(frame);
1240−
1241− kfree(cmd);
1404+ /* Len Tk */
1405+ *skb_put(skb, 1) = 0;
12421406
1243− return 0;
1407+ return skb;
12441408 }
12451409
1246−#define PN533_CMD_DATAEXCH_HEAD_LEN (sizeof(struct pn533_frame) + 3)
1410+#define PN533_CMD_DATAEXCH_HEAD_LEN 1
12471411 #define PN533_CMD_DATAEXCH_DATA_MAXLEN 262
12481412 static int pn533_tm_get_data_complete(struct pn533 *dev, void *arg,
1249− u8 *params, int params_len)
1413+ struct sk_buff *resp)
12501414 {
1251− struct sk_buff *skb_resp = arg;
1252− struct pn533_frame *in_frame = (struct pn533_frame *) skb_resp->data;
1415+ u8 status;
12531416
12541417 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
12551418
1256− if (params_len < 0) {
1257− nfc_dev_err(&dev->interface->dev,
1258− "Error %d when starting as a target",
1259− params_len);
1419+ if (IS_ERR(resp))
1420+ return PTR_ERR(resp);
12601421
1261− return params_len;
1262− }
1422+ status = resp->data[0];
1423+ skb_pull(resp, sizeof(status));
12631424
1264− if (params_len > 0 && params[0] != 0) {
1425+ if (status != 0) {
12651426 nfc_tm_deactivated(dev->nfc_dev);
1266−
12671427 dev->tgt_mode = 0;
1268−
1269− kfree_skb(skb_resp);
1428+ dev_kfree_skb(resp);
12701429 return 0;
12711430 }
12721431
1273− skb_put(skb_resp, PN533_FRAME_SIZE(in_frame));
1274− skb_pull(skb_resp, PN533_CMD_DATAEXCH_HEAD_LEN);
1275− skb_trim(skb_resp, skb_resp->len - PN533_FRAME_TAIL_SIZE);
1276−
1277− return nfc_tm_data_received(dev->nfc_dev, skb_resp);
1432+ return nfc_tm_data_received(dev->nfc_dev, resp);
12781433 }
12791434
12801435 static void pn533_wq_tg_get_data(struct work_struct *work)
12811436 {
12821437 struct pn533 *dev = container_of(work, struct pn533, tg_work);
1283− struct pn533_frame *in_frame;
1284− struct sk_buff *skb_resp;
1285− size_t skb_resp_len;
12861438
1287− nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1439+ struct sk_buff *skb;
1440+ int rc;
12881441
1289− skb_resp_len = PN533_CMD_DATAEXCH_HEAD_LEN +
1290− PN533_CMD_DATAEXCH_DATA_MAXLEN +
1291− PN533_FRAME_TAIL_SIZE;
1442+ nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
12921443
1293− skb_resp = nfc_alloc_recv_skb(skb_resp_len, GFP_KERNEL);
1294− if (!skb_resp)
1444+ skb = pn533_alloc_skb(dev, 0);
1445+ if (!skb)
12951446 return;
12961447
1297− in_frame = (struct pn533_frame *)skb_resp->data;
1448+ rc = pn533_send_data_async(dev, PN533_CMD_TG_GET_DATA, skb,
1449+ pn533_tm_get_data_complete, NULL);
12981450
1299− pn533_tx_frame_init(dev->out_frame, PN533_CMD_TG_GET_DATA);
1300− pn533_tx_frame_finish(dev->out_frame);
1301−
1302− pn533_send_cmd_frame_async(dev, dev->out_frame, in_frame,
1303− skb_resp_len,
1304− pn533_tm_get_data_complete,
1305− skb_resp, GFP_KERNEL);
1451+ if (rc < 0)
1452+ dev_kfree_skb(skb);
13061453
13071454 return;
13081455 }
13091456
13101457 #define ATR_REQ_GB_OFFSET 17
1311−static int pn533_init_target_complete(struct pn533 *dev, u8 *params, int params_len)
1458+static int pn533_init_target_complete(struct pn533 *dev, struct sk_buff *resp)
13121459 {
1313− struct pn533_cmd_init_target_response *resp;
1314− u8 frame, comm_mode = NFC_COMM_PASSIVE, *gb;
1460+ u8 mode, *cmd, comm_mode = NFC_COMM_PASSIVE, *gb;
13151461 size_t gb_len;
13161462 int rc;
13171463
13181464 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
13191465
1320− if (params_len < 0) {
1321− nfc_dev_err(&dev->interface->dev,
1322− "Error %d when starting as a target",
1323− params_len);
1324−
1325− return params_len;
1326− }
1327−
1328− if (params_len < ATR_REQ_GB_OFFSET + 1)
1466+ if (resp->len < ATR_REQ_GB_OFFSET + 1)
13291467 return -EINVAL;
13301468
1331− resp = (struct pn533_cmd_init_target_response *) params;
1469+ mode = resp->data[0];
1470+ cmd = &resp->data[1];
13321471
1333− nfc_dev_dbg(&dev->interface->dev, "Target mode 0x%x param len %d\n",
1334− resp->mode, params_len);
1472+ nfc_dev_dbg(&dev->interface->dev, "Target mode 0x%x len %d\n",
1473+ mode, resp->len);
13351474

1210 more lines aren’t shown here.

drivers/nfc/pn544/Kconfig+23−0

This diff is large: its 24 lines aren’t shown here.

drivers/nfc/pn544/Makefile+3−2

This diff is large: its 10 lines aren’t shown here.

drivers/nfc/pn544/i2c.c+7−37

This diff is large: its 91 lines aren’t shown here.

drivers/nfc/pn544/pn544.c+42−23

This diff is large: its 141 lines aren’t shown here.

drivers/ssb/Kconfig+6−2

This diff is large: its 22 lines aren’t shown here.

drivers/ssb/Makefile+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/ssb/driver_chipcommon_sflash.c+140−0

This diff is large: its 141 lines aren’t shown here.

drivers/ssb/driver_mipscore.c+2−1

This diff is large: its 10 lines aren’t shown here.

drivers/ssb/ssb_private.h+11−0

This diff is large: its 18 lines aren’t shown here.

include/linux/bcma/bcma_driver_mips.h+2−2

This diff is large: its 24 lines aren’t shown here.

include/linux/bcma/bcma_driver_pci.h+2−0

This diff is large: its 9 lines aren’t shown here.

include/net/nfc/hci.h+20−2

This diff is large: its 54 lines aren’t shown here.

include/net/nfc/nci_core.h+1−0

This diff is large: its 8 lines aren’t shown here.

include/net/nfc/nfc.h+8−0

This diff is large: its 35 lines aren’t shown here.

include/uapi/linux/nfc.h+24−13

This diff is large: its 80 lines aren’t shown here.

net/bluetooth/hci_core.c+0−8

This diff is large: its 15 lines aren’t shown here.

net/bluetooth/hci_event.c+1−1

This diff is large: its 9 lines aren’t shown here.

net/bluetooth/hidp/core.c+1−1

This diff is large: its 9 lines aren’t shown here.

net/bluetooth/l2cap_core.c+11−0

This diff is large: its 18 lines aren’t shown here.

net/bluetooth/sco.c+1−1

This diff is large: its 9 lines aren’t shown here.

net/mac80211/cfg.c+11−1

This diff is large: its 19 lines aren’t shown here.

net/mac80211/ieee80211_i.h+2−4

This diff is large: its 13 lines aren’t shown here.

net/mac80211/mesh_hwmp.c+4−1

This diff is large: its 23 lines aren’t shown here.

net/mac80211/offchannel.c+7−12

This diff is large: its 54 lines aren’t shown here.

net/mac80211/scan.c+5−10

This diff is large: its 43 lines aren’t shown here.

net/mac80211/tx.c+6−3

This diff is large: its 17 lines aren’t shown here.

net/nfc/core.c+25−25

This diff is large: its 110 lines aren’t shown here.

net/nfc/hci/command.c+6−1

This diff is large: its 21 lines aren’t shown here.

net/nfc/hci/core.c+42−15

This diff is large: its 127 lines aren’t shown here.

net/nfc/hci/hcp.c+7−0

This diff is large: its 14 lines aren’t shown here.

net/nfc/llcp/commands.c+2−0

This diff is large: its 9 lines aren’t shown here.

net/nfc/llcp/llcp.c+31−13

This diff is large: its 100 lines aren’t shown here.

net/nfc/llcp/llcp.h+0−1

This diff is large: its 8 lines aren’t shown here.

net/nfc/llcp/sock.c+11−11

This diff is large: its 53 lines aren’t shown here.

net/nfc/nci/core.c+2−0

This diff is large: its 16 lines aren’t shown here.

net/nfc/netlink.c+1−0

This diff is large: its 8 lines aren’t shown here.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t