68
68
69
69
#define PCI_DEVICE_ID_LOONGSON_GMAC 0x7a03
70
70
#define PCI_DEVICE_ID_LOONGSON_GNET 0x7a13
71
- #define DWMAC_CORE_LS_MULTICHAN 0x10 /* Loongson custom ID */
72
- #define CHANNEL_NUM 8
71
+ #define DWMAC_CORE_MULTICHAN_V1 0x10 /* Loongson custom ID 0x10 */
72
+ #define DWMAC_CORE_MULTICHAN_V2 0x12 /* Loongson custom ID 0x12 */
73
73
74
74
struct loongson_data {
75
+ u32 multichan ;
75
76
u32 loongson_id ;
76
77
struct device * dev ;
77
78
};
@@ -119,18 +120,29 @@ static void loongson_default_data(struct pci_dev *pdev,
119
120
plat -> dma_cfg -> pbl = 32 ;
120
121
plat -> dma_cfg -> pblx8 = true;
121
122
122
- if (ld -> loongson_id == DWMAC_CORE_LS_MULTICHAN ) {
123
- plat -> rx_queues_to_use = CHANNEL_NUM ;
124
- plat -> tx_queues_to_use = CHANNEL_NUM ;
123
+ switch (ld -> loongson_id ) {
124
+ case DWMAC_CORE_MULTICHAN_V1 :
125
+ ld -> multichan = 1 ;
126
+ plat -> rx_queues_to_use = 8 ;
127
+ plat -> tx_queues_to_use = 8 ;
125
128
126
129
/* Only channel 0 supports checksum,
127
130
* so turn off checksum to enable multiple channels.
128
131
*/
129
- for (int i = 1 ; i < CHANNEL_NUM ; i ++ )
132
+ for (int i = 1 ; i < 8 ; i ++ )
130
133
plat -> tx_queues_cfg [i ].coe_unsupported = 1 ;
131
- } else {
134
+
135
+ break ;
136
+ case DWMAC_CORE_MULTICHAN_V2 :
137
+ ld -> multichan = 1 ;
138
+ plat -> rx_queues_to_use = 4 ;
139
+ plat -> tx_queues_to_use = 4 ;
140
+ break ;
141
+ default :
142
+ ld -> multichan = 0 ;
132
143
plat -> tx_queues_to_use = 1 ;
133
144
plat -> rx_queues_to_use = 1 ;
145
+ break ;
134
146
}
135
147
}
136
148
@@ -328,14 +340,14 @@ static struct mac_device_info *loongson_dwmac_setup(void *apriv)
328
340
return NULL ;
329
341
330
342
/* The Loongson GMAC and GNET devices are based on the DW GMAC
331
- * v3.50a and v3.73a IP-cores. But the HW designers have changed the
332
- * GMAC_VERSION.SNPSVER field to the custom 0x10 value on the
333
- * network controllers with the multi-channels feature
343
+ * v3.50a and v3.73a IP-cores. But the HW designers have changed
344
+ * the GMAC_VERSION.SNPSVER field to the custom 0x10/0x12 value
345
+ * on the network controllers with the multi-channels feature
334
346
* available to emphasize the differences: multiple DMA-channels,
335
347
* AV feature and GMAC_INT_STATUS CSR flags layout. Get back the
336
348
* original value so the correct HW-interface would be selected.
337
349
*/
338
- if (ld -> loongson_id == DWMAC_CORE_LS_MULTICHAN ) {
350
+ if (ld -> multichan ) {
339
351
priv -> synopsys_id = DWMAC_CORE_3_70 ;
340
352
* dma = dwmac1000_dma_ops ;
341
353
dma -> init_chan = loongson_dwmac_dma_init_channel ;
@@ -356,13 +368,13 @@ static struct mac_device_info *loongson_dwmac_setup(void *apriv)
356
368
if (mac -> multicast_filter_bins )
357
369
mac -> mcast_bits_log2 = ilog2 (mac -> multicast_filter_bins );
358
370
359
- /* Loongson GMAC doesn't support the flow control. LS2K2000
360
- * GNET doesn't support the half-duplex link mode.
371
+ /* Loongson GMAC doesn't support the flow control. Loongson GNET
372
+ * without multi-channel doesn't support the half-duplex link mode.
361
373
*/
362
374
if (pdev -> device == PCI_DEVICE_ID_LOONGSON_GMAC ) {
363
375
mac -> link .caps = MAC_10 | MAC_100 | MAC_1000 ;
364
376
} else {
365
- if (ld -> loongson_id == DWMAC_CORE_LS_MULTICHAN )
377
+ if (ld -> multichan )
366
378
mac -> link .caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
367
379
MAC_10 | MAC_100 | MAC_1000 ;
368
380
else
@@ -391,9 +403,11 @@ static int loongson_dwmac_msi_config(struct pci_dev *pdev,
391
403
struct plat_stmmacenet_data * plat ,
392
404
struct stmmac_resources * res )
393
405
{
394
- int i , ret , vecs ;
406
+ int i , ch_num , ret , vecs ;
407
+
408
+ ch_num = min (plat -> tx_queues_to_use , plat -> rx_queues_to_use );
395
409
396
- vecs = roundup_pow_of_two (CHANNEL_NUM * 2 + 1 );
410
+ vecs = roundup_pow_of_two (ch_num * 2 + 1 );
397
411
ret = pci_alloc_irq_vectors (pdev , vecs , vecs , PCI_IRQ_MSI );
398
412
if (ret < 0 ) {
399
413
dev_warn (& pdev -> dev , "Failed to allocate MSI IRQs\n" );
@@ -402,14 +416,12 @@ static int loongson_dwmac_msi_config(struct pci_dev *pdev,
402
416
403
417
res -> irq = pci_irq_vector (pdev , 0 );
404
418
405
- for (i = 0 ; i < plat -> rx_queues_to_use ; i ++ ) {
406
- res -> rx_irq [CHANNEL_NUM - 1 - i ] =
407
- pci_irq_vector (pdev , 1 + i * 2 );
419
+ for (i = 0 ; i < ch_num ; i ++ ) {
420
+ res -> rx_irq [ch_num - 1 - i ] = pci_irq_vector (pdev , 1 + i * 2 );
408
421
}
409
422
410
- for (i = 0 ; i < plat -> tx_queues_to_use ; i ++ ) {
411
- res -> tx_irq [CHANNEL_NUM - 1 - i ] =
412
- pci_irq_vector (pdev , 2 + i * 2 );
423
+ for (i = 0 ; i < ch_num ; i ++ ) {
424
+ res -> tx_irq [ch_num - 1 - i ] = pci_irq_vector (pdev , 2 + i * 2 );
413
425
}
414
426
415
427
plat -> flags |= STMMAC_FLAG_MULTI_MSI_EN ;
@@ -571,7 +583,7 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
571
583
goto err_disable_device ;
572
584
573
585
/* Use the common MAC IRQ if per-channel MSIs allocation failed */
574
- if (ld -> loongson_id == DWMAC_CORE_LS_MULTICHAN )
586
+ if (ld -> multichan )
575
587
loongson_dwmac_msi_config (pdev , plat , & res );
576
588
577
589
ret = stmmac_dvr_probe (& pdev -> dev , plat , & res );
@@ -583,7 +595,7 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
583
595
err_plat_clear :
584
596
if (dev_of_node (& pdev -> dev ))
585
597
loongson_dwmac_dt_clear (pdev , plat );
586
- if (ld -> loongson_id == DWMAC_CORE_LS_MULTICHAN )
598
+ if (ld -> multichan )
587
599
loongson_dwmac_msi_clear (pdev );
588
600
err_disable_device :
589
601
pci_disable_device (pdev );
@@ -602,7 +614,7 @@ static void loongson_dwmac_remove(struct pci_dev *pdev)
602
614
if (dev_of_node (& pdev -> dev ))
603
615
loongson_dwmac_dt_clear (pdev , priv -> plat );
604
616
605
- if (ld -> loongson_id == DWMAC_CORE_LS_MULTICHAN )
617
+ if (ld -> multichan )
606
618
loongson_dwmac_msi_clear (pdev );
607
619
608
620
pci_disable_device (pdev );
0 commit comments