Index: lib/avxpci/avxpci.h
===================================================================
--- lib/avxpci/avxpci.h	(revision 9208)
+++ lib/avxpci/avxpci.h	(working copy)
@@ -23,6 +23,7 @@
     char vendor[16];
     uint16_t deviceid;
     uint16_t vendorid;
+    uint16_t subsystem_vendorid;
 } pci_dev_info_t;
 
 
@@ -63,6 +64,7 @@
     pci_driver_t driver;
     uint16_t deviceid;
     uint16_t vendorid;
+    uint16_t subsystem_vendorid;
     /* vf on this port */
     int vf_num;
     int vf_mode;
Index: lib/avxpci/avxpci.c
===================================================================
--- lib/avxpci/avxpci.c	(revision 9208)
+++ lib/avxpci/avxpci.c	(working copy)
@@ -117,6 +117,7 @@
             port_info[cnt].func = port_list[i].func;
             port_info[cnt].deviceid = port_list[i].deviceid;
             port_info[cnt].vendorid = port_list[i].vendorid;
+            port_info[cnt].subsystem_vendorid = port_list[i].subsystem_vendorid;
             cnt++;
         }
     }
Index: lib/avxpci/avxpci/pci_dev.py
===================================================================
--- lib/avxpci/avxpci/pci_dev.py	(revision 9208)
+++ lib/avxpci/avxpci/pci_dev.py	(working copy)
@@ -1,5 +1,6 @@
 import os
 import re
+from collections import OrderedDict
 
 class AVX_PCI(object):
     DBDF_PATTERN = '(.+):(.+):(.+)\\.(.?)$'
@@ -10,6 +11,7 @@
     device = None
     function = None
     vendorid = None
+    subsystem_vendorid = None
     deviceid = None
     numad = None
 
@@ -30,6 +32,7 @@
         self.device = "{0:#0{1}x}".format(int(res.groups()[2], 16), 4)
         self.function = "{0:#0{1}x}".format(int(res.groups()[3], 16), 3)
         self.vendorid = self.read_from_fd(self.path + '/vendor')
+        self.subsystem_vendorid = self.read_from_fd(self.path + '/subsystem_vendor')
         self.deviceid = self.read_from_fd(self.path + '/device')
         self.numad = self.read_from_fd(self.path + '/numa_node')
         if int(self.numad) < 0:
@@ -44,15 +47,16 @@
         return content
 
     def dump(self):
-        pci_info = {}
-        pci_info['path'] = self.path
+        pci_info = OrderedDict()
         pci_info['name'] = self.name
         pci_info['domain'] = self.domain
         pci_info['bus'] = self.bus
         pci_info['device'] = self.device
         pci_info['function'] = self.function
+        pci_info['path'] = self.path
         pci_info['vendorid'] = self.vendorid
         pci_info['deviceid'] = self.deviceid
+        pci_info['subsystem_vendorid'] = self.subsystem_vendorid
         pci_info['numad'] = self.numad
         return pci_info
 
Index: lib/avxpci/avxpci/pf.py
===================================================================
--- lib/avxpci/avxpci/pf.py	(revision 9208)
+++ lib/avxpci/avxpci/pf.py	(working copy)
@@ -3,6 +3,7 @@
 import collections
 from pci_dev import AVX_PCI
 from vf import AVX_VF
+from collections import OrderedDict
 
 #key: driver
 #val: vendor, driver type index, vf mode(multiple as one, 0 means only passthough)
@@ -161,20 +162,24 @@
 
 
     def dump(self, dump_vf_detail=True):
-        pf_info = {}
+        pf_info = OrderedDict()
         vf_info = []
+        # VF base info
         for vf in self.vfs:
             if dump_vf_detail:
                 vf_info.append(vf.dump())
             else:
                 vf_info.append(vf.alias)
+        # PF base info
         pci_info = super(AVX_PF, self).dump()
-        pf_info['vfs'] = vf_info
-        pf_info['vf_num'] = len(self.vfs)
+        for k, v in pci_info.items():
+            pf_info[k] = v
+        # PF extended info
+        pf_info['sys_name'] = self.sys_name
+        pf_info['vendor'] = self.vendor
         pf_info['driver'] = self.driver
+        pf_info['pf_type'] = self.pf_type
         pf_info['vf_mode'] = self.vf_mode
-        pf_info['pf_type'] = self.pf_type
-        pf_info['vendor'] = self.vendor
-        pf_info['sys_name'] = self.sys_name
-        pf_info = dict(pf_info, **pci_info)
+        pf_info['vf_num'] = len(self.vfs)
+        pf_info['vfs'] = vf_info
         return pf_info
Index: lib/avxpci/avxpci/utils.py
===================================================================
--- lib/avxpci/avxpci/utils.py	(revision 9208)
+++ lib/avxpci/avxpci/utils.py	(working copy)
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 import os
 import re
 import logging
@@ -3,4 +4,5 @@
 import json
 from pf import AVX_PF
+from collections import OrderedDict
 
 AVX_PF_CACHE_FILE='/var/run/avx_pf.cache'
@@ -51,9 +53,12 @@
     '2800GnPORT':    [0, 0],
     # 5900 policy: [10G, 1G, 40G, onboard 10G, 25G]
     '5900':    [PORT_REVERSE, PORT_EXCHANGE|PORT_REVERSE, PORT_SWAP, 0, 0],
-    # 7900/9900 policy: [10G NUMA0, 10G NUMA1, 1G NUMA0, 1G NUMA1, 40G NUMA0, 40G NUMA1, onboard 10G, 25G NUMA1, 25G NUMA2, 100G NUMA1, 100G NUMA2] 
+    # 7900/9900 policy: [10G NUMA0, 10G NUMA1, 1G NUMA0, 1G NUMA1, 40G NUMA0, 40G NUMA1, onboard 10G, 25G NUMA1, 25G NUMA2, 100G NUMA1, 100G NUMA2]
     '7900':    [PORT_REVERSE, PORT_REVERSE, PORT_EXCHANGE|PORT_REVERSE, PORT_EXCHANGE|PORT_REVERSE, PORT_SWAP, PORT_SWAP, 0, 0, 0, 0, 0],
     '9900':    [PORT_REVERSE, PORT_REVERSE, PORT_EXCHANGE|PORT_REVERSE, PORT_EXCHANGE|PORT_REVERSE, PORT_SWAP, PORT_SWAP, 0, 0, 0, 0, 0],
+    # Caswell 7900/9900 policy: [mgmt, slot1, slot2, slot3, slot4, slot5, slot6, slot7, slot8]
+    '7900Caswell':    [0, 0, PORT_EXCHANGE|PORT_REVERSE|PORT_SWAP, 0, PORT_EXCHANGE|PORT_REVERSE|PORT_SWAP, 0, 0, 0, 0],
+    '9900Caswell':    [0, 0, PORT_EXCHANGE|PORT_REVERSE|PORT_SWAP, 0, PORT_EXCHANGE|PORT_REVERSE|PORT_SWAP, 0, 0, 0, 0],
     '6850':  [0, 0],
     '7850':  [PORT_DESCEND|PORT_EXCHANGE, 0],
     'default':  [PORT_DESCEND|PORT_REVERSE, PORT_DESCEND|PORT_REVERSE],
@@ -76,8 +81,8 @@
     '952800': '2800',
     '956850': '6850',
     '957850': '7850',
-    '957902': '7900',   # Caswell 7900
-    '959902': '9900',   # Caswell 9900
+    '957902': '7900Caswell',   # Caswell 7900
+    '959902': '9900Caswell',   # Caswell 9900
 }
 
 def _get_onboard():
@@ -129,7 +134,7 @@
             modelex = '5800IMASTER'
     if modelex in PORT_POLICY:
         policy[0] = PORT_POLICY[modelex][0]
-    
+
     modelex = model
     if dom2_40G != 0:
         if model + '40G' in PORT_POLICY:
@@ -163,19 +168,22 @@
             policy[0] = PORT_POLICY[modelex][0]
             policy[1] = PORT_POLICY[modelex][1]
 
+    if model == '7900Caswell' or model == '9900Caswell':
+        policy = PORT_POLICY[model]
+
     return policy
 
 def _get_Gn1_policy(dom1_Gn1_pfs, dom2_Gn1_pfs):
-    
+
     model = _get_model()
     policy = [0, 0]
-    
+
     modelex = model
     if dom1_Gn1_pfs != 0:
         modelex = model + 'GnPORT'
         if modelex in PORT_POLICY:
             policy[0] = PORT_POLICY[modelex][0]
-    
+
     modelex = model
     if dom2_Gn1_pfs != 0:
         modelex = model + 'GnPORT'
@@ -300,7 +308,7 @@
     if os.access(path, os.R_OK) == False:
         return pfs
     files = os.listdir(path)
-    if len(files) < 0:
+    if len(files) <= 0:
         return pfs
 
     for f in files:
@@ -326,7 +334,7 @@
             pf100Gn1.append(f)
         elif f.deviceid == '0x1583' or f.deviceid == '0x1584':
             pf40Gn1.append(f)
-        elif f.deviceid == '0x158b' or f.deviceid == '0x1593':
+        elif f.deviceid == '0x158b' or (f.deviceid == '0x1593' and f.subsystem_vendorid == '0x1e97'):
             pf25Gn1.append(f)
         elif f.driver == 'igb':
             pfGn1.append(f)
@@ -353,7 +361,7 @@
             pf100Gn2.append(f)
         elif f.deviceid == '0x1583' or f.deviceid == '0x1584':
             pf40Gn2.append(f)
-        elif f.deviceid == '0x158b' or f.deviceid == '0x1593':
+        elif f.deviceid == '0x158b' or (f.deviceid == '0x1593' and f.subsystem_vendorid == '0x1e97'):
             pf25Gn2.append(f)
         elif f.driver == 'igb':
             pfGn2.append(f)
@@ -376,12 +384,12 @@
     if _get_model() == '9800' and silicom == True:
         sort_mixed_cards(pfn1)
         sort_mixed_cards(pfn2)
-    
+
     if _get_model() == '7601':
         policy = _get_Gn1_policy(pfGn1, pfGn2)
         pfGn1 = _pf_sort(pfGn1, policy[0])
         pfGn2 = _pf_sort(pfGn2, policy[1])
-    
+
     if _get_model() == '5900':
         policy = _get_policy(pfGn1, pfGn2, silicom, False, False, False)
         # policy[0] for 10G NIC and policy[1] for 1G NIC
@@ -411,13 +419,13 @@
         # policy[9] for 25G NIC in domian0 and policy[10] for 25G NIC in domain1
         pf100Gn1 = _pf_sort(pf100Gn1, policy[9])
         pf100Gn2 = _pf_sort(pf100Gn2, policy[10])
-    
+
     if _get_model() == '5800':
         pfGn1 = _pf_model5800_sort(pfGn1)
-    
+
     if _get_model() == "11600D":
         pfn2[2], pfn2[3], pfn2[4], pfn2[5] = pfn2[4], pfn2[5], pfn2[2], pfn2[3]
-        
+
     if _get_model() == "2800" and pfGn1:
         pfGn1[0],pfGn1[1],pfGn1[2] = pfGn1[2],pfGn1[0],pfGn1[1]
 
@@ -429,10 +437,9 @@
     if _get_model() == "5900" or _get_model() == "7900" or _get_model() == "9900":
         pfs = (
                 mgmt + pf40Gn1 + pf40Gn2 +
-                pf25Gn1 + pf25Gn2 + pfn1 + pfn2 + 
+                pf25Gn1 + pf25Gn2 + pfn1 + pfn2 +
                 pfGn1 + pfGn2 + pf100Gn1 + pf100Gn2
             )
-
     return pfs
 
 def _get_pf_cache():
@@ -448,9 +455,13 @@
         return cache
     ret = []
     try:
-        pfs = _get_pf(drv, drv_dir)
-        for p in pfs:
-            ret.append(p.dump(True))
+        if _get_model() == '7900Caswell' or _get_model() == '9900Caswell':
+            pfs = _get_pf_Caswell(drv, drv_dir)
+            return pfs
+        else:
+            pfs = _get_pf(drv, drv_dir)
+            for p in pfs:
+                ret.append(p.dump(True))
     except Exception, e:
         logging.error(e)
     return ret
@@ -473,3 +484,142 @@
             pfs[i : i+4] = newpfs
 
     return pfs
+
+
+
+def _get_pf_Caswell(drv, drv_dir):
+    global onboard
+    pfs = []
+    path = "/sys/module/%s/drivers" % drv
+
+    if drv_dir != None:
+        path = drv_dir + '/' + path
+    if os.access(path, os.R_OK) == False:
+        return pfs
+    files = os.listdir(path)
+    if len(files) != 1:
+        return pfs
+    path += '/' + files[0]
+    if os.access(path, os.R_OK) == False:
+        return pfs
+    files = os.listdir(path)
+    if len(files) <= 0:
+        return pfs
+
+    for f in files:
+        res = re.search(AVX_PF.DBDF_PATTERN, f)
+        if res == None:
+            continue
+        pfpath = path + '/' + f
+        pf = AVX_PF(pfpath)
+        pfs.append(pf)
+    return pfs
+
+
+# Physical layout of CAPB-5070: Front view
+#                                   ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
+#                                   │    slot5    │ │    slot6    │ │    slot7    │ │    slot8    │
+#                                   └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
+# ┌───────┬───┬───┬─────┬─────┬───┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
+# │console│USB│USB│mgmt1│mgmt2│BMC│ │    slot1    │ │    slot2    │ │    slot3    │ │    slot4    │
+# └───────┴───┴───┴─────┴─────┴───┘ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
+# PCI Bridge IDs:
+# - mgmt1 slot: 00:0c.0
+# - mgmt2 slot: 00:0e.0
+# - slot 1 and 2: 29:05.0 and 29:01.0
+# - slot 3 and 4: aa:05.0 and aa:01.0
+# - slot 5 and 6: 16:05.0 and 16:01.0
+# - slot 7 and 8: 98:05.0 and 98:01.0
+
+def search_bridge_pci(pci_id):
+    sysfs_path = os.path.join("/sys/bus/pci/devices", pci_id)
+    if not os.path.exists(sysfs_path):
+        return None
+
+    # Example real_path: /sys/devices/pci0000:00/0000:00:1c.0/0000:86:00.0
+    real_path = os.path.realpath(sysfs_path)
+
+    # split path segments
+    parts = real_path.strip("/").split("/")
+
+    # search pci0000:xx part
+    for i, part in enumerate(parts):
+        if part.startswith("pci0000:"):
+            # next must be  root port / bridge
+            if i + 1 < len(parts):
+                return parts[i + 1]
+    return None
+
+BRIDGE_PCI_CAPB_5070NR = {
+    "mgmt_1" : "0000:00:0c.0",
+    "mgmt_2" : "0000:00:0e.0",
+    "slot_1" : "0000:29:05.0",
+    "slot_2" : "0000:29:01.0",
+    "slot_3" : "0000:aa:05.0",
+    "slot_4" : "0000:aa:01.0",
+    "slot_5" : "0000:16:05.0",
+    "slot_6" : "0000:16:01.0",
+    "slot_7" : "0000:98:05.0",
+    "slot_8" : "0000:98:01.0"
+}
+
+# Caswell CAPB-5070NR uses the root bridge PCIe ID of the NIC slot for classification and then sorting.
+def _pf_sort_policy_Caswell_5070NR(port_list):
+    pfs = []
+    policy = PORT_POLICY[_get_model()]
+
+    # Reverse mapping for BRIDGE_PCI
+    PCI_TO_SLOT = {
+        pci: name
+        for name, pci in BRIDGE_PCI_CAPB_5070NR.items()
+    }
+
+    port_groups = OrderedDict([
+        ("mgmt", []),
+        ("slot_1", []),
+        ("slot_2", []),
+        ("slot_3", []),
+        ("slot_4", []),
+        ("slot_5", []),
+        ("slot_6", []),
+        ("slot_7", []),
+        ("slot_8", []),
+    ])
+
+    port_num = len(port_list)
+    if port_num == 0:
+        return port_list
+
+    for port in port_list:
+        bridge_pci = search_bridge_pci(port.name)
+        slot_name = PCI_TO_SLOT.get(bridge_pci)
+
+        if slot_name is None:
+            continue
+
+        # Use root bridge PCIe ID of the NIC slot for classification
+        if slot_name.startswith("mgmt"):
+            port_groups["mgmt"].append(port)
+        else:
+            port_groups[slot_name].append(port)
+
+    # Merge and sort port_groups according to slot index order
+    SLOT_ORDER = [
+        "mgmt",
+        "slot_1",
+        "slot_2",
+        "slot_3",
+        "slot_4",
+        "slot_5",
+        "slot_6",
+        "slot_7",
+        "slot_8",
+    ]
+
+    for i, slot in enumerate(SLOT_ORDER):
+        # Sort each port_groups according to each policy
+        port_groups[slot] = _pf_sort(port_groups.get(slot, []), policy[i])
+        # Merge all port_groups to slot index order
+        pfs.extend(port_groups.get(slot, []))
+
+    return pfs
\ No newline at end of file
Index: lib/avxpci/get_port.py
===================================================================
--- lib/avxpci/get_port.py	(revision 9208)
+++ lib/avxpci/get_port.py	(working copy)
@@ -4,6 +4,7 @@
 from avxpci.utils import get_pf
 from avxpci.utils import _get_model
 from avxpci.utils import _get_onboard
+from avxpci.utils import _pf_sort_policy_Caswell_5070NR
 from avxpci.pf import avx_pf_type
 
 AVX_PORT = avx_pf_type
@@ -14,6 +15,7 @@
     ssls = []
     onboard = []
     aewin_models = {"5900", "7900", "9900"}
+    caswell_models = {"7900Caswell", "9900Caswell"}
     if os.access(AVX_PORT_CACHE_PATH, os.F_OK):
         with open(AVX_PORT_CACHE_PATH, 'r') as f:
             jstring = f.read()
@@ -30,6 +32,12 @@
             if len(onboard) == 0:
                 onboard = _get_onboard()
 
+        if _get_model() in caswell_models:
+            ports = _pf_sort_policy_Caswell_5070NR(ports)
+            ssls = _pf_sort_policy_Caswell_5070NR(ssls)
+            ports = [p.dump(True) for p in ports] if ports else []
+            ssls  = [s.dump(True) for s in ssls] if ssls else []
+
         ssls = sorted(ssls, key=lambda v:(int(v['bus'], 16)<<12)+(int(v['device'], 16)<<4)+int(v['function'], 16))
 
         with open(AVX_PORT_CACHE_PATH, 'w') as f:
Index: lib/avxpci/struct_va_port_stub.c
===================================================================
--- lib/avxpci/struct_va_port_stub.c	(revision 9208)
+++ lib/avxpci/struct_va_port_stub.c	(working copy)
@@ -117,6 +117,8 @@
         snprintf(pf->vendor, sizeof(pf->vendor), "%s", str);
     } else if (strcmp(key, "vendorid") == 0) {
         pf->vendorid = (unsigned short)strtoul(str, NULL, 0);
+    } else if (strcmp(key, "subsystem_vendorid") == 0) {
+        pf->subsystem_vendorid = (unsigned short)strtoul(str, NULL, 0);
     } else if (strcmp(key, "vfs") == 0) {
         if (pf->vf_num != 0) {
             pf->pvf = (struct va_vf*)malloc(pf->vf_num * sizeof(struct va_vf));
Index: scripts/onboard_ifs.py
===================================================================
--- scripts/onboard_ifs.py	(revision 9208)
+++ scripts/onboard_ifs.py	(working copy)
@@ -1,210 +1,226 @@
-import json
-import os
-import re
-#  model     baseboard     cpu            cpu num(physical)
-#  10650     X9DR3-F       E5-2690-v2      2
-#  7600      X10DRi        E5-2620-v3      2
-#  3600v5    X11SSi-LN4F   E3-1240-v5      1
-#  5800      X11SSi-LN4F   E3-1240-v6      1
-#  7800      X11DPi-N      5115-CPU        1
-#  9800      X11DPi-N      5115-CPU        2
-#  5900      CB-1924       4210R-CPU       1
-#  7900      CB-1920       4215-CPU        2
-#  9900      CB-1920       6226R-CPU       2
-
-def get_model():
-    model = 'default'
-    with open('/var/array/public/config/arraymodel', 'r') as f:
-        model = f.read().strip('\n')
-    return model
-
-#PCI dictionary use 'baseboard info + cpu info + physical cpu count' as the key
-PCIs = {
-    "X10DRi E5-2620-v3 x 2": [
-        "0b:00.0", 
-        "0b:00.1"
-    ],
-
-    "X11SSi-LN4F E3-1240-v5 x 1": [
-        "0d:00.0", 
-        "0e:00.0", 
-        "0f:00.0", 
-        "10:00.0"
-    ],
-
-    "X9DR3-F E5-2690-v2 x 2": [
-        "02:00.0", 
-        "02:00.1"
-    ],
-    
-    "X11SSi-LN4F E3-1240-v6 x 1": [
-        [
-            "08:00.0",
-            "09:00.0",
-            "0a:00.0",
-            "0b:00.0"
-        ],
-        [
-            "09:00.0",
-            "0a:00.0",
-            "0b:00.0",
-            "0c:00.0"
-        ]
-    ],
-
-    "X11DPi-N 5115-CPU x 1": [
-        "b5:00.0",
-        "b5:00.1"
-    ],
-
-    "X11DPi-N 5115-CPU x 2": [
-        "60:00.0",
-        "60:00.1"
-    ],
-
-    "CB-1924 4210R-CPU x 1": [
-        "02:00.0"
-    ],
-
-    "CB-1920 4215-CPU x 2": [
-        "03:00.0"
-    ],
-
-    "CB-1920 6226R-CPU x 2": [
-        "03:00.0"
-    ]    
-}
-
-#  mode        onboard nic deviceid
-#  10650       0x1521
-#  7600        0x1521
-#  3600 v5     0x1533
-#  5800        0x1533
-#  7800        0x37d1
-#  9800        0x37d1
-#  5900        0x1533
-#  7900        0x1533
-#  9900        0x1533
-devices = [
-    "0x1533", 
-    "0x37d1"
-]
-
-
-model = get_model()
-if model != '955800' and model != '956850' and model != '900610':
-    devices.append("0x1521")
-
-vendors = [
-    "Super Micro"
-]
-
-drivers = ('igb', 'ixgb', 'i40e')
-DBDF_PATTERN = '(.+):(.+):(.+)\\.(.?)$'
-
-nics = []
-pcis = []
-
-cpu = os.popen('cat /proc/cpuinfo  |grep "model name"|uniq |awk \'{print $7"-"$8}\'').read().strip()
-phy_cpu_cnt = os.popen('cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l').read().strip()
-baseBoard = os.popen('dmidecode |grep -A13 "Base Board Information$" |grep Product |awk -F":" \'{print $2}\'').read().strip()
-pci_key = baseBoard + " " + cpu + " x " + phy_cpu_cnt
-if PCIs.has_key(pci_key):
-    pcis = PCIs[pci_key]
-
-#first , loop for dirvers and pick the onboard nics according to the PCI info
-for driver in drivers:
-    path = "/sys/module/%s/drivers" % driver
-    if os.access(path, os.R_OK) == False:
-        continue
-    files = os.listdir(path)
-    if len(files) != 1:
-        continue
-    path += '/' + files[0]
-    if os.access(path, os.R_OK) == False:
-        continue
-    for f in os.listdir(path):
-        res = re.search(DBDF_PATTERN, f)
-        if res == None:
-            continue
-        net_dir =  path + "/" + f + "/net"
-        if os.access(net_dir, os.R_OK) == False:
-            continue
-        phy_names = os.listdir(net_dir)
-        if not len(phy_names):
-            continue
-
-        if not f[-7:] in pcis:
-            continue
-        nics.append(phy_names[0])
-    if len(pcis) and len(pcis) != len(nics):
-        #maybe the pci info change
-        nics = []
-
-#second, if do not get nics, loop for drivers and pick the onboard nics according to the device id
-#get the device id from '/sys/module/igb/drivers/pci:igb/0000:02:00.0/device'
-if not len(nics):
-    for driver in drivers:
-        path = "/sys/module/%s/drivers" % driver
-        if os.access(path, os.R_OK) == False:
-            continue
-        files = os.listdir(path)
-        if len(files) != 1:
-            continue
-        path += '/' + files[0]
-        if os.access(path, os.R_OK) == False:
-            continue
-        for f in os.listdir(path):
-            res = re.search(DBDF_PATTERN, f)
-            if res == None:
-                continue
-            net_dir =  path + "/" + f + "/net"
-            if os.access(net_dir, os.R_OK) == False:
-                continue
-            phy_names = os.listdir(net_dir)
-            if not len(phy_names):
-                continue
-            #use device id to get nic
-            device_file = path + "/" + f + "/device"
-            if os.access(device_file, os.R_OK) == False:
-                continue
-            with open(device_file) as fo:
-                if not fo.read().strip() in devices:
-                    continue
-
-            nics.append(phy_names[0])
-
-#third, if do not get nics, loop for dirvers and pick the onboard nics according the vendors
-#for example , use lspci to get the below info
-#>>>lspci -mm -s 02:00.0
-#   02:00.0 "Ethernet controller" "Intel Corporation" "I350 Gigabit Network Connection" -r01 "Super Micro Computer Inc" "Device 1521"
-#we check the vendor info after '-r01'
-if not len(nics):
-    for driver in drivers:
-        path = "/sys/module/%s/drivers" % driver
-        if os.access(path, os.R_OK) == False:
-            continue
-        files = os.listdir(path)
-        if len(files) != 1:
-            continue
-        path += '/' + files[0]
-        if os.access(path, os.R_OK) == False:
-            continue
-        for f in os.listdir(path):
-            res = re.search(DBDF_PATTERN, f)
-            if res == None:
-                continue
-            net_dir =  path + "/" + f + "/net"
-            if os.access(net_dir, os.R_OK) == False:
-                continue
-            phy_names = os.listdir(net_dir)
-            if not len(phy_names):
-                continue
-
-            #use vendors to get nic
-            vendor = os.popen('lspci -mm -s %s|awk -F"\\"" \'{print $8}\'' % f[-7:]).read().strip()
-            if not vendor in vendors:
-                continue
-            nics.append(phy_names[0])
-nics = sorted(nics)
-print json.dumps(nics, ensure_ascii=True, indent=2, separators=(',', ': '))
+import json
+import os
+import re
+#  model     baseboard     cpu            cpu num(physical)
+#  10650     X9DR3-F       E5-2690-v2      2
+#  7600      X10DRi        E5-2620-v3      2
+#  3600v5    X11SSi-LN4F   E3-1240-v5      1
+#  5800      X11SSi-LN4F   E3-1240-v6      1
+#  7800      X11DPi-N      5115-CPU        1
+#  9800      X11DPi-N      5115-CPU        2
+#  5900      CB-1924       4210R-CPU       1
+#  7900      CB-1920       4215-CPU        2
+#  9900      CB-1920       6226R-CPU       2
+
+## Caswell Models ##
+#  model     baseboard          cpu            cpu num(physical)
+#  7900      CAPB-5070NR-8000   6526Y           2
+#  9900      CAPB-5070NR-8000   5515+           2
+
+def get_model():
+    model = 'default'
+    with open('/var/array/public/config/arraymodel', 'r') as f:
+        model = f.read().strip('\n')
+    return model
+
+#PCI dictionary use 'baseboard info + cpu info + physical cpu count' as the key
+PCIs = {
+    "X10DRi E5-2620-v3 x 2": [
+        "0b:00.0", 
+        "0b:00.1"
+    ],
+
+    "X11SSi-LN4F E3-1240-v5 x 1": [
+        "0d:00.0", 
+        "0e:00.0", 
+        "0f:00.0", 
+        "10:00.0"
+    ],
+
+    "X9DR3-F E5-2690-v2 x 2": [
+        "02:00.0", 
+        "02:00.1"
+    ],
+    
+    "X11SSi-LN4F E3-1240-v6 x 1": [
+        [
+            "08:00.0",
+            "09:00.0",
+            "0a:00.0",
+            "0b:00.0"
+        ],
+        [
+            "09:00.0",
+            "0a:00.0",
+            "0b:00.0",
+            "0c:00.0"
+        ]
+    ],
+
+    "X11DPi-N 5115-CPU x 1": [
+        "b5:00.0",
+        "b5:00.1"
+    ],
+
+    "X11DPi-N 5115-CPU x 2": [
+        "60:00.0",
+        "60:00.1"
+    ],
+
+    "CB-1924 4210R-CPU x 1": [
+        "02:00.0"
+    ],
+
+    "CB-1920 4215-CPU x 2": [
+        "03:00.0"
+    ],
+
+    "CB-1920 6226R-CPU x 2": [
+        "03:00.0"
+    ],
+    "CAPB-5070NR-8000 6526Y x 2": [
+        "01:00.0",
+        "04:00.0"
+    ],
+    "CAPB-5070NR-8000 5515+ x 2": [
+        "01:00.0",
+        "04:00.0"
+    ]
+}
+
+#  mode        onboard nic deviceid
+#  10650       0x1521
+#  7600        0x1521
+#  3600 v5     0x1533
+#  5800        0x1533
+#  7800        0x37d1
+#  9800        0x37d1
+#  5900        0x1533
+#  7900        0x1533
+#  9900        0x1533
+devices = [
+    "0x1533", 
+    "0x37d1"
+]
+
+
+model = get_model()
+if model != '955800' and model != '956850' and model != '900610':
+    devices.append("0x1521")
+
+vendors = [
+    "Super Micro"
+]
+
+drivers = ('igb', 'ixgb', 'i40e')
+DBDF_PATTERN = '(.+):(.+):(.+)\\.(.?)$'
+
+nics = []
+pcis = []
+
+if model == '957902' or model == '959902':
+    cpu = os.popen('cat /proc/cpuinfo  |grep "model name"|uniq |awk \'{print $7}\'').read().strip()
+else:
+    cpu = os.popen('cat /proc/cpuinfo  |grep "model name"|uniq |awk \'{print $7"-"$8}\'').read().strip()
+phy_cpu_cnt = os.popen('cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l').read().strip()
+baseBoard = os.popen('dmidecode |grep -A13 "Base Board Information$" |grep Product |awk -F":" \'{print $2}\'').read().strip()
+pci_key = baseBoard + " " + cpu + " x " + phy_cpu_cnt
+if PCIs.has_key(pci_key):
+    pcis = PCIs[pci_key]
+
+#first , loop for dirvers and pick the onboard nics according to the PCI info
+for driver in drivers:
+    path = "/sys/module/%s/drivers" % driver
+    if os.access(path, os.R_OK) == False:
+        continue
+    files = os.listdir(path)
+    if len(files) != 1:
+        continue
+    path += '/' + files[0]
+    if os.access(path, os.R_OK) == False:
+        continue
+    for f in os.listdir(path):
+        res = re.search(DBDF_PATTERN, f)
+        if res == None:
+            continue
+        net_dir =  path + "/" + f + "/net"
+        if os.access(net_dir, os.R_OK) == False:
+            continue
+        phy_names = os.listdir(net_dir)
+        if not len(phy_names):
+            continue
+
+        if not f[-7:] in pcis:
+            continue
+        nics.append(phy_names[0])
+    if len(pcis) and len(pcis) != len(nics):
+        #maybe the pci info change
+        nics = []
+
+#second, if do not get nics, loop for drivers and pick the onboard nics according to the device id
+#get the device id from '/sys/module/igb/drivers/pci:igb/0000:02:00.0/device'
+if not len(nics):
+    for driver in drivers:
+        path = "/sys/module/%s/drivers" % driver
+        if os.access(path, os.R_OK) == False:
+            continue
+        files = os.listdir(path)
+        if len(files) != 1:
+            continue
+        path += '/' + files[0]
+        if os.access(path, os.R_OK) == False:
+            continue
+        for f in os.listdir(path):
+            res = re.search(DBDF_PATTERN, f)
+            if res == None:
+                continue
+            net_dir =  path + "/" + f + "/net"
+            if os.access(net_dir, os.R_OK) == False:
+                continue
+            phy_names = os.listdir(net_dir)
+            if not len(phy_names):
+                continue
+            #use device id to get nic
+            device_file = path + "/" + f + "/device"
+            if os.access(device_file, os.R_OK) == False:
+                continue
+            with open(device_file) as fo:
+                if not fo.read().strip() in devices:
+                    continue
+
+            nics.append(phy_names[0])
+
+#third, if do not get nics, loop for dirvers and pick the onboard nics according the vendors
+#for example , use lspci to get the below info
+#>>>lspci -mm -s 02:00.0
+#   02:00.0 "Ethernet controller" "Intel Corporation" "I350 Gigabit Network Connection" -r01 "Super Micro Computer Inc" "Device 1521"
+#we check the vendor info after '-r01'
+if not len(nics):
+    for driver in drivers:
+        path = "/sys/module/%s/drivers" % driver
+        if os.access(path, os.R_OK) == False:
+            continue
+        files = os.listdir(path)
+        if len(files) != 1:
+            continue
+        path += '/' + files[0]
+        if os.access(path, os.R_OK) == False:
+            continue
+        for f in os.listdir(path):
+            res = re.search(DBDF_PATTERN, f)
+            if res == None:
+                continue
+            net_dir =  path + "/" + f + "/net"
+            if os.access(net_dir, os.R_OK) == False:
+                continue
+            phy_names = os.listdir(net_dir)
+            if not len(phy_names):
+                continue
+
+            #use vendors to get nic
+            vendor = os.popen('lspci -mm -s %s|awk -F"\\"" \'{print $8}\'' % f[-7:]).read().strip()
+            if not vendor in vendors:
+                continue
+            nics.append(phy_names[0])
+nics = sorted(nics)
+print json.dumps(nics, ensure_ascii=True, indent=2, separators=(',', ': '))
Index: src/library/avxvainst/va_resource.c
===================================================================
--- src/library/avxvainst/va_resource.c	(revision 9208)
+++ src/library/avxvainst/va_resource.c	(working copy)
@@ -96,7 +96,7 @@
 };
 
 struct array_nic {
-    char device[16];
+    char device[32];
     char info[32];
     int numG;
 }supported_nics[] = {
@@ -121,34 +121,39 @@
         .numG = 40,
     },
     {
+        .device = "0x8086-0x37d0",
+        .info = "Intel X722 10GbE SFP+",
+        .numG = 10,
+    },
+    {
         .device = "0x8086-0x37d1",
-        .info = "Intel XL722 1G",
+        .info = "Intel X722 1GbE",
         .numG = 1,
     },
     {
         .device = "0x8086-0x37d3",
-        .info = "Intel XL722 10GbE SFP+",
+        .info = "Intel X722 10GbE SFP+",
         .numG = 10,
     },
     {
         .device = "0x8086-0x150e",
         .info = "Intel 82580 1G Copper",
-        .numG = 1,        
+        .numG = 1,
     },
     {
         .device = "0x8086-0x150f",
         .info = "Intel 82580 1G Fiber",
-        .numG = 1,        
+        .numG = 1,
     },
     {
         .device = "0x8086-0x1521",
         .info = "Intel I350 1G Copper",
-        .numG = 1,        
+        .numG = 1,
     },
     {
         .device = "0x8086-0x1522",
         .info = "Intel I350 1G Fiber",
-        .numG = 1,        
+        .numG = 1,
     },
     {
         .device = "0x8086-0x1539",
@@ -158,22 +163,27 @@
     {
         .device = "0x8086-0x1533",
         .info = "Intel I210 1G Copper",
-        .numG = 1,       
+        .numG = 1,
     },
     {
         .device = "0x8086-0x158b",
         .info = "Intel XXV710 25G SFP28",
-        .numG = 25,       
+        .numG = 25,
     },
     {
-        .device = "0x8086-0x1593",
+        .device = "0x8086-0x1593-0x8086",
+        .info = "Intel E810-C 10G SFP",
+        .numG = 10,
+    },
+    {
+        .device = "0x8086-0x1593-0x1e97",
         .info = "Intel E810-C 25G SFP",
-        .numG = 25,       
+        .numG = 25,
     },
     {
         .device = "0x8086-0x1592",
         .info = "Intel E810-C 100G QSFP",
-        .numG = 100,       
+        .numG = 100,
     }
 };
 
@@ -2291,8 +2301,14 @@
         bzero(new_name, sizeof(new_name));
         snprintf(name, sizeof(name), "enp%ds%df%d",
             nic_vf_numa[p_num - 1].bus, nic_vf_numa[p_num - 1].dev, nic_vf_numa[p_num - 1].func);
-        
-        snprintf(array_nic_name, sizeof(array_nic_name), "0x%4x-0x%4x", nic_vf_numa[p_num - 1].vendorid, nic_vf_numa[p_num - 1].deviceid);
+
+        if (nic_vf_numa[p_num - 1].vendorid == 0x8086 && nic_vf_numa[p_num - 1].deviceid == 0x1593) {
+            snprintf(array_nic_name, sizeof(array_nic_name), "0x%4x-0x%4x-0x%4x",
+             nic_vf_numa[p_num - 1].vendorid, nic_vf_numa[p_num - 1].deviceid, nic_vf_numa[p_num - 1].subsystem_vendorid);
+        } else {
+            snprintf(array_nic_name, sizeof(array_nic_name), "0x%4x-0x%4x",
+             nic_vf_numa[p_num - 1].vendorid, nic_vf_numa[p_num - 1].deviceid);
+        }
         numG = get_bw_of_interface(array_nic_name);
         if(numG == 1) {
             snprintf(new_name, sizeof(new_name), "port%d", p_num);
