@@ -34,37 +34,40 @@ u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val)
34
34
return val ;
35
35
}
36
36
37
- static void airoha_qdma_set_irqmask (struct airoha_qdma * qdma , int index ,
38
- u32 clear , u32 set )
37
+ static void airoha_qdma_set_irqmask (struct airoha_irq_bank * irq_bank ,
38
+ int index , u32 clear , u32 set )
39
39
{
40
+ struct airoha_qdma * qdma = irq_bank -> qdma ;
41
+ int bank = irq_bank - & qdma -> irq_banks [0 ];
40
42
unsigned long flags ;
41
43
42
- if (WARN_ON_ONCE (index >= ARRAY_SIZE (qdma -> irqmask )))
44
+ if (WARN_ON_ONCE (index >= ARRAY_SIZE (irq_bank -> irqmask )))
43
45
return ;
44
46
45
- spin_lock_irqsave (& qdma -> irq_lock , flags );
47
+ spin_lock_irqsave (& irq_bank -> irq_lock , flags );
46
48
47
- qdma -> irqmask [index ] &= ~clear ;
48
- qdma -> irqmask [index ] |= set ;
49
- airoha_qdma_wr (qdma , REG_INT_ENABLE (index ), qdma -> irqmask [index ]);
49
+ irq_bank -> irqmask [index ] &= ~clear ;
50
+ irq_bank -> irqmask [index ] |= set ;
51
+ airoha_qdma_wr (qdma , REG_INT_ENABLE (bank , index ),
52
+ irq_bank -> irqmask [index ]);
50
53
/* Read irq_enable register in order to guarantee the update above
51
54
* completes in the spinlock critical section.
52
55
*/
53
- airoha_qdma_rr (qdma , REG_INT_ENABLE (index ));
56
+ airoha_qdma_rr (qdma , REG_INT_ENABLE (bank , index ));
54
57
55
- spin_unlock_irqrestore (& qdma -> irq_lock , flags );
58
+ spin_unlock_irqrestore (& irq_bank -> irq_lock , flags );
56
59
}
57
60
58
- static void airoha_qdma_irq_enable (struct airoha_qdma * qdma , int index ,
59
- u32 mask )
61
+ static void airoha_qdma_irq_enable (struct airoha_irq_bank * irq_bank ,
62
+ int index , u32 mask )
60
63
{
61
- airoha_qdma_set_irqmask (qdma , index , 0 , mask );
64
+ airoha_qdma_set_irqmask (irq_bank , index , 0 , mask );
62
65
}
63
66
64
- static void airoha_qdma_irq_disable (struct airoha_qdma * qdma , int index ,
65
- u32 mask )
67
+ static void airoha_qdma_irq_disable (struct airoha_irq_bank * irq_bank ,
68
+ int index , u32 mask )
66
69
{
67
- airoha_qdma_set_irqmask (qdma , index , mask , 0 );
70
+ airoha_qdma_set_irqmask (irq_bank , index , mask , 0 );
68
71
}
69
72
70
73
static bool airhoa_is_lan_gdm_port (struct airoha_gdm_port * port )
@@ -739,9 +742,20 @@ static int airoha_qdma_rx_napi_poll(struct napi_struct *napi, int budget)
739
742
done += cur ;
740
743
} while (cur && done < budget );
741
744
742
- if (done < budget && napi_complete (napi ))
743
- airoha_qdma_irq_enable (q -> qdma , QDMA_INT_REG_IDX1 ,
744
- RX_DONE_INT_MASK );
745
+ if (done < budget && napi_complete (napi )) {
746
+ struct airoha_qdma * qdma = q -> qdma ;
747
+ int i , qid = q - & qdma -> q_rx [0 ];
748
+ int intr_reg = qid < RX_DONE_HIGH_OFFSET ? QDMA_INT_REG_IDX1
749
+ : QDMA_INT_REG_IDX2 ;
750
+
751
+ for (i = 0 ; i < ARRAY_SIZE (qdma -> irq_banks ); i ++ ) {
752
+ if (!(BIT (qid ) & RX_IRQ_BANK_PIN_MASK (i )))
753
+ continue ;
754
+
755
+ airoha_qdma_irq_enable (& qdma -> irq_banks [i ], intr_reg ,
756
+ BIT (qid % RX_DONE_HIGH_OFFSET ));
757
+ }
758
+ }
745
759
746
760
return done ;
747
761
}
@@ -944,7 +958,7 @@ static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget)
944
958
}
945
959
946
960
if (done < budget && napi_complete (napi ))
947
- airoha_qdma_irq_enable (qdma , QDMA_INT_REG_IDX0 ,
961
+ airoha_qdma_irq_enable (& qdma -> irq_banks [ 0 ] , QDMA_INT_REG_IDX0 ,
948
962
TX_DONE_INT_MASK (id ));
949
963
950
964
return done ;
@@ -1174,14 +1188,24 @@ static int airoha_qdma_hw_init(struct airoha_qdma *qdma)
1174
1188
{
1175
1189
int i ;
1176
1190
1177
- /* clear pending irqs */
1178
- for ( i = 0 ; i < ARRAY_SIZE ( qdma -> irqmask ); i ++ )
1191
+ for ( i = 0 ; i < ARRAY_SIZE ( qdma -> irq_banks ); i ++ ) {
1192
+ /* clear pending irqs */
1179
1193
airoha_qdma_wr (qdma , REG_INT_STATUS (i ), 0xffffffff );
1180
-
1181
- /* setup irqs */
1182
- airoha_qdma_irq_enable (qdma , QDMA_INT_REG_IDX0 , INT_IDX0_MASK );
1183
- airoha_qdma_irq_enable (qdma , QDMA_INT_REG_IDX1 , INT_IDX1_MASK );
1184
- airoha_qdma_irq_enable (qdma , QDMA_INT_REG_IDX4 , INT_IDX4_MASK );
1194
+ /* setup rx irqs */
1195
+ airoha_qdma_irq_enable (& qdma -> irq_banks [i ], QDMA_INT_REG_IDX0 ,
1196
+ INT_RX0_MASK (RX_IRQ_BANK_PIN_MASK (i )));
1197
+ airoha_qdma_irq_enable (& qdma -> irq_banks [i ], QDMA_INT_REG_IDX1 ,
1198
+ INT_RX1_MASK (RX_IRQ_BANK_PIN_MASK (i )));
1199
+ airoha_qdma_irq_enable (& qdma -> irq_banks [i ], QDMA_INT_REG_IDX2 ,
1200
+ INT_RX2_MASK (RX_IRQ_BANK_PIN_MASK (i )));
1201
+ airoha_qdma_irq_enable (& qdma -> irq_banks [i ], QDMA_INT_REG_IDX3 ,
1202
+ INT_RX3_MASK (RX_IRQ_BANK_PIN_MASK (i )));
1203
+ }
1204
+ /* setup tx irqs */
1205
+ airoha_qdma_irq_enable (& qdma -> irq_banks [0 ], QDMA_INT_REG_IDX0 ,
1206
+ TX_COHERENT_LOW_INT_MASK | INT_TX_MASK );
1207
+ airoha_qdma_irq_enable (& qdma -> irq_banks [0 ], QDMA_INT_REG_IDX4 ,
1208
+ TX_COHERENT_HIGH_INT_MASK );
1185
1209
1186
1210
/* setup irq binding */
1187
1211
for (i = 0 ; i < ARRAY_SIZE (qdma -> q_tx ); i ++ ) {
@@ -1226,38 +1250,47 @@ static int airoha_qdma_hw_init(struct airoha_qdma *qdma)
1226
1250
1227
1251
static irqreturn_t airoha_irq_handler (int irq , void * dev_instance )
1228
1252
{
1229
- struct airoha_qdma * qdma = dev_instance ;
1230
- u32 intr [ARRAY_SIZE (qdma -> irqmask )];
1253
+ struct airoha_irq_bank * irq_bank = dev_instance ;
1254
+ struct airoha_qdma * qdma = irq_bank -> qdma ;
1255
+ u32 rx_intr_mask = 0 , rx_intr1 , rx_intr2 ;
1256
+ u32 intr [ARRAY_SIZE (irq_bank -> irqmask )];
1231
1257
int i ;
1232
1258
1233
- for (i = 0 ; i < ARRAY_SIZE (qdma -> irqmask ); i ++ ) {
1259
+ for (i = 0 ; i < ARRAY_SIZE (intr ); i ++ ) {
1234
1260
intr [i ] = airoha_qdma_rr (qdma , REG_INT_STATUS (i ));
1235
- intr [i ] &= qdma -> irqmask [i ];
1261
+ intr [i ] &= irq_bank -> irqmask [i ];
1236
1262
airoha_qdma_wr (qdma , REG_INT_STATUS (i ), intr [i ]);
1237
1263
}
1238
1264
1239
1265
if (!test_bit (DEV_STATE_INITIALIZED , & qdma -> eth -> state ))
1240
1266
return IRQ_NONE ;
1241
1267
1242
- if (intr [1 ] & RX_DONE_INT_MASK ) {
1243
- airoha_qdma_irq_disable (qdma , QDMA_INT_REG_IDX1 ,
1244
- RX_DONE_INT_MASK );
1268
+ rx_intr1 = intr [1 ] & RX_DONE_LOW_INT_MASK ;
1269
+ if (rx_intr1 ) {
1270
+ airoha_qdma_irq_disable (irq_bank , QDMA_INT_REG_IDX1 , rx_intr1 );
1271
+ rx_intr_mask |= rx_intr1 ;
1272
+ }
1273
+
1274
+ rx_intr2 = intr [2 ] & RX_DONE_HIGH_INT_MASK ;
1275
+ if (rx_intr2 ) {
1276
+ airoha_qdma_irq_disable (irq_bank , QDMA_INT_REG_IDX2 , rx_intr2 );
1277
+ rx_intr_mask |= (rx_intr2 << 16 );
1278
+ }
1245
1279
1246
- for (i = 0 ; i < ARRAY_SIZE (qdma -> q_rx ); i ++ ) {
1247
- if (!qdma -> q_rx [i ].ndesc )
1248
- continue ;
1280
+ for (i = 0 ; rx_intr_mask && i < ARRAY_SIZE (qdma -> q_rx ); i ++ ) {
1281
+ if (!qdma -> q_rx [i ].ndesc )
1282
+ continue ;
1249
1283
1250
- if (intr [1 ] & BIT (i ))
1251
- napi_schedule (& qdma -> q_rx [i ].napi );
1252
- }
1284
+ if (rx_intr_mask & BIT (i ))
1285
+ napi_schedule (& qdma -> q_rx [i ].napi );
1253
1286
}
1254
1287
1255
1288
if (intr [0 ] & INT_TX_MASK ) {
1256
1289
for (i = 0 ; i < ARRAY_SIZE (qdma -> q_tx_irq ); i ++ ) {
1257
1290
if (!(intr [0 ] & TX_DONE_INT_MASK (i )))
1258
1291
continue ;
1259
1292
1260
- airoha_qdma_irq_disable (qdma , QDMA_INT_REG_IDX0 ,
1293
+ airoha_qdma_irq_disable (irq_bank , QDMA_INT_REG_IDX0 ,
1261
1294
TX_DONE_INT_MASK (i ));
1262
1295
napi_schedule (& qdma -> q_tx_irq [i ].napi );
1263
1296
}
@@ -1266,16 +1299,47 @@ static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
1266
1299
return IRQ_HANDLED ;
1267
1300
}
1268
1301
1302
+ static int airoha_qdma_init_irq_banks (struct platform_device * pdev ,
1303
+ struct airoha_qdma * qdma )
1304
+ {
1305
+ struct airoha_eth * eth = qdma -> eth ;
1306
+ int i , id = qdma - & eth -> qdma [0 ];
1307
+
1308
+ for (i = 0 ; i < ARRAY_SIZE (qdma -> irq_banks ); i ++ ) {
1309
+ struct airoha_irq_bank * irq_bank = & qdma -> irq_banks [i ];
1310
+ int err , irq_index = 4 * id + i ;
1311
+ const char * name ;
1312
+
1313
+ spin_lock_init (& irq_bank -> irq_lock );
1314
+ irq_bank -> qdma = qdma ;
1315
+
1316
+ irq_bank -> irq = platform_get_irq (pdev , irq_index );
1317
+ if (irq_bank -> irq < 0 )
1318
+ return irq_bank -> irq ;
1319
+
1320
+ name = devm_kasprintf (eth -> dev , GFP_KERNEL ,
1321
+ KBUILD_MODNAME ".%d" , irq_index );
1322
+ if (!name )
1323
+ return - ENOMEM ;
1324
+
1325
+ err = devm_request_irq (eth -> dev , irq_bank -> irq ,
1326
+ airoha_irq_handler , IRQF_SHARED , name ,
1327
+ irq_bank );
1328
+ if (err )
1329
+ return err ;
1330
+ }
1331
+
1332
+ return 0 ;
1333
+ }
1334
+
1269
1335
static int airoha_qdma_init (struct platform_device * pdev ,
1270
1336
struct airoha_eth * eth ,
1271
1337
struct airoha_qdma * qdma )
1272
1338
{
1273
1339
int err , id = qdma - & eth -> qdma [0 ];
1274
1340
const char * res ;
1275
1341
1276
- spin_lock_init (& qdma -> irq_lock );
1277
1342
qdma -> eth = eth ;
1278
-
1279
1343
res = devm_kasprintf (eth -> dev , GFP_KERNEL , "qdma%d" , id );
1280
1344
if (!res )
1281
1345
return - ENOMEM ;
@@ -1285,12 +1349,7 @@ static int airoha_qdma_init(struct platform_device *pdev,
1285
1349
return dev_err_probe (eth -> dev , PTR_ERR (qdma -> regs ),
1286
1350
"failed to iomap qdma%d regs\n" , id );
1287
1351
1288
- qdma -> irq = platform_get_irq (pdev , 4 * id );
1289
- if (qdma -> irq < 0 )
1290
- return qdma -> irq ;
1291
-
1292
- err = devm_request_irq (eth -> dev , qdma -> irq , airoha_irq_handler ,
1293
- IRQF_SHARED , KBUILD_MODNAME , qdma );
1352
+ err = airoha_qdma_init_irq_banks (pdev , qdma );
1294
1353
if (err )
1295
1354
return err ;
1296
1355
@@ -2784,7 +2843,7 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth,
2784
2843
dev -> features |= dev -> hw_features ;
2785
2844
dev -> vlan_features = dev -> hw_features ;
2786
2845
dev -> dev .of_node = np ;
2787
- dev -> irq = qdma -> irq ;
2846
+ dev -> irq = qdma -> irq_banks [ 0 ]. irq ;
2788
2847
SET_NETDEV_DEV (dev , eth -> dev );
2789
2848
2790
2849
/* reserve hw queues for HTB offloading */
0 commit comments