@@ -1384,6 +1384,129 @@ static irqreturn_t mana_gd_intr(int irq, void *arg)
13841384 return IRQ_HANDLED ;
13851385}
13861386
1387+ void gdma_put_gic (struct gdma_context * gc , bool use_bitmap , int msi )
1388+ {
1389+ struct pci_dev * dev = to_pci_dev (gc -> dev );
1390+ struct msi_map irq_map ;
1391+ struct gdma_irq_context * gic ;
1392+ int irq ;
1393+
1394+ mutex_lock (& gc -> gic_mutex );
1395+
1396+ gic = xa_load (& gc -> irq_contexts , msi );
1397+ if (WARN_ON (!gic )) {
1398+ mutex_unlock (& gc -> gic_mutex );
1399+ return ;
1400+ }
1401+
1402+ if (!refcount_dec_and_test (& gic -> refcount ))
1403+ goto clear_bitmap ;
1404+
1405+ irq = pci_irq_vector (dev , msi );
1406+
1407+ irq_update_affinity_hint (irq , NULL );
1408+ free_irq (irq , gic );
1409+
1410+ irq_map .virq = irq ;
1411+ irq_map .index = msi ;
1412+ pci_msix_free_irq (dev , irq_map );
1413+
1414+ xa_erase (& gc -> irq_contexts , msi );
1415+ kfree (gic );
1416+
1417+ clear_bitmap :
1418+ if (use_bitmap )
1419+ clear_bit (msi , gc -> msi_bitmap );
1420+
1421+ mutex_unlock (& gc -> gic_mutex );
1422+ }
1423+ EXPORT_SYMBOL_NS (gdma_put_gic , "NET_MANA" );
1424+
1425+ struct gdma_irq_context * gdma_get_gic (struct gdma_context * gc , bool use_bitmap ,
1426+ u16 port_index , int queue_index ,
1427+ int * msi_requested )
1428+ {
1429+ struct gdma_irq_context * gic ;
1430+ struct pci_dev * dev = to_pci_dev (gc -> dev );
1431+ struct msi_map irq_map ;
1432+ int irq ;
1433+ int msi ;
1434+ int err ;
1435+
1436+ mutex_lock (& gc -> gic_mutex );
1437+
1438+ if (use_bitmap ) {
1439+ msi = find_first_zero_bit (gc -> msi_bitmap , gc -> num_msix_usable );
1440+ * msi_requested = msi ;
1441+ } else {
1442+ msi = * msi_requested ;
1443+ }
1444+
1445+ gic = xa_load (& gc -> irq_contexts , msi );
1446+ if (gic ) {
1447+ refcount_inc (& gic -> refcount );
1448+ if (use_bitmap )
1449+ set_bit (msi , gc -> msi_bitmap );
1450+ goto out ;
1451+ }
1452+
1453+ irq = pci_irq_vector (dev , msi );
1454+ if (irq == - EINVAL ) {
1455+ irq_map = pci_msix_alloc_irq_at (dev , msi , NULL );
1456+ if (!irq_map .virq ) {
1457+ err = irq_map .index ;
1458+ dev_err (gc -> dev ,
1459+ "Failed to alloc irq_map msi %d err %d\n" ,
1460+ msi , err );
1461+ gic = NULL ;
1462+ goto out ;
1463+ }
1464+ irq = irq_map .virq ;
1465+ msi = irq_map .index ;
1466+ }
1467+
1468+ gic = kzalloc (sizeof (* gic ), GFP_KERNEL );
1469+ if (!gic ) {
1470+ dev_err (gc -> dev , "Failed to allocate gic\n" );
1471+ goto out ;
1472+ }
1473+ gic -> handler = mana_gd_process_eq_events ;
1474+ gic -> msi = msi ;
1475+ gic -> irq = irq ;
1476+ INIT_LIST_HEAD (& gic -> eq_list );
1477+ spin_lock_init (& gic -> lock );
1478+
1479+ if (!gic -> msi )
1480+ snprintf (gic -> name , MANA_IRQ_NAME_SZ , "mana_hwc@pci:%s" ,
1481+ pci_name (dev ));
1482+ else if (use_bitmap )
1483+ snprintf (gic -> name , MANA_IRQ_NAME_SZ , "mana_p%dq%d@pci:%s" ,
1484+ port_index , queue_index , pci_name (dev ));
1485+ else
1486+ snprintf (gic -> name , MANA_IRQ_NAME_SZ , "mana_q%d@pci:%s" ,
1487+ queue_index , pci_name (dev ));
1488+
1489+ err = request_irq (irq , mana_gd_intr , 0 , gic -> name , gic );
1490+ if (err ) {
1491+ dev_err (gc -> dev , "Failed to request irq %d %s\n" ,
1492+ irq , gic -> name );
1493+ kfree (gic );
1494+ gic = NULL ;
1495+ goto out ;
1496+ }
1497+
1498+ refcount_set (& gic -> refcount , 1 );
1499+ xa_store (& gc -> irq_contexts , msi , gic , GFP_KERNEL );
1500+
1501+ if (use_bitmap )
1502+ set_bit (msi , gc -> msi_bitmap );
1503+
1504+ out :
1505+ mutex_unlock (& gc -> gic_mutex );
1506+ return gic ;
1507+ }
1508+ EXPORT_SYMBOL_NS (gdma_get_gic , "NET_MANA" );
1509+
13871510int mana_gd_alloc_res_map (u32 res_avail , struct gdma_resource * r )
13881511{
13891512 r -> map = bitmap_zalloc (res_avail , GFP_KERNEL );
@@ -1856,6 +1979,7 @@ static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
18561979 goto release_region ;
18571980
18581981 mutex_init (& gc -> eq_test_event_mutex );
1982+ mutex_init (& gc -> gic_mutex );
18591983 pci_set_drvdata (pdev , gc );
18601984 gc -> bar0_pa = pci_resource_start (pdev , 0 );
18611985
0 commit comments