vxge_main.c

Go to the documentation of this file.
00001 /*
00002  * vxge-main.c: gPXE driver for Neterion Inc's X3100 Series 10GbE
00003  *              PCIe I/O Virtualized Server Adapter.
00004  *
00005  * Copyright(c) 2002-2010 Neterion Inc.
00006  *
00007  * This software may be used and distributed according to the terms of
00008  * the GNU General Public License (GPL), incorporated herein by
00009  * reference.  Drivers based on or derived from this code fall under
00010  * the GPL and must retain the authorship, copyright and license
00011  * notice.
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 /* function modes strings */
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  * vxge_xmit_compl
00057  *
00058  * If an interrupt was raised to indicate DMA complete of the Tx packet,
00059  * this function is called. It identifies the last TxD whose buffer was
00060  * freed and frees all skbs whose data have already DMA'ed into the NICs
00061  * internal memory.
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 /* reset vpaths */
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 /* close vpaths */
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 /* open vpaths */
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 /** Functions that implement the gPXE driver API **/
00169 
00170 /**
00171  * vxge_xmit
00172  * @skb : the socket buffer containing the Tx data.
00173  * @dev : device pointer.
00174  *
00175  * This function is the Tx entry point of the driver. Neterion NIC supports
00176  * certain protocol assist features on Tx side, namely  CSO, S/G, LSO.
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  *  vxge_poll
00226  *  @ndev: net device pointer
00227  *
00228  *  This function acks the interrupt. It polls for rx packets
00229  *  and send to upper layer. It also checks for tx completion
00230  *  and frees iobs.
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         /* process alarm and acknowledge the interrupts */
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  * vxge_irq - enable or Disable interrupts
00255  *
00256  * @netdev   netdevice sturcture reference
00257  * @action   requested interrupt action
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  * vxge_open
00282  * @dev: pointer to the device structure.
00283  *
00284  * This function is the open entry point of the driver. It mainly calls a
00285  * function to allocate Rx buffers and inserts them into the buffer
00286  * descriptors and then enables the Rx part of the NIC.
00287  * Return value: '0' on success and an appropriate (-)ve integer as
00288  * defined in errno.h file on failure.
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         /* make sure you have link off by default every time Nic is
00305          * initialized */
00306         netdev_link_down(dev);
00307 
00308         /* Open VPATHs */
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         /* set initial mtu before enabling the device */
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  * vxge_close
00356  * @dev: device pointer.
00357  *
00358  * This is the stop entry point of the driver. It needs to undo exactly
00359  * whatever was done by the open entry point, thus it's usually referred to
00360  * as the close function.Among other things this function mainly stops the
00361  * Rx side of the NIC and frees all the Rx buffers in the Rx rings.
00362  * Return value: '0' on success and an appropriate (-)ve integer as
00363  * defined in errno.h file on failure.
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         /* Note that at this point xmit() is stopped by upper layer */
00387         vxge_hw_device_intr_disable(hldev);
00388 
00389         /* Multi function shares INTA, hence we should
00390          * leave it in enabled state
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         /* Associate vxge-specific network operations operations with
00433          * generic network device layer */
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         /* Make Link state as off at this point, when the Link change
00447          * interrupt comes the state will be automatically changed to
00448          * the right state.
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  * vxge_device_unregister
00466  *
00467  * This function will unregister and free network device
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  * vxge_probe
00488  * @pdev : structure containing the PCI related information of the device.
00489  * @id: List of PCI devices supported by the driver listed in vxge_id_table.
00490  * Description:
00491  * This function is called when a new PCI device gets detected and initializes
00492  * it.
00493  * Return value:
00494  * returns 0 on success and negative on failure.
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         /* sets the bus master */
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                 /* Non zero function, So do not load the driver */
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         /* fail the driver loading if firmware is incompatible */
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         /* find the vpath id of the first available one */
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         /* if FCS stripping is not disabled in MAC fail driver load */
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         /* Read function mode */
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         /* set private device info */
00616         pci_set_drvdata(pdev, hldev);
00617 
00618         if (vxge_device_register(hldev, &vdev)) {
00619                 ret = -EINVAL;
00620                 goto _exit2;
00621         }
00622 
00623         /* set private HW device info */
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         /* Virtual Path count */
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  * vxge_remove - Free the PCI device
00675  * @pdev: structure containing the PCI related information of the device.
00676  * Description: This function is called by the Pci subsystem to release a
00677  * PCI device and free up all resource held up by the device.
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 /* vxge net device operations */
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         /* If you change this, also adjust vxge_nics[] in vxge.c */
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 };

Generated on Tue Apr 6 20:01:05 2010 for gPXE by  doxygen 1.5.7.1