00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 FILE_LICENCE(GPL2_ONLY);
00016
00017 #include <stdlib.h>
00018 #include <stdio.h>
00019 #include <string.h>
00020 #include <gpxe/io.h>
00021 #include <errno.h>
00022 #include <byteswap.h>
00023 #include <gpxe/pci.h>
00024 #include <gpxe/malloc.h>
00025 #include <gpxe/if_ether.h>
00026 #include <gpxe/ethernet.h>
00027 #include <gpxe/iobuf.h>
00028 #include <gpxe/netdevice.h>
00029 #include <gpxe/timer.h>
00030 #include <nic.h>
00031
00032 #include "vxge_main.h"
00033 #include "vxge_reg.h"
00034
00035
00036 static char *vxge_func_mode_names[] = {
00037 "Single Function - 1 func, 17 vpath",
00038 "Multi Function 8 - 8 func, 2 vpath per func",
00039 "SRIOV 17 - 17 VF, 1 vpath per VF",
00040 "WLPEX/SharedIO 17 - 17 VH, 1 vpath/func/hierarchy",
00041 "WLPEX/SharedIO 8 - 8 VH, 2 vpath/func/hierarchy",
00042 "Multi Function 17 - 17 func, 1 vpath per func",
00043 "SRIOV 8 - 1 PF, 7 VF, 2 vpath per VF",
00044 "SRIOV 4 - 1 PF, 3 VF, 4 vpath per VF",
00045 "Multi Function 2 - 2 func, 8 vpath per func",
00046 "Multi Function 4 - 4 func, 4 vpath per func",
00047 "WLPEX/SharedIO 4 - 17 func, 1 vpath per func (PCIe ARI)",
00048 };
00049
00050 static inline int is_vxge_card_up(struct vxgedev *vdev)
00051 {
00052 return test_bit(__VXGE_STATE_CARD_UP, vdev->state);
00053 }
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 enum vxge_hw_status
00064 vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw,
00065 struct vxge_hw_fifo_txd *txdp, enum vxge_hw_fifo_tcode tcode)
00066 {
00067 struct net_device *netdev;
00068 struct io_buffer *tx_iob = NULL;
00069
00070 vxge_trace();
00071
00072 netdev = fifo_hw->vpathh->hldev->ndev;
00073
00074 tx_iob = (struct io_buffer *)(intptr_t)txdp->host_control;
00075
00076 if (tcode == VXGE_HW_FIFO_T_CODE_OK) {
00077 netdev_tx_complete(netdev, tx_iob);
00078 } else {
00079 netdev_tx_complete_err(netdev, tx_iob, -EINVAL);
00080 vxge_debug(VXGE_ERR, "%s: transmit failed, tcode %d\n",
00081 netdev->name, tcode);
00082 }
00083
00084 memset(txdp, 0, sizeof(struct vxge_hw_fifo_txd));
00085
00086 return VXGE_HW_OK;
00087 }
00088
00089
00090 enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev)
00091 {
00092 enum vxge_hw_status status = VXGE_HW_OK;
00093 struct __vxge_hw_virtualpath *vpath;
00094
00095 vxge_trace();
00096
00097 vpath = vdev->vpath.vpathh;
00098
00099 if (vpath) {
00100 if ((status = vxge_hw_vpath_reset(vpath)) == VXGE_HW_OK) {
00101 if (is_vxge_card_up(vdev) &&
00102 (status = vxge_hw_vpath_recover_from_reset(
00103 vpath)) != VXGE_HW_OK) {
00104 vxge_debug(VXGE_ERR, "vxge_hw_vpath_recover_"
00105 "from_reset failed\n");
00106 return status;
00107 } else {
00108 status = __vxge_hw_vpath_reset_check(vpath);
00109 if (status != VXGE_HW_OK) {
00110 vxge_debug(VXGE_ERR,
00111 "__vxge_hw_vpath_reset_check error\n");
00112 return status;
00113 }
00114 }
00115 } else {
00116 vxge_debug(VXGE_ERR, "vxge_hw_vpath_reset failed\n");
00117 return status;
00118 }
00119 }
00120 return status;
00121 }
00122
00123
00124 void vxge_close_vpaths(struct vxgedev *vdev)
00125 {
00126
00127 if (vdev->vpath.vpathh && vdev->vpath.is_open)
00128 vxge_hw_vpath_close(vdev->vpath.vpathh);
00129
00130 vdev->vpath.is_open = 0;
00131 vdev->vpath.vpathh = NULL;
00132 }
00133
00134
00135 int vxge_open_vpaths(struct vxgedev *vdev)
00136 {
00137 enum vxge_hw_status status;
00138 struct __vxge_hw_device *hldev;
00139
00140 hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev);
00141
00142 vdev->vpath.vpathh = &hldev->virtual_path;
00143 vdev->vpath.fifo.ndev = vdev->ndev;
00144 vdev->vpath.fifo.pdev = vdev->pdev;
00145 vdev->vpath.fifo.fifoh = &hldev->virtual_path.fifoh;
00146 vdev->vpath.ring.ndev = vdev->ndev;
00147 vdev->vpath.ring.pdev = vdev->pdev;
00148 vdev->vpath.ring.ringh = &hldev->virtual_path.ringh;
00149
00150 status = vxge_hw_vpath_open(vdev->devh, &vdev->vpath);
00151 if (status == VXGE_HW_OK) {
00152 vdev->vpath.is_open = 1;
00153 } else {
00154 vxge_debug(VXGE_ERR,
00155 "%s: vpath: %d failed to open "
00156 "with status: %d\n",
00157 vdev->ndev->name, vdev->vpath.device_id,
00158 status);
00159 vxge_close_vpaths(vdev);
00160 return status;
00161 }
00162
00163 hldev->vpaths_deployed |= vxge_mBIT(vdev->vpath.vpathh->vp_id);
00164
00165 return VXGE_HW_OK;
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 static int
00179 vxge_xmit(struct net_device *dev, struct io_buffer *iobuf)
00180 {
00181 struct vxge_fifo *fifo = NULL;
00182 struct vxgedev *vdev = NULL;
00183 struct __vxge_hw_fifo *fifoh;
00184 struct __vxge_hw_device *hldev;
00185 struct vxge_hw_fifo_txd *txdp;
00186
00187 vxge_trace();
00188
00189 vdev = (struct vxgedev *)netdev_priv(dev);
00190 hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev);
00191
00192 if (!is_vxge_card_up(vdev)) {
00193 vxge_debug(VXGE_ERR,
00194 "%s: vdev not initialized\n", dev->name);
00195 return -EIO;
00196 }
00197
00198 if (!netdev_link_ok(dev)) {
00199 vxge_debug(VXGE_ERR,
00200 "%s: Link down, transmit failed\n", dev->name);
00201 return -ENETDOWN;
00202 }
00203
00204 fifo = &vdev->vpath.fifo;
00205 fifoh = fifo->fifoh;
00206
00207 txdp = vxge_hw_fifo_free_txdl_get(fifoh);
00208 if (!txdp) {
00209 vxge_debug(VXGE_ERR,
00210 "%s: Out of tx descriptors\n", dev->name);
00211 return -ENOBUFS;
00212 }
00213
00214 vxge_debug(VXGE_XMIT, "%s: %s:%d fifoh offset= %d\n",
00215 dev->name, __func__, __LINE__, fifoh->sw_offset);
00216
00217 vxge_hw_fifo_txdl_buffer_set(fifoh, txdp, iobuf);
00218
00219 vxge_hw_fifo_txdl_post(fifoh, txdp);
00220
00221 return 0;
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 static void vxge_poll(struct net_device *ndev)
00233 {
00234 struct __vxge_hw_device *hldev;
00235 struct vxgedev *vdev;
00236
00237 vxge_debug(VXGE_POLL, "%s:%d \n", __func__, __LINE__);
00238
00239 vdev = (struct vxgedev *)netdev_priv(ndev);
00240 hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev);
00241
00242 if (!is_vxge_card_up(vdev))
00243 return;
00244
00245
00246 vxge_hw_device_begin_irq(hldev);
00247
00248 vxge_hw_vpath_poll_tx(&hldev->virtual_path.fifoh);
00249
00250 vxge_hw_vpath_poll_rx(&hldev->virtual_path.ringh);
00251 }
00252
00253
00254
00255
00256
00257
00258
00259 static void vxge_irq(struct net_device *netdev __unused, int action)
00260 {
00261 struct __vxge_hw_device *hldev;
00262 struct vxgedev *vdev;
00263
00264 vxge_debug(VXGE_INFO,
00265 "%s:%d action(%d)\n", __func__, __LINE__, action);
00266
00267 vdev = (struct vxgedev *)netdev_priv(netdev);
00268 hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev);
00269
00270 switch (action) {
00271 case DISABLE:
00272 vxge_hw_device_mask_all(hldev);
00273 break;
00274 default:
00275 vxge_hw_device_unmask_all(hldev);
00276 break;
00277 }
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 int
00291 vxge_open(struct net_device *dev)
00292 {
00293 enum vxge_hw_status status;
00294 struct vxgedev *vdev;
00295 struct __vxge_hw_device *hldev;
00296 int ret = 0;
00297
00298 vxge_debug(VXGE_INFO, "%s: %s:%d\n",
00299 VXGE_DRIVER_NAME, __func__, __LINE__);
00300
00301 vdev = (struct vxgedev *)netdev_priv(dev);
00302 hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev);
00303
00304
00305
00306 netdev_link_down(dev);
00307
00308
00309 status = vxge_open_vpaths(vdev);
00310 if (status != VXGE_HW_OK) {
00311 vxge_debug(VXGE_ERR, "%s: fatal: Vpath open failed\n",
00312 VXGE_DRIVER_NAME);
00313 ret = -EPERM;
00314 goto out0;
00315 }
00316
00317 vdev->mtu = VXGE_HW_DEFAULT_MTU;
00318
00319 status = vxge_hw_vpath_mtu_set(vdev->vpath.vpathh, vdev->mtu);
00320 if (status != VXGE_HW_OK) {
00321 vxge_debug(VXGE_ERR,
00322 "%s: fatal: can not set new MTU\n", dev->name);
00323 ret = -EPERM;
00324 goto out2;
00325 }
00326 vxge_debug(VXGE_INFO,
00327 "%s: MTU is %d\n", vdev->ndev->name, vdev->mtu);
00328
00329 set_bit(__VXGE_STATE_CARD_UP, vdev->state);
00330
00331 wmb();
00332
00333 if (vxge_hw_device_link_state_get(vdev->devh) == VXGE_HW_LINK_UP) {
00334 netdev_link_up(vdev->ndev);
00335 vxge_debug(VXGE_INFO, "%s: Link Up\n", vdev->ndev->name);
00336 }
00337
00338 vxge_hw_device_intr_enable(hldev);
00339
00340 vxge_hw_vpath_enable(vdev->vpath.vpathh);
00341 wmb();
00342 vxge_hw_vpath_rx_doorbell_init(vdev->vpath.vpathh);
00343
00344 goto out0;
00345
00346 out2:
00347 vxge_close_vpaths(vdev);
00348 out0:
00349 vxge_debug(VXGE_INFO, "%s: %s:%d Exiting...\n",
00350 dev->name, __func__, __LINE__);
00351 return ret;
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 static void vxge_close(struct net_device *dev)
00366 {
00367 struct vxgedev *vdev;
00368 struct __vxge_hw_device *hldev;
00369
00370 vxge_debug(VXGE_INFO, "%s: %s:%d\n",
00371 dev->name, __func__, __LINE__);
00372
00373 vdev = (struct vxgedev *)netdev_priv(dev);
00374 hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev);
00375
00376 if (!is_vxge_card_up(vdev))
00377 return;
00378
00379 clear_bit(__VXGE_STATE_CARD_UP, vdev->state);
00380
00381 vxge_hw_vpath_set_zero_rx_frm_len(hldev);
00382
00383 netdev_link_down(vdev->ndev);
00384 vxge_debug(VXGE_INFO, "%s: Link Down\n", vdev->ndev->name);
00385
00386
00387 vxge_hw_device_intr_disable(hldev);
00388
00389
00390
00391
00392 if (is_mf(hldev->hw_info.function_mode))
00393 vxge_hw_device_unmask_all(hldev);
00394
00395 vxge_reset_all_vpaths(vdev);
00396
00397 vxge_close_vpaths(vdev);
00398
00399 vxge_debug(VXGE_INFO,
00400 "%s: %s:%d Exiting...\n", dev->name, __func__, __LINE__);
00401 }
00402
00403 static struct net_device_operations vxge_operations;
00404
00405 int vxge_device_register(struct __vxge_hw_device *hldev,
00406 struct vxgedev **vdev_out)
00407 {
00408 struct net_device *ndev;
00409 struct vxgedev *vdev;
00410 int ret = 0;
00411
00412 *vdev_out = NULL;
00413
00414 ndev = alloc_etherdev(sizeof(struct vxgedev));
00415 if (ndev == NULL) {
00416 vxge_debug(VXGE_ERR, "%s : device allocation failed\n",
00417 __func__);
00418 ret = -ENODEV;
00419 goto _out0;
00420 }
00421
00422 vxge_debug(VXGE_INFO, "%s:%d netdev registering\n",
00423 __func__, __LINE__);
00424 vdev = netdev_priv(ndev);
00425 memset(vdev, 0, sizeof(struct vxgedev));
00426
00427 vdev->ndev = ndev;
00428 vdev->devh = hldev;
00429 vdev->pdev = hldev->pdev;
00430
00431 ndev->dev = &vdev->pdev->dev;
00432
00433
00434 netdev_init(ndev, &vxge_operations);
00435
00436 memcpy(ndev->hw_addr,
00437 (u8 *)hldev->hw_info.mac_addrs[hldev->first_vp_id], ETH_ALEN);
00438
00439 if (register_netdev(ndev)) {
00440 vxge_debug(VXGE_ERR, "%s : device registration failed!\n",
00441 __func__);
00442 ret = -ENODEV;
00443 goto _out2;
00444 }
00445
00446
00447
00448
00449
00450 netdev_link_down(ndev);
00451
00452 vxge_debug(VXGE_INFO, "%s: Ethernet device registered\n",
00453 VXGE_DRIVER_NAME);
00454
00455 *vdev_out = vdev;
00456
00457 return ret;
00458 _out2:
00459 netdev_put(ndev);
00460 _out0:
00461 return ret;
00462 }
00463
00464
00465
00466
00467
00468
00469 void
00470 vxge_device_unregister(struct __vxge_hw_device *hldev)
00471 {
00472 struct vxgedev *vdev;
00473 struct net_device *ndev;
00474
00475 ndev = hldev->ndev;
00476 vdev = netdev_priv(ndev);
00477
00478 unregister_netdev(ndev);
00479 netdev_nullify(ndev);
00480 netdev_put(ndev);
00481
00482 vxge_debug(VXGE_INFO, "%s: ethernet device unregistered\n",
00483 VXGE_DRIVER_NAME);
00484 }
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 static int
00498 vxge_probe(struct pci_device *pdev, const struct pci_device_id *id __unused)
00499 {
00500 struct __vxge_hw_device *hldev;
00501 enum vxge_hw_status status;
00502 int ret = 0;
00503 u64 vpath_mask = 0;
00504 struct vxgedev *vdev;
00505 int i;
00506 u8 revision, titan1;
00507 u32 host_type;
00508 u32 function_mode;
00509 unsigned long mmio_start, mmio_len;
00510 void *bar0;
00511 struct vxge_hw_device_hw_info hw_info;
00512 struct vxge_hw_device_version *fw_version;
00513
00514 vxge_debug(VXGE_INFO, "vxge_probe for device %02X:%02X.%X\n",
00515 pdev->bus, PCI_SLOT(pdev->devfn),
00516 PCI_FUNC(pdev->devfn));
00517
00518 pci_read_config_byte(pdev, PCI_REVISION_ID, &revision);
00519 titan1 = is_titan1(pdev->device, revision);
00520
00521 mmio_start = pci_bar_start(pdev, PCI_BASE_ADDRESS_0);
00522 mmio_len = pci_bar_size(pdev, PCI_BASE_ADDRESS_0);
00523 vxge_debug(VXGE_INFO, "mmio_start: %#08lx, mmio_len: %#08lx\n",
00524 mmio_start, mmio_len);
00525
00526
00527 adjust_pci_device(pdev);
00528
00529 bar0 = ioremap(mmio_start, mmio_len);
00530 if (!bar0) {
00531 vxge_debug(VXGE_ERR,
00532 "%s : cannot remap io memory bar0\n", __func__);
00533 ret = -ENODEV;
00534 goto _exit0;
00535 }
00536
00537 status = vxge_hw_device_hw_info_get(bar0, &hw_info);
00538 if (status != VXGE_HW_OK) {
00539 vxge_debug(VXGE_ERR,
00540 "%s: Reading of hardware info failed.\n",
00541 VXGE_DRIVER_NAME);
00542 ret = -EINVAL;
00543 goto _exit1;
00544 }
00545
00546 if (hw_info.func_id != 0) {
00547
00548 iounmap(bar0);
00549 pci_set_drvdata(pdev, NULL);
00550 return -EINVAL;
00551 }
00552
00553
00554 vpath_mask = hw_info.vpath_mask;
00555 if (vpath_mask == 0) {
00556 vxge_debug(VXGE_ERR,
00557 "%s: No vpaths available in device\n",
00558 VXGE_DRIVER_NAME);
00559 ret = -EINVAL;
00560 goto _exit1;
00561 }
00562 vxge_debug(VXGE_INFO,
00563 "%s:%d Vpath mask = %llx\n", __func__, __LINE__,
00564 (unsigned long long)vpath_mask);
00565
00566 host_type = hw_info.host_type;
00567 fw_version = &hw_info.fw_version;
00568
00569 if ((fw_version->major != VXGE_CERT_FW_VER_MAJOR) ||
00570 (fw_version->minor < VXGE_CERT_FW_VER_MINOR)) {
00571 printf("%s: Adapter's current firmware version: %d.%d.%d\n",
00572 VXGE_DRIVER_NAME, fw_version->major,
00573 fw_version->minor, fw_version->build);
00574
00575 printf("%s: Upgrade firmware to version %d.%d.%d\n",
00576 VXGE_DRIVER_NAME, VXGE_CERT_FW_VER_MAJOR,
00577 VXGE_CERT_FW_VER_MINOR, VXGE_CERT_FW_VER_BUILD);
00578
00579 ret = -EACCES;
00580 goto _exit1;
00581 }
00582
00583 status = vxge_hw_device_initialize(&hldev, bar0, pdev, titan1);
00584 if (status != VXGE_HW_OK) {
00585 vxge_debug(VXGE_ERR,
00586 "Failed to initialize device (%d)\n", status);
00587 ret = -EINVAL;
00588 goto _exit1;
00589 }
00590 memcpy(&hldev->hw_info, &hw_info,
00591 sizeof(struct vxge_hw_device_hw_info));
00592
00593
00594 for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++)
00595 if (vpath_mask & vxge_mBIT(i)) {
00596 hldev->first_vp_id = i;
00597 break;
00598 }
00599
00600 if (vxge_hw_vpath_strip_fcs_check(hldev, vpath_mask) != VXGE_HW_OK) {
00601 vxge_debug(VXGE_ERR,
00602 "%s: FCS stripping is not disabled in MAC"
00603 " failing driver load\n", VXGE_DRIVER_NAME);
00604 ret = -EINVAL;
00605 goto _exit2;
00606 }
00607
00608
00609 status = vxge_hw_get_func_mode(hldev, &function_mode);
00610 if (status != VXGE_HW_OK)
00611 goto _exit2;
00612
00613 hldev->hw_info.function_mode = function_mode;
00614
00615
00616 pci_set_drvdata(pdev, hldev);
00617
00618 if (vxge_device_register(hldev, &vdev)) {
00619 ret = -EINVAL;
00620 goto _exit2;
00621 }
00622
00623
00624 hldev->ndev = vdev->ndev;
00625 hldev->vdev = vdev;
00626 hldev->pdev = pdev;
00627 vdev->mtu = VXGE_HW_DEFAULT_MTU;
00628 vdev->bar0 = bar0;
00629 vdev->titan1 = titan1;
00630
00631 vdev->vpath.device_id = hldev->first_vp_id;
00632 vdev->vpath.vdev = vdev;
00633 memcpy((u8 *)vdev->vpath.macaddr,
00634 (u8 *)hldev->hw_info.mac_addrs[hldev->first_vp_id],
00635 ETH_ALEN);
00636
00637 hldev->hw_info.serial_number[VXGE_HW_INFO_LEN - 1] = '\0';
00638 hldev->hw_info.product_desc[VXGE_HW_INFO_LEN - 1] = '\0';
00639 hldev->hw_info.part_number[VXGE_HW_INFO_LEN - 1] = '\0';
00640
00641 vxge_debug(VXGE_INFO, "%s: Neterion %s Server Adapter\n",
00642 VXGE_DRIVER_NAME, hldev->hw_info.product_desc);
00643 vxge_debug(VXGE_INFO, "%s: SERIAL NUMBER: %s\n",
00644 VXGE_DRIVER_NAME, hldev->hw_info.serial_number);
00645 vxge_debug(VXGE_INFO, "%s: PART NUMBER: %s\n",
00646 VXGE_DRIVER_NAME, hldev->hw_info.part_number);
00647 vxge_debug(VXGE_INFO, "%s: MAC ADDR: %s\n",
00648 VXGE_DRIVER_NAME, eth_ntoa(vdev->vpath.macaddr));
00649 vxge_debug(VXGE_INFO,
00650 "%s: Firmware version : %s Date : %s\n", VXGE_DRIVER_NAME,
00651 hldev->hw_info.fw_version.version,
00652 hldev->hw_info.fw_date.date);
00653 vxge_debug(VXGE_INFO, "%s: %s Enabled\n",
00654 VXGE_DRIVER_NAME, vxge_func_mode_names[function_mode]);
00655
00656 vxge_debug(VXGE_INFO, "%s: %s:%d Probe Exiting...\n",
00657 VXGE_DRIVER_NAME, __func__, __LINE__);
00658
00659 return 0;
00660
00661 _exit2:
00662 vxge_hw_device_terminate(hldev);
00663 _exit1:
00664 iounmap(bar0);
00665 _exit0:
00666 pci_set_drvdata(pdev, NULL);
00667 printf("%s: WARNING!! Driver loading failed!!\n",
00668 VXGE_DRIVER_NAME);
00669
00670 return ret;
00671 }
00672
00673
00674
00675
00676
00677
00678
00679 static void
00680 vxge_remove(struct pci_device *pdev)
00681 {
00682 struct __vxge_hw_device *hldev;
00683 struct vxgedev *vdev = NULL;
00684 struct net_device *ndev;
00685
00686 vxge_debug(VXGE_INFO,
00687 "%s:%d\n", __func__, __LINE__);
00688 hldev = (struct __vxge_hw_device *) pci_get_drvdata(pdev);
00689 if (hldev == NULL)
00690 return;
00691
00692 ndev = hldev->ndev;
00693 vdev = netdev_priv(ndev);
00694
00695 iounmap(vdev->bar0);
00696
00697 vxge_device_unregister(hldev);
00698
00699 vxge_debug(VXGE_INFO,
00700 "%s:%d Device unregistered\n", __func__, __LINE__);
00701
00702 vxge_hw_device_terminate(hldev);
00703 pci_set_drvdata(pdev, NULL);
00704 }
00705
00706
00707 static struct net_device_operations vxge_operations = {
00708 .open = vxge_open,
00709 .close = vxge_close,
00710 .transmit = vxge_xmit,
00711 .poll = vxge_poll,
00712 .irq = vxge_irq,
00713 };
00714
00715 static struct pci_device_id vxge_main_nics[] = {
00716
00717 PCI_ID(0x17d5, 0x5833, "vxge-x3100", "Neterion X3100 Series", 0),
00718 };
00719
00720 struct pci_driver vxge_driver __pci_driver = {
00721 .ids = vxge_main_nics,
00722 .id_count = (sizeof(vxge_main_nics) / sizeof(vxge_main_nics[0])),
00723 .probe = vxge_probe,
00724 .remove = vxge_remove,
00725 };