vxge_config.c

Go to the documentation of this file.
00001 /*
00002  * vxge-config.c: gPXE driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
00003  *              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 <gpxe/malloc.h>
00020 #include <gpxe/iobuf.h>
00021 #include <byteswap.h>
00022 
00023 #include "vxge_traffic.h"
00024 #include "vxge_config.h"
00025 #include "vxge_main.h"
00026 
00027 void
00028 vxge_hw_vpath_set_zero_rx_frm_len(struct __vxge_hw_device *hldev)
00029 {
00030         u64 val64;
00031         struct __vxge_hw_virtualpath *vpath;
00032         struct vxge_hw_vpath_reg __iomem *vp_reg;
00033 
00034         vpath = &hldev->virtual_path;
00035         vp_reg = vpath->vp_reg;
00036 
00037         val64 = readq(&vp_reg->rxmac_vcfg0);
00038         val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff);
00039         writeq(val64, &vp_reg->rxmac_vcfg0);
00040         val64 = readq(&vp_reg->rxmac_vcfg0);
00041         return;
00042 }
00043 
00044 enum vxge_hw_status
00045 vxge_hw_set_fw_api(struct __vxge_hw_device *hldev,
00046                 u64 vp_id,
00047                 u32 action,
00048                 u32 offset,
00049                 u64 data0,
00050                 u64 data1)
00051 {
00052         enum vxge_hw_status status = VXGE_HW_OK;
00053         u64 val64;
00054         u32 fw_memo = VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO;
00055 
00056         struct vxge_hw_vpath_reg __iomem *vp_reg;
00057 
00058         vp_reg = (struct vxge_hw_vpath_reg __iomem *)hldev->vpath_reg[vp_id];
00059 
00060         writeq(data0, &vp_reg->rts_access_steer_data0);
00061         writeq(data1, &vp_reg->rts_access_steer_data1);
00062 
00063         wmb();
00064 
00065         val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) |
00066                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(fw_memo) |
00067                 VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset) |
00068                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE;
00069 
00070         writeq(val64, &vp_reg->rts_access_steer_ctrl);
00071 
00072         wmb();
00073 
00074         status = __vxge_hw_device_register_poll(
00075                         &vp_reg->rts_access_steer_ctrl,
00076                         VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
00077                         WAIT_FACTOR *
00078                         VXGE_HW_DEF_DEVICE_POLL_MILLIS);
00079 
00080         if (status != VXGE_HW_OK)
00081                 return VXGE_HW_FAIL;
00082 
00083         val64 = readq(&vp_reg->rts_access_steer_ctrl);
00084 
00085         if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS)
00086                 status = VXGE_HW_OK;
00087         else
00088                 status = VXGE_HW_FAIL;
00089 
00090         return status;
00091 }
00092 
00093 /* Get function mode */
00094 enum vxge_hw_status
00095 vxge_hw_get_func_mode(struct __vxge_hw_device *hldev, u32 *func_mode)
00096 {
00097         enum vxge_hw_status status = VXGE_HW_OK;
00098         struct vxge_hw_vpath_reg __iomem *vp_reg;
00099         u64 val64;
00100         int vp_id;
00101 
00102         /* get the first vpath number assigned to this function */
00103         vp_id = hldev->first_vp_id;
00104 
00105         vp_reg = (struct vxge_hw_vpath_reg __iomem *)hldev->vpath_reg[vp_id];
00106 
00107         status = vxge_hw_set_fw_api(hldev, vp_id,
00108                                 VXGE_HW_FW_API_GET_FUNC_MODE, 0, 0, 0);
00109 
00110         if (status == VXGE_HW_OK) {
00111                 val64 = readq(&vp_reg->rts_access_steer_data0);
00112                 *func_mode = VXGE_HW_GET_FUNC_MODE_VAL(val64);
00113         }
00114 
00115         return status;
00116 }
00117 
00118 /*
00119  * __vxge_hw_device_pci_e_init
00120  * Initialize certain PCI/PCI-X configuration registers
00121  * with recommended values. Save config space for future hw resets.
00122  */
00123 void
00124 __vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev)
00125 {
00126         u16 cmd = 0;
00127         struct pci_device *pdev = hldev->pdev;
00128 
00129         vxge_trace();
00130 
00131         /* Set the PErr Repconse bit and SERR in PCI command register. */
00132         pci_read_config_word(pdev, PCI_COMMAND, &cmd);
00133         cmd |= 0x140;
00134         pci_write_config_word(pdev, PCI_COMMAND, cmd);
00135 
00136         return;
00137 }
00138 
00139 /*
00140  * __vxge_hw_device_register_poll
00141  * Will poll certain register for specified amount of time.
00142  * Will poll until masked bit is not cleared.
00143  */
00144 enum vxge_hw_status
00145 __vxge_hw_device_register_poll(void __iomem *reg, u64 mask, u32 max_millis)
00146 {
00147         u64 val64;
00148         u32 i = 0;
00149         enum vxge_hw_status ret = VXGE_HW_FAIL;
00150 
00151         udelay(10);
00152 
00153         do {
00154                 val64 = readq(reg);
00155                 if (!(val64 & mask))
00156                         return VXGE_HW_OK;
00157                 udelay(100);
00158         } while (++i <= 9);
00159 
00160         i = 0;
00161         do {
00162                 val64 = readq(reg);
00163                 if (!(val64 & mask))
00164                         return VXGE_HW_OK;
00165                 udelay(1000);
00166         } while (++i <= max_millis);
00167 
00168         return ret;
00169 }
00170 
00171  /* __vxge_hw_device_vpath_reset_in_prog_check - Check if vpath reset
00172  * in progress
00173  * This routine checks the vpath reset in progress register is turned zero
00174  */
00175 enum vxge_hw_status
00176 __vxge_hw_device_vpath_reset_in_prog_check(u64 __iomem *vpath_rst_in_prog)
00177 {
00178         enum vxge_hw_status status;
00179 
00180         vxge_trace();
00181 
00182         status = __vxge_hw_device_register_poll(vpath_rst_in_prog,
00183                         VXGE_HW_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(0x1ffff),
00184                         VXGE_HW_DEF_DEVICE_POLL_MILLIS);
00185         return status;
00186 }
00187 
00188 /*
00189  * __vxge_hw_device_toc_get
00190  * This routine sets the swapper and reads the toc pointer and returns the
00191  * memory mapped address of the toc
00192  */
00193 struct vxge_hw_toc_reg __iomem *
00194 __vxge_hw_device_toc_get(void __iomem *bar0)
00195 {
00196         u64 val64;
00197         struct vxge_hw_toc_reg __iomem *toc = NULL;
00198         enum vxge_hw_status status;
00199 
00200         struct vxge_hw_legacy_reg __iomem *legacy_reg =
00201                 (struct vxge_hw_legacy_reg __iomem *)bar0;
00202 
00203         status = __vxge_hw_legacy_swapper_set(legacy_reg);
00204         if (status != VXGE_HW_OK)
00205                 goto exit;
00206 
00207         val64 = readq(&legacy_reg->toc_first_pointer);
00208         toc = (struct vxge_hw_toc_reg __iomem *)(bar0+val64);
00209 exit:
00210         return toc;
00211 }
00212 
00213 /*
00214  * __vxge_hw_device_reg_addr_get
00215  * This routine sets the swapper and reads the toc pointer and initializes the
00216  * register location pointers in the device object. It waits until the ric is
00217  * completed initializing registers.
00218  */
00219 enum vxge_hw_status
00220 __vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev)
00221 {
00222         u64 val64;
00223         u32 i;
00224         enum vxge_hw_status status = VXGE_HW_OK;
00225 
00226         hldev->legacy_reg = (struct vxge_hw_legacy_reg __iomem *)hldev->bar0;
00227 
00228         hldev->toc_reg = __vxge_hw_device_toc_get(hldev->bar0);
00229         if (hldev->toc_reg  == NULL) {
00230                 status = VXGE_HW_FAIL;
00231                 goto exit;
00232         }
00233 
00234         val64 = readq(&hldev->toc_reg->toc_common_pointer);
00235         hldev->common_reg =
00236         (struct vxge_hw_common_reg __iomem *)(hldev->bar0 + val64);
00237 
00238         val64 = readq(&hldev->toc_reg->toc_mrpcim_pointer);
00239         hldev->mrpcim_reg =
00240                 (struct vxge_hw_mrpcim_reg __iomem *)(hldev->bar0 + val64);
00241 
00242         for (i = 0; i < VXGE_HW_TITAN_SRPCIM_REG_SPACES; i++) {
00243                 val64 = readq(&hldev->toc_reg->toc_srpcim_pointer[i]);
00244                 hldev->srpcim_reg[i] =
00245                         (struct vxge_hw_srpcim_reg __iomem *)
00246                                 (hldev->bar0 + val64);
00247         }
00248 
00249         for (i = 0; i < VXGE_HW_TITAN_VPMGMT_REG_SPACES; i++) {
00250                 val64 = readq(&hldev->toc_reg->toc_vpmgmt_pointer[i]);
00251                 hldev->vpmgmt_reg[i] =
00252                 (struct vxge_hw_vpmgmt_reg __iomem *)(hldev->bar0 + val64);
00253         }
00254 
00255         for (i = 0; i < VXGE_HW_TITAN_VPATH_REG_SPACES; i++) {
00256                 val64 = readq(&hldev->toc_reg->toc_vpath_pointer[i]);
00257                 hldev->vpath_reg[i] =
00258                         (struct vxge_hw_vpath_reg __iomem *)
00259                                 (hldev->bar0 + val64);
00260         }
00261 
00262         val64 = readq(&hldev->toc_reg->toc_kdfc);
00263 
00264         switch (VXGE_HW_TOC_GET_KDFC_INITIAL_BIR(val64)) {
00265         case 0:
00266                 hldev->kdfc = (u8 __iomem *)(hldev->bar0 +
00267                         VXGE_HW_TOC_GET_KDFC_INITIAL_OFFSET(val64));
00268                 break;
00269         default:
00270                 break;
00271         }
00272 
00273         status = __vxge_hw_device_vpath_reset_in_prog_check(
00274                         (u64 __iomem *)&hldev->common_reg->vpath_rst_in_prog);
00275 exit:
00276         return status;
00277 }
00278 
00279 /*
00280  * __vxge_hw_device_access_rights_get: Get Access Rights of the driver
00281  * This routine returns the Access Rights of the driver
00282  */
00283 static u32
00284 __vxge_hw_device_access_rights_get(u32 host_type, u32 func_id)
00285 {
00286         u32 access_rights = VXGE_HW_DEVICE_ACCESS_RIGHT_VPATH;
00287 
00288         switch (host_type) {
00289         case VXGE_HW_NO_MR_NO_SR_NORMAL_FUNCTION:
00290                 if (func_id == 0) {
00291                         access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM |
00292                                         VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
00293                 }
00294                 break;
00295         case VXGE_HW_MR_NO_SR_VH0_BASE_FUNCTION:
00296                 access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM |
00297                                 VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
00298                 break;
00299         case VXGE_HW_NO_MR_SR_VH0_FUNCTION0:
00300                 access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM |
00301                                 VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
00302                 break;
00303         case VXGE_HW_NO_MR_SR_VH0_VIRTUAL_FUNCTION:
00304         case VXGE_HW_SR_VH_VIRTUAL_FUNCTION:
00305         case VXGE_HW_MR_SR_VH0_INVALID_CONFIG:
00306                 break;
00307         case VXGE_HW_SR_VH_FUNCTION0:
00308         case VXGE_HW_VH_NORMAL_FUNCTION:
00309                 access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
00310                 break;
00311         }
00312 
00313         return access_rights;
00314 }
00315 
00316 /*
00317  * __vxge_hw_device_host_info_get
00318  * This routine returns the host type assignments
00319  */
00320 void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev)
00321 {
00322         u64 val64;
00323         u32 i;
00324 
00325         val64 = readq(&hldev->common_reg->host_type_assignments);
00326 
00327         hldev->host_type =
00328            (u32)VXGE_HW_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64);
00329 
00330         hldev->vpath_assignments = readq(&hldev->common_reg->vpath_assignments);
00331 
00332         for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
00333 
00334                 if (!(hldev->vpath_assignments & vxge_mBIT(i)))
00335                         continue;
00336 
00337                 hldev->func_id =
00338                         __vxge_hw_vpath_func_id_get(hldev->vpmgmt_reg[i]);
00339 
00340                 hldev->access_rights = __vxge_hw_device_access_rights_get(
00341                         hldev->host_type, hldev->func_id);
00342 
00343                 hldev->first_vp_id = i;
00344                 break;
00345         }
00346 
00347         return;
00348 }
00349 
00350 /**
00351  * vxge_hw_device_hw_info_get - Get the hw information
00352  * Returns the vpath mask that has the bits set for each vpath allocated
00353  * for the driver, FW version information and the first mac addresse for
00354  * each vpath
00355  */
00356 enum vxge_hw_status
00357 vxge_hw_device_hw_info_get(void __iomem *bar0,
00358                                 struct vxge_hw_device_hw_info *hw_info)
00359 {
00360         u32 i;
00361         u64 val64;
00362         struct vxge_hw_toc_reg __iomem *toc;
00363         struct vxge_hw_mrpcim_reg __iomem *mrpcim_reg;
00364         struct vxge_hw_common_reg __iomem *common_reg;
00365         struct vxge_hw_vpath_reg __iomem *vpath_reg;
00366         struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg;
00367         enum vxge_hw_status status;
00368 
00369         vxge_trace();
00370 
00371         memset(hw_info, 0, sizeof(struct vxge_hw_device_hw_info));
00372 
00373         toc = __vxge_hw_device_toc_get(bar0);
00374         if (toc == NULL) {
00375                 status = VXGE_HW_ERR_CRITICAL;
00376                 goto exit;
00377         }
00378 
00379         val64 = readq(&toc->toc_common_pointer);
00380         common_reg = (struct vxge_hw_common_reg __iomem *)(bar0 + val64);
00381 
00382         status = __vxge_hw_device_vpath_reset_in_prog_check(
00383                 (u64 __iomem *)&common_reg->vpath_rst_in_prog);
00384         if (status != VXGE_HW_OK)
00385                 goto exit;
00386 
00387         hw_info->vpath_mask = readq(&common_reg->vpath_assignments);
00388 
00389         val64 = readq(&common_reg->host_type_assignments);
00390 
00391         hw_info->host_type =
00392            (u32)VXGE_HW_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64);
00393 
00394         for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
00395 
00396                 if (!((hw_info->vpath_mask) & vxge_mBIT(i)))
00397                         continue;
00398 
00399                 val64 = readq(&toc->toc_vpmgmt_pointer[i]);
00400 
00401                 vpmgmt_reg = (struct vxge_hw_vpmgmt_reg __iomem *)
00402                                 (bar0 + val64);
00403 
00404                 hw_info->func_id = __vxge_hw_vpath_func_id_get(vpmgmt_reg);
00405                 if (__vxge_hw_device_access_rights_get(hw_info->host_type,
00406                         hw_info->func_id) &
00407                         VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM) {
00408 
00409                         val64 = readq(&toc->toc_mrpcim_pointer);
00410 
00411                         mrpcim_reg = (struct vxge_hw_mrpcim_reg __iomem *)
00412                                         (bar0 + val64);
00413 
00414                         writeq(0, &mrpcim_reg->xgmac_gen_fw_memo_mask);
00415                         wmb();
00416                 }
00417 
00418                 val64 = readq(&toc->toc_vpath_pointer[i]);
00419 
00420                 vpath_reg = (struct vxge_hw_vpath_reg __iomem *)(bar0 + val64);
00421 
00422                 status = __vxge_hw_vpath_fw_ver_get(vpath_reg, hw_info);
00423                 if (status != VXGE_HW_OK)
00424                         goto exit;
00425 
00426                 status = __vxge_hw_vpath_card_info_get(vpath_reg, hw_info);
00427                 if (status != VXGE_HW_OK)
00428                         goto exit;
00429 
00430                 break;
00431         }
00432 
00433         for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
00434 
00435                 if (!((hw_info->vpath_mask) & vxge_mBIT(i)))
00436                         continue;
00437 
00438                 val64 = readq(&toc->toc_vpath_pointer[i]);
00439                 vpath_reg = (struct vxge_hw_vpath_reg __iomem *)(bar0 + val64);
00440 
00441                 status =  __vxge_hw_vpath_addr_get(vpath_reg,
00442                                 hw_info->mac_addrs[i],
00443                                 hw_info->mac_addr_masks[i]);
00444                 if (status != VXGE_HW_OK)
00445                         goto exit;
00446         }
00447 exit:
00448         return status;
00449 }
00450 
00451 /*
00452  * vxge_hw_device_initialize - Initialize Titan device.
00453  * Initialize Titan device. Note that all the arguments of this public API
00454  * are 'IN', including @hldev. Driver cooperates with
00455  * OS to find new Titan device, locate its PCI and memory spaces.
00456  *
00457  * When done, the driver allocates sizeof(struct __vxge_hw_device) bytes for HW
00458  * to enable the latter to perform Titan hardware initialization.
00459  */
00460 enum vxge_hw_status
00461 vxge_hw_device_initialize(
00462         struct __vxge_hw_device **devh,
00463         void *bar0,
00464         struct pci_device *pdev,
00465         u8 titan1)
00466 {
00467         struct __vxge_hw_device *hldev = NULL;
00468         enum vxge_hw_status status = VXGE_HW_OK;
00469 
00470         vxge_trace();
00471 
00472         hldev = (struct __vxge_hw_device *)
00473                         zalloc(sizeof(struct __vxge_hw_device));
00474         if (hldev == NULL) {
00475                 vxge_debug(VXGE_ERR, "hldev allocation failed\n");
00476                 status = VXGE_HW_ERR_OUT_OF_MEMORY;
00477                 goto exit;
00478         }
00479 
00480         hldev->magic = VXGE_HW_DEVICE_MAGIC;
00481 
00482         hldev->bar0 = bar0;
00483         hldev->pdev = pdev;
00484         hldev->titan1 = titan1;
00485 
00486         __vxge_hw_device_pci_e_init(hldev);
00487 
00488         status = __vxge_hw_device_reg_addr_get(hldev);
00489         if (status != VXGE_HW_OK) {
00490                 vxge_debug(VXGE_ERR, "%s:%d __vxge_hw_device_reg_addr_get "
00491                         "failed\n", __func__, __LINE__);
00492                 vxge_hw_device_terminate(hldev);
00493                 goto exit;
00494         }
00495 
00496         __vxge_hw_device_host_info_get(hldev);
00497 
00498         *devh = hldev;
00499 exit:
00500         return status;
00501 }
00502 
00503 /*
00504  * vxge_hw_device_terminate - Terminate Titan device.
00505  * Terminate HW device.
00506  */
00507 void
00508 vxge_hw_device_terminate(struct __vxge_hw_device *hldev)
00509 {
00510         vxge_trace();
00511 
00512         assert(hldev->magic == VXGE_HW_DEVICE_MAGIC);
00513 
00514         hldev->magic = VXGE_HW_DEVICE_DEAD;
00515         free(hldev);
00516 }
00517 
00518 /*
00519  *vxge_hw_ring_replenish - Initial replenish of RxDs
00520  * This function replenishes the RxDs from reserve array to work array
00521  */
00522 enum vxge_hw_status
00523 vxge_hw_ring_replenish(struct __vxge_hw_ring *ring)
00524 {
00525         struct __vxge_hw_device *hldev;
00526         struct vxge_hw_ring_rxd_1 *rxd;
00527         enum vxge_hw_status status = VXGE_HW_OK;
00528         u8 offset = 0;
00529         struct __vxge_hw_ring_block *block;
00530         u8 i, iob_off;
00531 
00532         vxge_trace();
00533 
00534         hldev = ring->vpathh->hldev;
00535         /*
00536          * We allocate all the dma buffers first and then share the
00537          * these buffers among the all rx descriptors in the block.
00538          */
00539         for (i = 0; i < ARRAY_SIZE(ring->iobuf); i++) {
00540                 ring->iobuf[i] = alloc_iob(VXGE_LL_MAX_FRAME_SIZE(hldev->vdev));
00541                 if (!ring->iobuf[i]) {
00542                         while (i) {
00543                                 free_iob(ring->iobuf[--i]);
00544                                 ring->iobuf[i] = NULL;
00545                         }
00546                         status = VXGE_HW_ERR_OUT_OF_MEMORY;
00547                         goto iobuf_err;
00548                 }
00549         }
00550 
00551         for (offset = 0; offset < VXGE_HW_MAX_RXDS_PER_BLOCK_1; offset++) {
00552 
00553                 rxd = &ring->rxdl->rxd[offset];
00554                 if (offset == (VXGE_HW_MAX_RXDS_PER_BLOCK_1 - 1))
00555                         iob_off = VXGE_HW_RING_BUF_PER_BLOCK;
00556                 else
00557                         iob_off = offset % ring->buf_per_block;
00558 
00559                 rxd->control_0 = rxd->control_1 = 0;
00560                 vxge_hw_ring_rxd_1b_set(rxd, ring->iobuf[iob_off],
00561                                 VXGE_LL_MAX_FRAME_SIZE(hldev->vdev));
00562 
00563                 vxge_hw_ring_rxd_post(ring, rxd);
00564         }
00565         /* linking the block to itself as we use only one rx block*/
00566         block = ring->rxdl;
00567         block->reserved_2_pNext_RxD_block = (unsigned long) block;
00568         block->pNext_RxD_Blk_physical = (u64)virt_to_bus(block);
00569 
00570         ring->rxd_offset = 0;
00571 iobuf_err:
00572         return status;
00573 }
00574 
00575 /*
00576  * __vxge_hw_ring_create - Create a Ring
00577  * This function creates Ring and initializes it.
00578  *
00579  */
00580 enum vxge_hw_status
00581 __vxge_hw_ring_create(struct __vxge_hw_virtualpath *vpath,
00582                       struct __vxge_hw_ring *ring)
00583 {
00584         enum vxge_hw_status status = VXGE_HW_OK;
00585         struct __vxge_hw_device *hldev;
00586         u32 vp_id;
00587 
00588         vxge_trace();
00589 
00590         hldev = vpath->hldev;
00591         vp_id = vpath->vp_id;
00592 
00593         ring->rxdl = malloc_dma(sizeof(struct __vxge_hw_ring_block),
00594                         sizeof(struct __vxge_hw_ring_block));
00595         if (!ring->rxdl) {
00596                 vxge_debug(VXGE_ERR, "%s:%d malloc_dma error\n",
00597                                 __func__, __LINE__);
00598                 status = VXGE_HW_ERR_OUT_OF_MEMORY;
00599                 goto exit;
00600         }
00601         ring->rxd_offset = 0;
00602         ring->vpathh = vpath;
00603         ring->buf_per_block = VXGE_HW_RING_BUF_PER_BLOCK;
00604         ring->rx_poll_weight = VXGE_HW_RING_RX_POLL_WEIGHT;
00605         ring->vp_id = vp_id;
00606         ring->vp_reg = vpath->vp_reg;
00607         ring->common_reg = hldev->common_reg;
00608 
00609         ring->rxd_qword_limit = VXGE_HW_RING_RXD_QWORD_LIMIT;
00610 
00611         status = vxge_hw_ring_replenish(ring);
00612         if (status != VXGE_HW_OK) {
00613                 __vxge_hw_ring_delete(ring);
00614                 goto exit;
00615         }
00616 exit:
00617         return status;
00618 }
00619 
00620 /*
00621  * __vxge_hw_ring_delete - Removes the ring
00622  * This function freeup the memory pool and removes the ring
00623  */
00624 enum vxge_hw_status __vxge_hw_ring_delete(struct __vxge_hw_ring *ring)
00625 {
00626         u8 i;
00627 
00628         vxge_trace();
00629 
00630         for (i = 0; (i < ARRAY_SIZE(ring->iobuf)) && ring->iobuf[i]; i++) {
00631                 free_iob(ring->iobuf[i]);
00632                 ring->iobuf[i] = NULL;
00633         }
00634 
00635         if (ring->rxdl) {
00636                 free_dma(ring->rxdl, sizeof(struct __vxge_hw_ring_block));
00637                 ring->rxdl = NULL;
00638         }
00639         ring->rxd_offset = 0;
00640 
00641         return VXGE_HW_OK;
00642 }
00643 
00644 /*
00645  * _hw_legacy_swapper_set - Set the swapper bits for the legacy secion.
00646  * Set the swapper bits appropriately for the legacy section.
00647  */
00648 enum vxge_hw_status
00649 __vxge_hw_legacy_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg)
00650 {
00651         u64 val64;
00652         enum vxge_hw_status status = VXGE_HW_OK;
00653 
00654         vxge_trace();
00655 
00656         val64 = readq(&legacy_reg->toc_swapper_fb);
00657 
00658         wmb();
00659 
00660         switch (val64) {
00661 
00662         case VXGE_HW_SWAPPER_INITIAL_VALUE:
00663                 return status;
00664 
00665         case VXGE_HW_SWAPPER_BYTE_SWAPPED_BIT_FLIPPED:
00666                 writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE,
00667                         &legacy_reg->pifm_rd_swap_en);
00668                 writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE,
00669                         &legacy_reg->pifm_rd_flip_en);
00670                 writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE,
00671                         &legacy_reg->pifm_wr_swap_en);
00672                 writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE,
00673                         &legacy_reg->pifm_wr_flip_en);
00674                 break;
00675 
00676         case VXGE_HW_SWAPPER_BYTE_SWAPPED:
00677                 writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE,
00678                         &legacy_reg->pifm_rd_swap_en);
00679                 writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE,
00680                         &legacy_reg->pifm_wr_swap_en);
00681                 break;
00682 
00683         case VXGE_HW_SWAPPER_BIT_FLIPPED:
00684                 writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE,
00685                         &legacy_reg->pifm_rd_flip_en);
00686                 writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE,
00687                         &legacy_reg->pifm_wr_flip_en);
00688                 break;
00689         }
00690 
00691         wmb();
00692 
00693         val64 = readq(&legacy_reg->toc_swapper_fb);
00694         if (val64 != VXGE_HW_SWAPPER_INITIAL_VALUE)
00695                 status = VXGE_HW_ERR_SWAPPER_CTRL;
00696 
00697         return status;
00698 }
00699 
00700 /*
00701  * __vxge_hw_vpath_swapper_set - Set the swapper bits for the vpath.
00702  * Set the swapper bits appropriately for the vpath.
00703  */
00704 enum vxge_hw_status
00705 __vxge_hw_vpath_swapper_set(struct vxge_hw_vpath_reg __iomem *vpath_reg)
00706 {
00707         vxge_trace();
00708 
00709 #if (__BYTE_ORDER != __BIG_ENDIAN)
00710         u64 val64;
00711 
00712         val64 = readq(&vpath_reg->vpath_general_cfg1);
00713         wmb();
00714         val64 |= VXGE_HW_VPATH_GENERAL_CFG1_CTL_BYTE_SWAPEN;
00715         writeq(val64, &vpath_reg->vpath_general_cfg1);
00716         wmb();
00717 #endif
00718         return VXGE_HW_OK;
00719 }
00720 
00721 /*
00722  * __vxge_hw_kdfc_swapper_set - Set the swapper bits for the kdfc.
00723  * Set the swapper bits appropriately for the vpath.
00724  */
00725 enum vxge_hw_status
00726 __vxge_hw_kdfc_swapper_set(
00727         struct vxge_hw_legacy_reg __iomem *legacy_reg,
00728         struct vxge_hw_vpath_reg __iomem *vpath_reg)
00729 {
00730         u64 val64;
00731 
00732         vxge_trace();
00733 
00734         val64 = readq(&legacy_reg->pifm_wr_swap_en);
00735 
00736         if (val64 == VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE) {
00737                 val64 = readq(&vpath_reg->kdfcctl_cfg0);
00738                 wmb();
00739 
00740                 val64 |= VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO0 |
00741                         VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO1  |
00742                         VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO2;
00743 
00744                 writeq(val64, &vpath_reg->kdfcctl_cfg0);
00745                 wmb();
00746         }
00747 
00748         return VXGE_HW_OK;
00749 }
00750 
00751 /*
00752  * vxge_hw_vpath_strip_fcs_check - Check for FCS strip.
00753  */
00754 enum vxge_hw_status
00755 vxge_hw_vpath_strip_fcs_check(struct __vxge_hw_device *hldev, u64 vpath_mask)
00756 {
00757         struct vxge_hw_vpmgmt_reg       __iomem *vpmgmt_reg;
00758         enum vxge_hw_status status = VXGE_HW_OK;
00759         int i = 0, j = 0;
00760 
00761         for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
00762                 if (!((vpath_mask) & vxge_mBIT(i)))
00763                         continue;
00764                 vpmgmt_reg = hldev->vpmgmt_reg[i];
00765                 for (j = 0; j < VXGE_HW_MAC_MAX_MAC_PORT_ID; j++) {
00766                         if (readq(&vpmgmt_reg->rxmac_cfg0_port_vpmgmt_clone[j])
00767                         & VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_STRIP_FCS)
00768                                 return VXGE_HW_FAIL;
00769                 }
00770         }
00771         return status;
00772 }
00773 
00774 /*
00775  * __vxge_hw_fifo_create - Create a FIFO
00776  * This function creates FIFO and initializes it.
00777  */
00778 enum vxge_hw_status
00779 __vxge_hw_fifo_create(struct __vxge_hw_virtualpath *vpath,
00780                         struct __vxge_hw_fifo *fifo)
00781 {
00782         enum vxge_hw_status status = VXGE_HW_OK;
00783 
00784         vxge_trace();
00785 
00786         fifo->vpathh = vpath;
00787         fifo->depth = VXGE_HW_FIFO_TXD_DEPTH;
00788         fifo->hw_offset = fifo->sw_offset = 0;
00789         fifo->nofl_db = vpath->nofl_db;
00790         fifo->vp_id = vpath->vp_id;
00791         fifo->vp_reg = vpath->vp_reg;
00792         fifo->tx_intr_num = (vpath->vp_id * VXGE_HW_MAX_INTR_PER_VP)
00793                                 + VXGE_HW_VPATH_INTR_TX;
00794 
00795         fifo->txdl = malloc_dma(sizeof(struct vxge_hw_fifo_txd)
00796                                 * fifo->depth, fifo->depth);
00797         if (!fifo->txdl) {
00798                 vxge_debug(VXGE_ERR, "%s:%d malloc_dma error\n",
00799                                 __func__, __LINE__);
00800                 return VXGE_HW_ERR_OUT_OF_MEMORY;
00801         }
00802         memset(fifo->txdl, 0, sizeof(struct vxge_hw_fifo_txd) * fifo->depth);
00803         return status;
00804 }
00805 
00806 /*
00807  * __vxge_hw_fifo_delete - Removes the FIFO
00808  * This function freeup the memory pool and removes the FIFO
00809  */
00810 enum vxge_hw_status __vxge_hw_fifo_delete(struct __vxge_hw_fifo *fifo)
00811 {
00812         vxge_trace();
00813 
00814         if (fifo->txdl)
00815                 free_dma(fifo->txdl,
00816                         sizeof(struct vxge_hw_fifo_txd) * fifo->depth);
00817 
00818         fifo->txdl = NULL;
00819         fifo->hw_offset = fifo->sw_offset = 0;
00820 
00821         return VXGE_HW_OK;
00822 }
00823 
00824 /*
00825  * __vxge_hw_vpath_pci_read - Read the content of given address
00826  *                          in pci config space.
00827  * Read from the vpath pci config space.
00828  */
00829 enum vxge_hw_status
00830 __vxge_hw_vpath_pci_read(struct __vxge_hw_virtualpath *vpath,
00831                          u32 phy_func_0, u32 offset, u32 *val)
00832 {
00833         u64 val64;
00834         enum vxge_hw_status status = VXGE_HW_OK;
00835         struct vxge_hw_vpath_reg __iomem *vp_reg = vpath->vp_reg;
00836 
00837         val64 = VXGE_HW_PCI_CONFIG_ACCESS_CFG1_ADDRESS(offset);
00838 
00839         if (phy_func_0)
00840                 val64 |= VXGE_HW_PCI_CONFIG_ACCESS_CFG1_SEL_FUNC0;
00841 
00842         writeq(val64, &vp_reg->pci_config_access_cfg1);
00843         wmb();
00844         writeq(VXGE_HW_PCI_CONFIG_ACCESS_CFG2_REQ,
00845                         &vp_reg->pci_config_access_cfg2);
00846         wmb();
00847 
00848         status = __vxge_hw_device_register_poll(
00849                         &vp_reg->pci_config_access_cfg2,
00850                         VXGE_HW_INTR_MASK_ALL, VXGE_HW_DEF_DEVICE_POLL_MILLIS);
00851 
00852         if (status != VXGE_HW_OK)
00853                 goto exit;
00854 
00855         val64 = readq(&vp_reg->pci_config_access_status);
00856 
00857         if (val64 & VXGE_HW_PCI_CONFIG_ACCESS_STATUS_ACCESS_ERR) {
00858                 status = VXGE_HW_FAIL;
00859                 *val = 0;
00860         } else
00861                 *val = (u32)vxge_bVALn(val64, 32, 32);
00862 exit:
00863         return status;
00864 }
00865 
00866 /*
00867  * __vxge_hw_vpath_func_id_get - Get the function id of the vpath.
00868  * Returns the function number of the vpath.
00869  */
00870 u32
00871 __vxge_hw_vpath_func_id_get(struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg)
00872 {
00873         u64 val64;
00874 
00875         val64 = readq(&vpmgmt_reg->vpath_to_func_map_cfg1);
00876 
00877         return
00878          (u32)VXGE_HW_VPATH_TO_FUNC_MAP_CFG1_GET_VPATH_TO_FUNC_MAP_CFG1(val64);
00879 }
00880 
00881 /*
00882  * __vxge_hw_read_rts_ds - Program RTS steering critieria
00883  */
00884 static inline void
00885 __vxge_hw_read_rts_ds(struct vxge_hw_vpath_reg __iomem *vpath_reg,
00886                                 u64 dta_struct_sel)
00887 {
00888         writeq(0, &vpath_reg->rts_access_steer_ctrl);
00889         wmb();
00890         writeq(dta_struct_sel, &vpath_reg->rts_access_steer_data0);
00891         writeq(0, &vpath_reg->rts_access_steer_data1);
00892         wmb();
00893         return;
00894 }
00895 
00896 /*
00897  * __vxge_hw_vpath_card_info_get - Get the serial numbers,
00898  * part number and product description.
00899  */
00900 enum vxge_hw_status
00901 __vxge_hw_vpath_card_info_get(
00902         struct vxge_hw_vpath_reg __iomem *vpath_reg,
00903         struct vxge_hw_device_hw_info *hw_info)
00904 {
00905         u32 i, j;
00906         u64 val64;
00907         u64 data1 = 0ULL;
00908         u64 data2 = 0ULL;
00909         enum vxge_hw_status status = VXGE_HW_OK;
00910         u8 *serial_number = hw_info->serial_number;
00911         u8 *part_number = hw_info->part_number;
00912         u8 *product_desc = hw_info->product_desc;
00913 
00914         __vxge_hw_read_rts_ds(vpath_reg,
00915                 VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_SERIAL_NUMBER);
00916 
00917         val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
00918                         VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
00919                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
00920                         VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
00921                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
00922                 VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
00923 
00924         status = __vxge_hw_pio_mem_write64(val64,
00925                                 &vpath_reg->rts_access_steer_ctrl,
00926                                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
00927                                 VXGE_HW_DEF_DEVICE_POLL_MILLIS);
00928 
00929         if (status != VXGE_HW_OK)
00930                 return status;
00931 
00932         val64 = readq(&vpath_reg->rts_access_steer_ctrl);
00933 
00934         if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
00935                 data1 = readq(&vpath_reg->rts_access_steer_data0);
00936                 ((u64 *)serial_number)[0] = be64_to_cpu(data1);
00937 
00938                 data2 = readq(&vpath_reg->rts_access_steer_data1);
00939                 ((u64 *)serial_number)[1] = be64_to_cpu(data2);
00940                 status = VXGE_HW_OK;
00941         } else
00942                 *serial_number = 0;
00943 
00944         __vxge_hw_read_rts_ds(vpath_reg,
00945                         VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PART_NUMBER);
00946 
00947         val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
00948                         VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
00949                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
00950                         VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
00951                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
00952                 VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
00953 
00954         status = __vxge_hw_pio_mem_write64(val64,
00955                                 &vpath_reg->rts_access_steer_ctrl,
00956                                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
00957                                 VXGE_HW_DEF_DEVICE_POLL_MILLIS);
00958 
00959         if (status != VXGE_HW_OK)
00960                 return status;
00961 
00962         val64 = readq(&vpath_reg->rts_access_steer_ctrl);
00963 
00964         if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
00965 
00966                 data1 = readq(&vpath_reg->rts_access_steer_data0);
00967                 ((u64 *)part_number)[0] = be64_to_cpu(data1);
00968 
00969                 data2 = readq(&vpath_reg->rts_access_steer_data1);
00970                 ((u64 *)part_number)[1] = be64_to_cpu(data2);
00971 
00972                 status = VXGE_HW_OK;
00973 
00974         } else
00975                 *part_number = 0;
00976 
00977         j = 0;
00978 
00979         for (i = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_0;
00980              i <= VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_3; i++) {
00981 
00982                 __vxge_hw_read_rts_ds(vpath_reg, i);
00983 
00984                 val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
00985                         VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
00986                         VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
00987                         VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
00988                         VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
00989                         VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
00990 
00991                 status = __vxge_hw_pio_mem_write64(val64,
00992                                 &vpath_reg->rts_access_steer_ctrl,
00993                                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
00994                                 VXGE_HW_DEF_DEVICE_POLL_MILLIS);
00995 
00996                 if (status != VXGE_HW_OK)
00997                         return status;
00998 
00999                 val64 = readq(&vpath_reg->rts_access_steer_ctrl);
01000 
01001                 if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
01002 
01003                         data1 = readq(&vpath_reg->rts_access_steer_data0);
01004                         ((u64 *)product_desc)[j++] = be64_to_cpu(data1);
01005 
01006                         data2 = readq(&vpath_reg->rts_access_steer_data1);
01007                         ((u64 *)product_desc)[j++] = be64_to_cpu(data2);
01008 
01009                         status = VXGE_HW_OK;
01010                 } else
01011                         *product_desc = 0;
01012         }
01013 
01014         return status;
01015 }
01016 
01017 /*
01018  * __vxge_hw_vpath_fw_ver_get - Get the fw version
01019  * Returns FW Version
01020  */
01021 enum vxge_hw_status
01022 __vxge_hw_vpath_fw_ver_get(
01023         struct vxge_hw_vpath_reg __iomem *vpath_reg,
01024         struct vxge_hw_device_hw_info *hw_info)
01025 {
01026         u64 val64;
01027         u64 data1 = 0ULL;
01028         u64 data2 = 0ULL;
01029         struct vxge_hw_device_version *fw_version = &hw_info->fw_version;
01030         struct vxge_hw_device_date *fw_date = &hw_info->fw_date;
01031         struct vxge_hw_device_version *flash_version = &hw_info->flash_version;
01032         struct vxge_hw_device_date *flash_date = &hw_info->flash_date;
01033         enum vxge_hw_status status = VXGE_HW_OK;
01034 
01035         val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
01036                 VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY) |
01037                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
01038                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
01039                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
01040                 VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
01041 
01042         status = __vxge_hw_pio_mem_write64(val64,
01043                                 &vpath_reg->rts_access_steer_ctrl,
01044                                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
01045                                 VXGE_HW_DEF_DEVICE_POLL_MILLIS);
01046 
01047         if (status != VXGE_HW_OK)
01048                 goto exit;
01049 
01050         val64 = readq(&vpath_reg->rts_access_steer_ctrl);
01051 
01052         if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
01053 
01054                 data1 = readq(&vpath_reg->rts_access_steer_data0);
01055                 data2 = readq(&vpath_reg->rts_access_steer_data1);
01056 
01057                 fw_date->day =
01058                         (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_DAY(
01059                                                 data1);
01060                 fw_date->month =
01061                         (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MONTH(
01062                                                 data1);
01063                 fw_date->year =
01064                         (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_YEAR(
01065                                                 data1);
01066 
01067                 snprintf(fw_date->date, VXGE_HW_FW_STRLEN, "%d/%d/%d",
01068                         fw_date->month, fw_date->day, fw_date->year);
01069 
01070                 fw_version->major =
01071                     (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data1);
01072                 fw_version->minor =
01073                     (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data1);
01074                 fw_version->build =
01075                     (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data1);
01076 
01077                 snprintf(fw_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d",
01078                     fw_version->major, fw_version->minor, fw_version->build);
01079 
01080                 flash_date->day =
01081                   (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_DAY(data2);
01082                 flash_date->month =
01083                  (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MONTH(data2);
01084                 flash_date->year =
01085                  (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_YEAR(data2);
01086 
01087                 snprintf(flash_date->date, VXGE_HW_FW_STRLEN, "%d/%d/%d",
01088                         flash_date->month, flash_date->day, flash_date->year);
01089 
01090                 flash_version->major =
01091                  (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MAJOR(data2);
01092                 flash_version->minor =
01093                  (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MINOR(data2);
01094                 flash_version->build =
01095                  (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(data2);
01096 
01097                 snprintf(flash_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d",
01098                         flash_version->major, flash_version->minor,
01099                         flash_version->build);
01100 
01101                 status = VXGE_HW_OK;
01102 
01103         } else
01104                 status = VXGE_HW_FAIL;
01105 exit:
01106         return status;
01107 }
01108 
01109 /*
01110  * __vxge_hw_vpath_addr_get - Get the hw address entry for this vpath
01111  *               from MAC address table.
01112  */
01113 enum vxge_hw_status
01114 __vxge_hw_vpath_addr_get(
01115         struct vxge_hw_vpath_reg *vpath_reg,
01116         u8 (macaddr)[ETH_ALEN], u8 (macaddr_mask)[ETH_ALEN])
01117 {
01118         u32 i;
01119         u64 val64;
01120         u64 data1 = 0ULL;
01121         u64 data2 = 0ULL;
01122         u64 action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY;
01123         enum vxge_hw_status status = VXGE_HW_OK;
01124 
01125         while (1) {
01126                 val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) |
01127                         VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
01128                         VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) |
01129                         VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
01130                         VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
01131 
01132                 status = __vxge_hw_pio_mem_write64(val64,
01133                                         &vpath_reg->rts_access_steer_ctrl,
01134                                         VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
01135                                         VXGE_HW_DEF_DEVICE_POLL_MILLIS);
01136 
01137                 if (status != VXGE_HW_OK)
01138                         break;
01139 
01140                 val64 = readq(&vpath_reg->rts_access_steer_ctrl);
01141 
01142                 if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
01143 
01144                         data1 = readq(&vpath_reg->rts_access_steer_data0);
01145                         data2 = readq(&vpath_reg->rts_access_steer_data1);
01146 
01147                         data1 =
01148                          VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data1);
01149                         data2 =
01150                          VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK(
01151                                                                 data2);
01152 
01153                         for (i = ETH_ALEN; i > 0; i--) {
01154                                 macaddr[i-1] = (u8)(data1 & 0xFF);
01155                                 data1 >>= 8;
01156 
01157                                 macaddr_mask[i-1] = (u8)(data2 & 0xFF);
01158                                 data2 >>= 8;
01159                         }
01160                         if (is_valid_ether_addr(macaddr)) {
01161                                 status = VXGE_HW_OK;
01162                                 break;
01163                         }
01164                         action =
01165                           VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_NEXT_ENTRY;
01166                 } else
01167                         status = VXGE_HW_FAIL;
01168         }
01169 
01170         return status;
01171 }
01172 
01173 /*
01174  * __vxge_hw_vpath_mgmt_read
01175  * This routine reads the vpath_mgmt registers
01176  */
01177 static enum vxge_hw_status
01178 __vxge_hw_vpath_mgmt_read(
01179         struct __vxge_hw_virtualpath *vpath)
01180 {
01181         u32 i, mtu = 0, max_pyld = 0;
01182         u64 val64;
01183         enum vxge_hw_status status = VXGE_HW_OK;
01184 
01185         for (i = 0; i < VXGE_HW_MAC_MAX_MAC_PORT_ID; i++) {
01186 
01187                 val64 = readq(&vpath->vpmgmt_reg->
01188                                 rxmac_cfg0_port_vpmgmt_clone[i]);
01189                 max_pyld =
01190                         (u32)
01191                         VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_GET_MAX_PYLD_LEN
01192                         (val64);
01193                 if (mtu < max_pyld)
01194                         mtu = max_pyld;
01195         }
01196 
01197         vpath->max_mtu = mtu + VXGE_HW_MAC_HEADER_MAX_SIZE;
01198 
01199         val64 = readq(&vpath->vpmgmt_reg->xgmac_gen_status_vpmgmt_clone);
01200 
01201         if (val64 & VXGE_HW_XGMAC_GEN_STATUS_VPMGMT_CLONE_XMACJ_NTWK_OK)
01202                 VXGE_HW_DEVICE_LINK_STATE_SET(vpath->hldev, VXGE_HW_LINK_UP);
01203         else
01204                 VXGE_HW_DEVICE_LINK_STATE_SET(vpath->hldev, VXGE_HW_LINK_DOWN);
01205 
01206         return status;
01207 }
01208 
01209 /*
01210  * __vxge_hw_vpath_reset_check - Check if resetting the vpath completed
01211  * This routine checks the vpath_rst_in_prog register to see if
01212  * adapter completed the reset process for the vpath
01213  */
01214 enum vxge_hw_status
01215 __vxge_hw_vpath_reset_check(struct __vxge_hw_virtualpath *vpath)
01216 {
01217         enum vxge_hw_status status;
01218 
01219         vxge_trace();
01220 
01221         status = __vxge_hw_device_register_poll(
01222                         &vpath->hldev->common_reg->vpath_rst_in_prog,
01223                         VXGE_HW_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(
01224                                 1 << (16 - vpath->vp_id)),
01225                         VXGE_HW_DEF_DEVICE_POLL_MILLIS);
01226 
01227         return status;
01228 }
01229 
01230 /*
01231  * __vxge_hw_vpath_reset
01232  * This routine resets the vpath on the device
01233  */
01234 enum vxge_hw_status
01235 __vxge_hw_vpath_reset(struct __vxge_hw_device *hldev, u32 vp_id)
01236 {
01237         u64 val64;
01238         enum vxge_hw_status status = VXGE_HW_OK;
01239 
01240         vxge_trace();
01241 
01242         val64 = VXGE_HW_CMN_RSTHDLR_CFG0_SW_RESET_VPATH(1 << (16 - vp_id));
01243 
01244         __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32),
01245                                 &hldev->common_reg->cmn_rsthdlr_cfg0);
01246 
01247         return status;
01248 }
01249 
01250 /*
01251  * __vxge_hw_vpath_prc_configure
01252  * This routine configures the prc registers of virtual path using the config
01253  * passed
01254  */
01255 void
01256 __vxge_hw_vpath_prc_configure(struct __vxge_hw_device *hldev)
01257 {
01258         u64 val64;
01259         struct __vxge_hw_virtualpath *vpath;
01260         struct vxge_hw_vpath_reg __iomem *vp_reg;
01261 
01262         vxge_trace();
01263 
01264         vpath = &hldev->virtual_path;
01265         vp_reg = vpath->vp_reg;
01266 
01267         val64 = readq(&vp_reg->prc_cfg1);
01268         val64 |= VXGE_HW_PRC_CFG1_RTI_TINT_DISABLE;
01269         writeq(val64, &vp_reg->prc_cfg1);
01270 
01271         val64 = readq(&vpath->vp_reg->prc_cfg6);
01272         val64 &= ~VXGE_HW_PRC_CFG6_RXD_CRXDT(0x1ff);
01273         val64 &= ~VXGE_HW_PRC_CFG6_RXD_SPAT(0x1ff);
01274         val64 |= VXGE_HW_PRC_CFG6_DOORBELL_MODE_EN;
01275         val64 |= VXGE_HW_PRC_CFG6_RXD_CRXDT(0x3);
01276         val64 |= VXGE_HW_PRC_CFG6_RXD_SPAT(0xf);
01277         writeq(val64, &vpath->vp_reg->prc_cfg6);
01278 
01279         writeq(VXGE_HW_PRC_CFG5_RXD0_ADD(
01280                         (u64)virt_to_bus(vpath->ringh.rxdl) >> 3),
01281                         &vp_reg->prc_cfg5);
01282 
01283         val64 = readq(&vp_reg->prc_cfg4);
01284         val64 |= VXGE_HW_PRC_CFG4_IN_SVC;
01285         val64 &= ~VXGE_HW_PRC_CFG4_RING_MODE(0x3);
01286         val64 |= VXGE_HW_PRC_CFG4_RING_MODE(
01287                         VXGE_HW_PRC_CFG4_RING_MODE_ONE_BUFFER);
01288         val64 |= VXGE_HW_PRC_CFG4_RTH_DISABLE;
01289 
01290         writeq(val64, &vp_reg->prc_cfg4);
01291         return;
01292 }
01293 
01294 /*
01295  * __vxge_hw_vpath_kdfc_configure
01296  * This routine configures the kdfc registers of virtual path using the
01297  * config passed
01298  */
01299 enum vxge_hw_status
01300 __vxge_hw_vpath_kdfc_configure(struct __vxge_hw_device *hldev, u32 vp_id)
01301 {
01302         u64 val64;
01303         u64 vpath_stride;
01304         enum vxge_hw_status status = VXGE_HW_OK;
01305         struct __vxge_hw_virtualpath *vpath;
01306         struct vxge_hw_vpath_reg __iomem *vp_reg;
01307 
01308         vxge_trace();
01309 
01310         vpath = &hldev->virtual_path;
01311         vp_reg = vpath->vp_reg;
01312         status = __vxge_hw_kdfc_swapper_set(hldev->legacy_reg, vp_reg);
01313 
01314         if (status != VXGE_HW_OK)
01315                 goto exit;
01316 
01317         val64 = readq(&vp_reg->kdfc_drbl_triplet_total);
01318 
01319         vpath->max_kdfc_db =
01320                 (u32)VXGE_HW_KDFC_DRBL_TRIPLET_TOTAL_GET_KDFC_MAX_SIZE(
01321                         val64+1)/2;
01322 
01323         vpath->max_nofl_db = vpath->max_kdfc_db;
01324 
01325         val64 = VXGE_HW_KDFC_FIFO_TRPL_PARTITION_LENGTH_0(
01326                                 (vpath->max_nofl_db*2)-1);
01327 
01328         writeq(val64, &vp_reg->kdfc_fifo_trpl_partition);
01329 
01330         writeq(VXGE_HW_KDFC_FIFO_TRPL_CTRL_TRIPLET_ENABLE,
01331                 &vp_reg->kdfc_fifo_trpl_ctrl);
01332 
01333         val64 = readq(&vp_reg->kdfc_trpl_fifo_0_ctrl);
01334 
01335         val64 &= ~(VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE(0x3) |
01336                    VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SELECT(0xFF));
01337 
01338         val64 |= VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE(
01339                  VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE_NON_OFFLOAD_ONLY) |
01340 #if (__BYTE_ORDER != __BIG_ENDIAN)
01341                  VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SWAP_EN |
01342 #endif
01343                  VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SELECT(0);
01344 
01345         writeq(val64, &vp_reg->kdfc_trpl_fifo_0_ctrl);
01346         writeq((u64)0, &vp_reg->kdfc_trpl_fifo_0_wb_address);
01347         wmb();
01348         vpath_stride = readq(&hldev->toc_reg->toc_kdfc_vpath_stride);
01349 
01350         vpath->nofl_db =
01351                 (struct __vxge_hw_non_offload_db_wrapper __iomem *)
01352                 (hldev->kdfc + (vp_id *
01353                 VXGE_HW_TOC_KDFC_VPATH_STRIDE_GET_TOC_KDFC_VPATH_STRIDE(
01354                                         vpath_stride)));
01355 exit:
01356         return status;
01357 }
01358 
01359 /*
01360  * __vxge_hw_vpath_mac_configure
01361  * This routine configures the mac of virtual path using the config passed
01362  */
01363 enum vxge_hw_status
01364 __vxge_hw_vpath_mac_configure(struct __vxge_hw_device *hldev)
01365 {
01366         u64 val64;
01367         enum vxge_hw_status status = VXGE_HW_OK;
01368         struct __vxge_hw_virtualpath *vpath;
01369         struct vxge_hw_vpath_reg __iomem *vp_reg;
01370 
01371         vxge_trace();
01372 
01373         vpath = &hldev->virtual_path;
01374         vp_reg = vpath->vp_reg;
01375 
01376         writeq(VXGE_HW_XMAC_VSPORT_CHOICE_VSPORT_NUMBER(
01377                         vpath->vsport_number), &vp_reg->xmac_vsport_choice);
01378 
01379         val64 = readq(&vp_reg->rxmac_vcfg1);
01380 
01381         val64 &= ~(VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_BD_MODE(0x3) |
01382                 VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_EN_MODE);
01383 
01384         writeq(val64, &vp_reg->rxmac_vcfg1);
01385         return status;
01386 }
01387 
01388 /*
01389  * __vxge_hw_vpath_tim_configure
01390  * This routine configures the tim registers of virtual path using the config
01391  * passed
01392  */
01393 enum vxge_hw_status
01394 __vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id)
01395 {
01396         u64 val64;
01397         enum vxge_hw_status status = VXGE_HW_OK;
01398         struct __vxge_hw_virtualpath *vpath;
01399         struct vxge_hw_vpath_reg __iomem *vp_reg;
01400 
01401         vxge_trace();
01402 
01403         vpath = &hldev->virtual_path;
01404         vp_reg = vpath->vp_reg;
01405 
01406         writeq((u64)0, &vp_reg->tim_dest_addr);
01407         writeq((u64)0, &vp_reg->tim_vpath_map);
01408         writeq((u64)0, &vp_reg->tim_bitmap);
01409         writeq((u64)0, &vp_reg->tim_remap);
01410 
01411         writeq(VXGE_HW_TIM_RING_ASSN_INT_NUM(
01412                 (vp_id * VXGE_HW_MAX_INTR_PER_VP) +
01413                 VXGE_HW_VPATH_INTR_RX), &vp_reg->tim_ring_assn);
01414 
01415         val64 = readq(&vp_reg->tim_pci_cfg);
01416         val64 |= VXGE_HW_TIM_PCI_CFG_ADD_PAD;
01417         writeq(val64, &vp_reg->tim_pci_cfg);
01418 
01419         /* TX configuration */
01420         val64 = VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
01421                         (VXGE_TTI_BTIMER_VAL * 1000) / 272);
01422         val64 |= (VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC |
01423                         VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI |
01424                         VXGE_HW_TIM_CFG1_INT_NUM_TXFRM_CNT_EN);
01425         val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(TTI_TX_URANGE_A) |
01426                         VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(TTI_TX_URANGE_B) |
01427                         VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(TTI_TX_URANGE_C);
01428         writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]);
01429 
01430         val64 = VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(TTI_TX_UFC_A) |
01431                         VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(TTI_TX_UFC_B) |
01432                         VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(TTI_TX_UFC_C) |
01433                         VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(TTI_TX_UFC_D);
01434         writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_TX]);
01435 
01436         val64 = VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(
01437                         VXGE_HW_TIM_UTIL_SEL_LEGACY_TX_NET_UTIL);
01438         val64 |= VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
01439                         (VXGE_TTI_LTIMER_VAL * 1000) / 272);
01440         writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_TX]);
01441 
01442         /* RX configuration */
01443         val64 = VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
01444                         (VXGE_RTI_BTIMER_VAL * 1000) / 272);
01445         val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC;
01446         val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(RTI_RX_URANGE_A) |
01447                         VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(RTI_RX_URANGE_B) |
01448                         VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(RTI_RX_URANGE_C);
01449         writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_RX]);
01450 
01451         val64 = VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(RTI_RX_UFC_A) |
01452                         VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(RTI_RX_UFC_B) |
01453                         VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(RTI_RX_UFC_C) |
01454                         VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(RTI_RX_UFC_D);
01455         writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_RX]);
01456 
01457         val64 = VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(
01458                         VXGE_HW_TIM_UTIL_SEL_LEGACY_RX_NET_UTIL);
01459         val64 |= VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
01460                         (VXGE_RTI_LTIMER_VAL * 1000) / 272);
01461         writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_RX]);
01462 
01463         val64 = 0;
01464         writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_EINTA]);
01465         writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_EINTA]);
01466         writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_EINTA]);
01467         writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_BMAP]);
01468         writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_BMAP]);
01469         writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_BMAP]);
01470 
01471         return status;
01472 }
01473 
01474 /*
01475  * __vxge_hw_vpath_initialize
01476  * This routine is the final phase of init which initializes the
01477  * registers of the vpath using the configuration passed.
01478  */
01479 enum vxge_hw_status
01480 __vxge_hw_vpath_initialize(struct __vxge_hw_device *hldev, u32 vp_id)
01481 {
01482         u64 val64;
01483         u32 val32;
01484         int i;
01485         enum vxge_hw_status status = VXGE_HW_OK;
01486         struct __vxge_hw_virtualpath *vpath;
01487         struct vxge_hw_vpath_reg *vp_reg;
01488 
01489         vxge_trace();
01490 
01491         vpath = &hldev->virtual_path;
01492 
01493         if (!(hldev->vpath_assignments & vxge_mBIT(vp_id))) {
01494                 status = VXGE_HW_ERR_VPATH_NOT_AVAILABLE;
01495                 goto exit;
01496         }
01497         vp_reg = vpath->vp_reg;
01498         status = __vxge_hw_legacy_swapper_set(hldev->legacy_reg);
01499         if (status != VXGE_HW_OK)
01500                 goto exit;
01501 
01502         status = __vxge_hw_vpath_swapper_set(vpath->vp_reg);
01503 
01504         if (status != VXGE_HW_OK)
01505                 goto exit;
01506         val64 = readq(&vpath->vpmgmt_reg->xmac_vsport_choices_vp);
01507 
01508         for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
01509                 if (val64 & vxge_mBIT(i))
01510                         vpath->vsport_number = i;
01511         }
01512 
01513         status = __vxge_hw_vpath_mac_configure(hldev);
01514 
01515         if (status != VXGE_HW_OK)
01516                 goto exit;
01517 
01518         status = __vxge_hw_vpath_kdfc_configure(hldev, vp_id);
01519 
01520         if (status != VXGE_HW_OK)
01521                 goto exit;
01522 
01523         status = __vxge_hw_vpath_tim_configure(hldev, vp_id);
01524 
01525         if (status != VXGE_HW_OK)
01526                 goto exit;
01527 
01528         val64 = readq(&vp_reg->rtdma_rd_optimization_ctrl);
01529 
01530         /* Get MRRS value from device control */
01531         status = __vxge_hw_vpath_pci_read(vpath, 1, 0x78, &val32);
01532 
01533         if (status == VXGE_HW_OK) {
01534                 val32 = (val32 & VXGE_HW_PCI_EXP_DEVCTL_READRQ) >> 12;
01535                 val64 &=
01536                     ~(VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(7));
01537                 val64 |=
01538                     VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(val32);
01539 
01540                 val64 |= VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_WAIT_FOR_SPACE;
01541         }
01542 
01543         val64 &= ~(VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY(7));
01544         val64 |=
01545             VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY(
01546                     VXGE_HW_MAX_PAYLOAD_SIZE_512);
01547 
01548         val64 |= VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY_EN;
01549         writeq(val64, &vp_reg->rtdma_rd_optimization_ctrl);
01550 
01551 exit:
01552         return status;
01553 }
01554 
01555 /*
01556  * __vxge_hw_vp_initialize - Initialize Virtual Path structure
01557  * This routine is the initial phase of init which resets the vpath and
01558  * initializes the software support structures.
01559  */
01560 enum vxge_hw_status
01561 __vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id,
01562                         struct __vxge_hw_virtualpath *vpath)
01563 {
01564         enum vxge_hw_status status = VXGE_HW_OK;
01565 
01566         vxge_trace();
01567 
01568         if (!(hldev->vpath_assignments & vxge_mBIT(vp_id))) {
01569                 status = VXGE_HW_ERR_VPATH_NOT_AVAILABLE;
01570                 goto exit;
01571         }
01572 
01573         vpath->vp_id = vp_id;
01574         vpath->vp_open = VXGE_HW_VP_OPEN;
01575         vpath->hldev = hldev;
01576         vpath->vp_reg = hldev->vpath_reg[vp_id];
01577         vpath->vpmgmt_reg = hldev->vpmgmt_reg[vp_id];
01578 
01579         __vxge_hw_vpath_reset(hldev, vp_id);
01580 
01581         status = __vxge_hw_vpath_reset_check(vpath);
01582         if (status != VXGE_HW_OK) {
01583                 memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
01584                 goto exit;
01585         }
01586 
01587         VXGE_HW_DEVICE_TIM_INT_MASK_SET(hldev->tim_int_mask0,
01588                 hldev->tim_int_mask1, vp_id);
01589 
01590         status = __vxge_hw_vpath_initialize(hldev, vp_id);
01591 
01592         if (status != VXGE_HW_OK) {
01593                 __vxge_hw_vp_terminate(hldev, vpath);
01594                 goto exit;
01595         }
01596 
01597         status = __vxge_hw_vpath_mgmt_read(vpath);
01598 exit:
01599         return status;
01600 }
01601 
01602 /*
01603  * __vxge_hw_vp_terminate - Terminate Virtual Path structure
01604  * This routine closes all channels it opened and freeup memory
01605  */
01606 void
01607 __vxge_hw_vp_terminate(struct __vxge_hw_device *hldev,
01608                         struct __vxge_hw_virtualpath *vpath)
01609 {
01610         vxge_trace();
01611 
01612         if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN)
01613                 return;
01614 
01615         VXGE_HW_DEVICE_TIM_INT_MASK_RESET(hldev->tim_int_mask0,
01616                 hldev->tim_int_mask1, vpath->vp_id);
01617 
01618         memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
01619 }
01620 
01621 /*
01622  * vxge_hw_vpath_mtu_set - Set MTU.
01623  * Set new MTU value. Example, to use jumbo frames:
01624  * vxge_hw_vpath_mtu_set(my_device, 9600);
01625  */
01626 enum vxge_hw_status
01627 vxge_hw_vpath_mtu_set(struct __vxge_hw_virtualpath *vpath, u32 new_mtu)
01628 {
01629         u64 val64;
01630         enum vxge_hw_status status = VXGE_HW_OK;
01631 
01632         vxge_trace();
01633 
01634         new_mtu += VXGE_HW_MAC_HEADER_MAX_SIZE;
01635 
01636         if ((new_mtu < VXGE_HW_MIN_MTU) || (new_mtu > vpath->max_mtu))
01637                 status = VXGE_HW_ERR_INVALID_MTU_SIZE;
01638 
01639         val64 = readq(&vpath->vp_reg->rxmac_vcfg0);
01640 
01641         val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff);
01642         val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(new_mtu);
01643 
01644         writeq(val64, &vpath->vp_reg->rxmac_vcfg0);
01645 
01646         return status;
01647 }
01648 
01649 /*
01650  * vxge_hw_vpath_open - Open a virtual path on a given adapter
01651  * This function is used to open access to virtual path of an
01652  * adapter for offload, GRO operations. This function returns
01653  * synchronously.
01654  */
01655 enum vxge_hw_status
01656 vxge_hw_vpath_open(struct __vxge_hw_device *hldev, struct vxge_vpath *vpath)
01657 {
01658         struct __vxge_hw_virtualpath *vpathh;
01659         enum vxge_hw_status status;
01660 
01661         vxge_trace();
01662 
01663         vpathh = &hldev->virtual_path;
01664 
01665         if (vpath->vp_open == VXGE_HW_VP_OPEN) {
01666                 status = VXGE_HW_ERR_INVALID_STATE;
01667                 goto vpath_open_exit1;
01668         }
01669 
01670         status = __vxge_hw_vp_initialize(hldev, hldev->first_vp_id, vpathh);
01671         if (status != VXGE_HW_OK)
01672                 goto vpath_open_exit1;
01673 
01674         status = __vxge_hw_fifo_create(vpathh, &vpathh->fifoh);
01675         if (status != VXGE_HW_OK)
01676                 goto vpath_open_exit2;
01677 
01678         status = __vxge_hw_ring_create(vpathh, &vpathh->ringh);
01679         if (status != VXGE_HW_OK)
01680                 goto vpath_open_exit3;
01681 
01682         __vxge_hw_vpath_prc_configure(hldev);
01683 
01684         return VXGE_HW_OK;
01685 
01686 vpath_open_exit3:
01687         __vxge_hw_fifo_delete(&vpathh->fifoh);
01688 vpath_open_exit2:
01689         __vxge_hw_vp_terminate(hldev, vpathh);
01690 vpath_open_exit1:
01691         return status;
01692 }
01693 
01694 /*
01695  * vxge_hw_vpath_rx_doorbell_init -  Post the count of the refreshed region
01696  * of RxD list
01697  * @vp: vpath handle
01698  *
01699  * This function decides on the Rxd replenish count depending on the
01700  * descriptor memory that has been allocated to this VPath.
01701  */
01702 void
01703 vxge_hw_vpath_rx_doorbell_init(struct __vxge_hw_virtualpath *vpath)
01704 {
01705         u64 new_count, val64;
01706 
01707         vxge_trace();
01708 
01709         if (vpath->hldev->titan1) {
01710                 new_count = readq(&vpath->vp_reg->rxdmem_size);
01711                 new_count &= 0x1fff;
01712         } else
01713                 new_count = VXGE_HW_RING_RXD_QWORDS_MODE_1 * 4;
01714 
01715         val64 = (VXGE_HW_RXDMEM_SIZE_PRC_RXDMEM_SIZE(new_count));
01716 
01717         writeq(VXGE_HW_PRC_RXD_DOORBELL_NEW_QW_CNT(val64),
01718                 &vpath->vp_reg->prc_rxd_doorbell);
01719 }
01720 
01721 /*
01722  * vxge_hw_vpath_close - Close the handle got from previous vpath (vpath) open
01723  * This function is used to close access to virtual path opened
01724  * earlier.
01725  */
01726 enum vxge_hw_status vxge_hw_vpath_close(struct __vxge_hw_virtualpath *vpath)
01727 {
01728         struct __vxge_hw_device *devh = NULL;
01729         u32 vp_id = vpath->vp_id;
01730         enum vxge_hw_status status = VXGE_HW_OK;
01731 
01732         vxge_trace();
01733 
01734         devh = vpath->hldev;
01735 
01736         if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
01737                 status = VXGE_HW_ERR_VPATH_NOT_OPEN;
01738                 goto vpath_close_exit;
01739         }
01740 
01741         devh->vpaths_deployed &= ~vxge_mBIT(vp_id);
01742 
01743         __vxge_hw_ring_delete(&vpath->ringh);
01744 
01745         __vxge_hw_fifo_delete(&vpath->fifoh);
01746 
01747         __vxge_hw_vp_terminate(devh, vpath);
01748 
01749         vpath->vp_open = VXGE_HW_VP_NOT_OPEN;
01750 
01751 vpath_close_exit:
01752         return status;
01753 }
01754 
01755 /*
01756  * vxge_hw_vpath_reset - Resets vpath
01757  * This function is used to request a reset of vpath
01758  */
01759 enum vxge_hw_status vxge_hw_vpath_reset(struct __vxge_hw_virtualpath *vpath)
01760 {
01761         enum vxge_hw_status status;
01762         u32 vp_id;
01763 
01764         vxge_trace();
01765 
01766         vp_id = vpath->vp_id;
01767 
01768         if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
01769                 status = VXGE_HW_ERR_VPATH_NOT_OPEN;
01770                 goto exit;
01771         }
01772 
01773         status = __vxge_hw_vpath_reset(vpath->hldev, vp_id);
01774 exit:
01775         return status;
01776 }
01777 
01778 /*
01779  * vxge_hw_vpath_recover_from_reset - Poll for reset complete and re-initialize.
01780  * This function poll's for the vpath reset completion and re initializes
01781  * the vpath.
01782  */
01783 enum vxge_hw_status
01784 vxge_hw_vpath_recover_from_reset(struct __vxge_hw_virtualpath *vpath)
01785 {
01786         enum vxge_hw_status status;
01787         struct __vxge_hw_device *hldev;
01788         u32 vp_id;
01789 
01790         vxge_trace();
01791 
01792         vp_id = vpath->vp_id;
01793         hldev = vpath->hldev;
01794 
01795         if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
01796                 status = VXGE_HW_ERR_VPATH_NOT_OPEN;
01797                 goto exit;
01798         }
01799 
01800         status = __vxge_hw_vpath_reset_check(vpath);
01801         if (status != VXGE_HW_OK)
01802                 goto exit;
01803 
01804         status = __vxge_hw_vpath_initialize(hldev, vp_id);
01805         if (status != VXGE_HW_OK)
01806                 goto exit;
01807 
01808         __vxge_hw_vpath_prc_configure(hldev);
01809 
01810 exit:
01811         return status;
01812 }
01813 
01814 /*
01815  * vxge_hw_vpath_enable - Enable vpath.
01816  * This routine clears the vpath reset thereby enabling a vpath
01817  * to start forwarding frames and generating interrupts.
01818  */
01819 void
01820 vxge_hw_vpath_enable(struct __vxge_hw_virtualpath *vpath)
01821 {
01822         struct __vxge_hw_device *hldev;
01823         u64 val64;
01824 
01825         vxge_trace();
01826 
01827         hldev = vpath->hldev;
01828 
01829         val64 = VXGE_HW_CMN_RSTHDLR_CFG1_CLR_VPATH_RESET(
01830                 1 << (16 - vpath->vp_id));
01831 
01832         __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32),
01833                 &hldev->common_reg->cmn_rsthdlr_cfg1);
01834 }

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