11// SPDX-License-Identifier: ISC
22/* Copyright (C) 2020 MediaTek Inc. */
33
4+ #include <linux/kernel.h>
5+ #include <linux/module.h>
6+ #include <linux/platform_device.h>
7+ #include <linux/pci.h>
8+
49#include "mt7915.h"
10+ #include "mac.h"
11+ #include "../trace.h"
512
613static u32 mt7915_reg_map_l1 (struct mt7915_dev * dev , u32 addr )
714{
@@ -125,7 +132,9 @@ static u32 mt7915_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
125132 return dev -> bus_ops -> rmw (mdev , addr , mask , val );
126133}
127134
128- int mt7915_mmio_init (struct mt76_dev * mdev , void __iomem * mem_base , int irq )
135+ static int mt7915_mmio_init (struct mt76_dev * mdev ,
136+ void __iomem * mem_base ,
137+ u32 device_id )
129138{
130139 struct mt76_bus_ops * bus_ops ;
131140 struct mt7915_dev * dev ;
@@ -148,7 +157,229 @@ int mt7915_mmio_init(struct mt76_dev *mdev, void __iomem *mem_base, int irq)
148157 (mt76_rr (dev , MT_HW_REV ) & 0xff );
149158 dev_dbg (mdev -> dev , "ASIC revision: %04x\n" , mdev -> rev );
150159
160+ return 0 ;
161+ }
162+
163+ void mt7915_dual_hif_set_irq_mask (struct mt7915_dev * dev ,
164+ bool write_reg ,
165+ u32 clear , u32 set )
166+ {
167+ struct mt76_dev * mdev = & dev -> mt76 ;
168+ unsigned long flags ;
169+
170+ spin_lock_irqsave (& mdev -> mmio .irq_lock , flags );
171+
172+ mdev -> mmio .irqmask &= ~clear ;
173+ mdev -> mmio .irqmask |= set ;
174+
175+ if (write_reg ) {
176+ mt76_wr (dev , MT_INT_MASK_CSR , mdev -> mmio .irqmask );
177+ mt76_wr (dev , MT_INT1_MASK_CSR , mdev -> mmio .irqmask );
178+ }
179+
180+ spin_unlock_irqrestore (& mdev -> mmio .irq_lock , flags );
181+ }
182+
183+ static void mt7915_rx_poll_complete (struct mt76_dev * mdev ,
184+ enum mt76_rxq_id q )
185+ {
186+ struct mt7915_dev * dev = container_of (mdev , struct mt7915_dev , mt76 );
187+ static const u32 rx_irq_mask [] = {
188+ [MT_RXQ_MAIN ] = MT_INT_RX_DONE_DATA0 ,
189+ [MT_RXQ_EXT ] = MT_INT_RX_DONE_DATA1 ,
190+ [MT_RXQ_MCU ] = MT_INT_RX_DONE_WM ,
191+ [MT_RXQ_MCU_WA ] = MT_INT_RX_DONE_WA ,
192+ [MT_RXQ_EXT_WA ] = MT_INT_RX_DONE_WA_EXT ,
193+ };
194+
195+ mt7915_irq_enable (dev , rx_irq_mask [q ]);
196+ }
197+
198+ /* TODO: support 2/4/6/8 MSI-X vectors */
199+ static void mt7915_irq_tasklet (struct tasklet_struct * t )
200+ {
201+ struct mt7915_dev * dev = from_tasklet (dev , t , irq_tasklet );
202+ u32 intr , intr1 , mask ;
203+
151204 mt76_wr (dev , MT_INT_MASK_CSR , 0 );
205+ if (dev -> hif2 )
206+ mt76_wr (dev , MT_INT1_MASK_CSR , 0 );
207+
208+ intr = mt76_rr (dev , MT_INT_SOURCE_CSR );
209+ intr &= dev -> mt76 .mmio .irqmask ;
210+ mt76_wr (dev , MT_INT_SOURCE_CSR , intr );
211+
212+ if (dev -> hif2 ) {
213+ intr1 = mt76_rr (dev , MT_INT1_SOURCE_CSR );
214+ intr1 &= dev -> mt76 .mmio .irqmask ;
215+ mt76_wr (dev , MT_INT1_SOURCE_CSR , intr1 );
216+
217+ intr |= intr1 ;
218+ }
219+
220+ trace_dev_irq (& dev -> mt76 , intr , dev -> mt76 .mmio .irqmask );
221+
222+ mask = intr & MT_INT_RX_DONE_ALL ;
223+ if (intr & MT_INT_TX_DONE_MCU )
224+ mask |= MT_INT_TX_DONE_MCU ;
225+
226+ mt7915_irq_disable (dev , mask );
227+
228+ if (intr & MT_INT_TX_DONE_MCU )
229+ napi_schedule (& dev -> mt76 .tx_napi );
230+
231+ if (intr & MT_INT_RX_DONE_DATA0 )
232+ napi_schedule (& dev -> mt76 .napi [MT_RXQ_MAIN ]);
233+
234+ if (intr & MT_INT_RX_DONE_DATA1 )
235+ napi_schedule (& dev -> mt76 .napi [MT_RXQ_EXT ]);
236+
237+ if (intr & MT_INT_RX_DONE_WM )
238+ napi_schedule (& dev -> mt76 .napi [MT_RXQ_MCU ]);
239+
240+ if (intr & MT_INT_RX_DONE_WA )
241+ napi_schedule (& dev -> mt76 .napi [MT_RXQ_MCU_WA ]);
242+
243+ if (intr & MT_INT_RX_DONE_WA_EXT )
244+ napi_schedule (& dev -> mt76 .napi [MT_RXQ_EXT_WA ]);
245+
246+ if (intr & MT_INT_MCU_CMD ) {
247+ u32 val = mt76_rr (dev , MT_MCU_CMD );
248+
249+ mt76_wr (dev , MT_MCU_CMD , val );
250+ if (val & MT_MCU_CMD_ERROR_MASK ) {
251+ dev -> reset_state = val ;
252+ ieee80211_queue_work (mt76_hw (dev ), & dev -> reset_work );
253+ wake_up (& dev -> reset_wait );
254+ }
255+ }
256+ }
257+
258+ static irqreturn_t mt7915_irq_handler (int irq , void * dev_instance )
259+ {
260+ struct mt7915_dev * dev = dev_instance ;
261+
262+ mt76_wr (dev , MT_INT_MASK_CSR , 0 );
263+ if (dev -> hif2 )
264+ mt76_wr (dev , MT_INT1_MASK_CSR , 0 );
265+
266+ if (!test_bit (MT76_STATE_INITIALIZED , & dev -> mphy .state ))
267+ return IRQ_NONE ;
268+
269+ tasklet_schedule (& dev -> irq_tasklet );
270+
271+ return IRQ_HANDLED ;
272+ }
273+
274+ int mt7915_mmio_probe (struct device * pdev ,
275+ void __iomem * mem_base ,
276+ u32 device_id ,
277+ int irq , struct mt7915_hif * hif2 )
278+ {
279+ static const struct mt76_driver_ops drv_ops = {
280+ /* txwi_size = txd size + txp size */
281+ .txwi_size = MT_TXD_SIZE + sizeof (struct mt7915_txp ),
282+ .drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ ,
283+ .survey_flags = SURVEY_INFO_TIME_TX |
284+ SURVEY_INFO_TIME_RX |
285+ SURVEY_INFO_TIME_BSS_RX ,
286+ .token_size = MT7915_TOKEN_SIZE ,
287+ .tx_prepare_skb = mt7915_tx_prepare_skb ,
288+ .tx_complete_skb = mt7915_tx_complete_skb ,
289+ .rx_skb = mt7915_queue_rx_skb ,
290+ .rx_check = mt7915_rx_check ,
291+ .rx_poll_complete = mt7915_rx_poll_complete ,
292+ .sta_ps = mt7915_sta_ps ,
293+ .sta_add = mt7915_mac_sta_add ,
294+ .sta_remove = mt7915_mac_sta_remove ,
295+ .update_survey = mt7915_update_channel ,
296+ };
297+ struct ieee80211_ops * ops ;
298+ struct mt7915_dev * dev ;
299+ struct mt76_dev * mdev ;
300+ int ret ;
301+
302+ ops = devm_kmemdup (pdev , & mt7915_ops , sizeof (mt7915_ops ), GFP_KERNEL );
303+ if (!ops )
304+ return - ENOMEM ;
305+
306+ mdev = mt76_alloc_device (pdev , sizeof (* dev ), ops , & drv_ops );
307+ if (!mdev )
308+ return - ENOMEM ;
309+
310+ dev = container_of (mdev , struct mt7915_dev , mt76 );
311+
312+ ret = mt7915_mmio_init (mdev , mem_base , device_id );
313+ if (ret )
314+ goto error ;
315+
316+ tasklet_setup (& dev -> irq_tasklet , mt7915_irq_tasklet );
317+
318+ mt76_wr (dev , MT_INT_MASK_CSR , 0 );
319+ /* master switch of PCIe tnterrupt enable */
320+ if (dev_is_pci (pdev ))
321+ mt76_wr (dev , MT_PCIE_MAC_INT_ENABLE , 0xff );
322+
323+ ret = devm_request_irq (mdev -> dev , irq , mt7915_irq_handler ,
324+ IRQF_SHARED , KBUILD_MODNAME , dev );
325+ if (ret )
326+ goto error ;
327+
328+ if (hif2 ) {
329+ dev -> hif2 = hif2 ;
330+
331+ mt76_wr (dev , MT_INT1_MASK_CSR , 0 );
332+ /* master switch of PCIe tnterrupt enable */
333+ if (dev_is_pci (pdev ))
334+ mt76_wr (dev , MT_PCIE1_MAC_INT_ENABLE , 0xff );
335+
336+ ret = devm_request_irq (mdev -> dev , dev -> hif2 -> irq ,
337+ mt7915_irq_handler , IRQF_SHARED ,
338+ KBUILD_MODNAME "-hif" , dev );
339+ if (ret ) {
340+ put_device (dev -> hif2 -> dev );
341+ goto free_irq ;
342+ }
343+ }
344+
345+ ret = mt7915_register_device (dev );
346+ if (ret )
347+ goto free_hif2_irq ;
152348
153349 return 0 ;
350+
351+ free_hif2_irq :
352+ if (dev -> hif2 )
353+ devm_free_irq (mdev -> dev , dev -> hif2 -> irq , dev );
354+ free_irq :
355+ devm_free_irq (mdev -> dev , irq , dev );
356+ error :
357+ mt76_free_device (& dev -> mt76 );
358+
359+ return ret ;
154360}
361+
362+ static int __init mt7915_init (void )
363+ {
364+ int ret ;
365+
366+ ret = pci_register_driver (& mt7915_hif_driver );
367+ if (ret )
368+ return ret ;
369+
370+ ret = pci_register_driver (& mt7915_pci_driver );
371+ if (ret )
372+ pci_unregister_driver (& mt7915_hif_driver );
373+
374+ return ret ;
375+ }
376+
377+ static void __exit mt7915_exit (void )
378+ {
379+ pci_unregister_driver (& mt7915_pci_driver );
380+ pci_unregister_driver (& mt7915_hif_driver );
381+ }
382+
383+ module_init (mt7915_init );
384+ module_exit (mt7915_exit );
385+ MODULE_LICENSE ("Dual BSD/GPL" );
0 commit comments