u64 bar;\r
int n_supported;\r
PHYSICAL_ADDRESS pa;\r
- ULONG capOffset, bir;\r
+ ULONG cap_offset, bir;\r
PPCI_MSIX_CAPABILITY pPciMsixCap;\r
\r
MLX4_ENTER( MLX4_DBG_PNP );\r
\r
/* find capability */\r
- capOffset = __find_capability( p_cfg, PCI_CAPABILITY_ID_MSIX );\r
- if( !capOffset ) {\r
+ cap_offset = __find_capability( p_cfg, PCI_CAPABILITY_ID_MSIX );\r
+ if( !cap_offset ) {\r
p_info->valid = 0;\r
return 0;\r
} \r
- pPciMsixCap = (PPCI_MSIX_CAPABILITY)(((UCHAR*)p_cfg) + capOffset);\r
+ pPciMsixCap = (PPCI_MSIX_CAPABILITY)(((UCHAR*)p_cfg) + cap_offset);\r
n_supported = MSIX_FLAGS_SUPPORTED(pPciMsixCap->Flags) + 1;\r
p_info->num = n_supported;\r
\r
memset(pMsixInfo,0,sizeof(struct msix_saved_info));\r
}\r
\r
+static NTSTATUS __read_vpd_dword(\r
+ IN BUS_INTERFACE_STANDARD *pBusIfc,\r
+ IN ULONG cap_offset,\r
+ IN ULONG offset,\r
+ OUT UCHAR *p_data\r
+ )\r
+{\r
+ ULONG len;\r
+ USHORT addr = (USHORT)offset;\r
+\r
+ /* write offset inside VPD data */\r
+ len = pBusIfc->SetBusData( pBusIfc->Context, PCI_WHICHSPACE_CONFIG, &addr, cap_offset+2,2 );\r
+ if ( len != 2 ) \r
+ goto err_write;\r
+\r
+ /* wait for data to be put in the data register */\r
+ while ( !(addr & 0x8000) ) {\r
+ len = pBusIfc->GetBusData( pBusIfc->Context, PCI_WHICHSPACE_CONFIG, &addr, cap_offset+2, 2 );\r
+ if ( len != 2 )\r
+ goto err_read;\r
+ } \r
+\r
+ /* get the tag value */\r
+ len = pBusIfc->GetBusData( pBusIfc->Context, PCI_WHICHSPACE_CONFIG, p_data, cap_offset+4, 4 );\r
+ if ( len != 4 )\r
+ goto err_read;\r
+\r
+ return STATUS_SUCCESS;\r
+ \r
+err_write:\r
+ MLX4_PRINT( TRACE_LEVEL_ERROR , MLX4_DBG_PNP , \r
+ ("Failed to write HCA config. \n" )); \r
+ return STATUS_DEVICE_NOT_READY;\r
+\r
+err_read: \r
+ MLX4_PRINT( TRACE_LEVEL_ERROR , MLX4_DBG_PNP , \r
+ ("Failed to read HCA config. \n" )); \r
+ return STATUS_DEVICE_NOT_READY;\r
+}\r
+\r
+\r
+#define MAX_VPD_SIZE (1 << 16)\r
+\r
+NTSTATUS pci_get_vpd(\r
+ IN BUS_INTERFACE_STANDARD *pBusIfc,\r
+ IN PCI_COMMON_CONFIG* const pConfig,\r
+ OUT UCHAR* *p_vpd,\r
+ IN OUT int* p_vpd_size\r
+ )\r
+{\r
+ PCI_VPD_CAPABILITY *pPciVpdCap;\r
+ ULONG cap_offset;\r
+ NTSTATUS status = STATUS_SUCCESS;\r
+ int vpd_size = 0;\r
+ UCHAR *vpd = NULL;\r
+\r
+ *p_vpd = NULL;\r
+ *p_vpd_size = 0;\r
+\r
+ cap_offset = __find_capability( pConfig, PCI_CAPABILITY_ID_VPD );\r
+ if( cap_offset ) {\r
+ ULONG offset;\r
+ pPciVpdCap = (PCI_VPD_CAPABILITY*)(((UCHAR*)pConfig) + cap_offset);\r
+\r
+ /* allocate temp buffer */\r
+ vpd = kmalloc( MAX_VPD_SIZE, GFP_KERNEL);\r
+ if ( !vpd ) {\r
+ MLX4_PRINT( TRACE_LEVEL_ERROR , MLX4_DBG_PNP ,\r
+ ("Failed to allocate VPD buffer of size %d.\n", MAX_VPD_SIZE));\r
+ return STATUS_UNSUCCESSFUL;\r
+ }\r
+ \r
+ /* read VPD */\r
+ for ( offset = 0; offset < MAX_VPD_SIZE; offset += 0x4 ) {\r
+ status = __read_vpd_dword( pBusIfc, cap_offset,\r
+ offset, vpd + offset);\r
+ if( !NT_SUCCESS( status ) ) {\r
+ kfree( vpd );\r
+ return STATUS_UNSUCCESSFUL;\r
+ }\r
+ }\r
+ /* find the size */\r
+ for ( offset = 0; offset < MAX_VPD_SIZE; ) {\r
+ ULONG size;\r
+ if ( vpd[offset] == 0x78 ) {\r
+ vpd_size = offset + 1;\r
+ break;\r
+ }\r
+ if ( vpd[offset] & 0x80 ) { /* Large Resource Type */ \r
+ size = *(PUSHORT)(&vpd[offset+1]);\r
+ offset += size + 3; \r
+ }\r
+ else { /* Small Resource Type */\r
+ size = vpd[offset] & 7;\r
+ offset += size + 1; \r
+ }\r
+ }\r
+ /* shorten the VPD array */\r
+ if ( offset >= MAX_VPD_SIZE ) {\r
+ /* we didn't found VPD end. We'll keep it all */\r
+ *p_vpd = vpd;\r
+ *p_vpd_size = MAX_VPD_SIZE;\r
+ }\r
+ else {\r
+ /* allocate VPD */\r
+ if ( vpd_size ) {\r
+ *p_vpd = kmalloc( vpd_size, GFP_KERNEL);\r
+ if ( !*p_vpd ) {\r
+ *p_vpd = vpd;\r
+ *p_vpd_size = MAX_VPD_SIZE;\r
+ }\r
+ else {\r
+ memcpy( *p_vpd, vpd, vpd_size );\r
+ *p_vpd_size = vpd_size;\r
+ kfree( vpd );\r
+ }\r
+ }\r
+ else {\r
+ MLX4_PRINT( TRACE_LEVEL_ERROR , MLX4_DBG_PNP ,\r
+ ("VPD starts from end tag.\n"));\r
+ kfree( vpd );\r
+ status = STATUS_UNSUCCESSFUL;\r
+ }\r
+ }\r
+ MLX4_PRINT( TRACE_LEVEL_WARNING , MLX4_DBG_PNP ,\r
+ ("Found VPD of size %d, beginning with '%s'\n", *p_vpd_size, &vpd[3]));\r
+ }\r
+ else {\r
+ MLX4_PRINT( TRACE_LEVEL_ERROR , MLX4_DBG_PNP ,("Failed to find VPD capability.\n"));\r
+ status = STATUS_UNSUCCESSFUL;\r
+ }\r
+\r
+ return status;\r
+}\r
+\r
/*\r
* Reads and saves the PCI configuration of the device accessible\r
* through the provided bus interface. Does not read registers 22 or 23\r
- * as directed in PRM , Appendix A. Software Reset.\r
+ * as directed in Tavor PRM 1.0.1, Appendix A. InfiniHost Software Reset.\r
*/\r
NTSTATUS\r
pci_save_config(\r
IN BUS_INTERFACE_STANDARD *pBusIfc,\r
- OUT PCI_COMMON_CONFIG* const pConfig)\r
+ OUT PCI_COMMON_CONFIG* const pConfig )\r
{\r
ULONG len;\r
UINT32 *pBuf;\r
OUT PCI_COMMON_CONFIG * p_cfg,\r
OUT uplink_info_t * p_uplink_info )\r
{\r
- ULONG capOffset;\r
+ ULONG cap_offset;\r
NTSTATUS status;\r
BUS_INTERFACE_STANDARD *pBusIfc = &pdev->bus_pci_ifc;\r
\r
\r
// PCI MSI-X Capability\r
memset( &p_uplink_info->x, 0, sizeof(p_uplink_info->x) );\r
- capOffset = __find_capability( p_cfg, PCI_CAPABILITY_ID_MSIX );\r
- if( capOffset ) {\r
+ cap_offset = __find_capability( p_cfg, PCI_CAPABILITY_ID_MSIX );\r
+ if( cap_offset ) {\r
PVOID ka;\r
ULONG sz;\r
PHYSICAL_ADDRESS pa;\r
PPCI_MSIX_VECTOR p_vector;\r
PPCI_MSIX_PENDING p_pend;\r
ULONG granted_mask = 0;\r
- PPCI_MSIX_CAPABILITY pPciMsixCap = (PPCI_MSIX_CAPABILITY)(((UCHAR*)p_cfg) + capOffset);\r
+ PPCI_MSIX_CAPABILITY pPciMsixCap = (PPCI_MSIX_CAPABILITY)(((UCHAR*)p_cfg) + cap_offset);\r
USHORT flags = pPciMsixCap->Flags;\r
ULONG table_bir = MSIX_OFFSET_BIR(pPciMsixCap->Table_Offset);\r
ULONG pend_bir = MSIX_OFFSET_BIR(pPciMsixCap->PBA_Offset);\r
IN PCI_COMMON_CONFIG * p_cfg,\r
OUT uplink_info_t * p_uplink_info )\r
{\r
- ULONG capOffset;\r
+ ULONG cap_offset;\r
PCI_PCIX_CAPABILITY *pPciXCap;\r
PCI_PCIEXP_CAPABILITY *pPciExpCap;\r
\r
MLX4_ENTER( MLX4_DBG_PNP );\r
\r
// PCIX Capability\r
- capOffset = __find_capability( p_cfg, PCI_CAPABILITY_ID_PCIX );\r
- if( capOffset ) {\r
- pPciXCap = (PCI_PCIX_CAPABILITY*)(((UCHAR*)p_cfg) + capOffset);\r
+ cap_offset = __find_capability( p_cfg, PCI_CAPABILITY_ID_PCIX );\r
+ if( cap_offset ) {\r
+ pPciXCap = (PCI_PCIX_CAPABILITY*)(((UCHAR*)p_cfg) + cap_offset);\r
\r
p_uplink_info->bus_type = UPLINK_BUS_PCIX;\r
if (pPciXCap->Status & (1 << 17))\r
}\r
\r
// PCI Express Capability\r
- capOffset = __find_capability( p_cfg, PCI_CAPABILITY_ID_PCI_EXPRESS );\r
- if( capOffset ) {\r
- pPciExpCap = (PCI_PCIEXP_CAPABILITY*)(((UCHAR*)p_cfg) + capOffset);\r
+ cap_offset = __find_capability( p_cfg, PCI_CAPABILITY_ID_PCI_EXPRESS );\r
+ if( cap_offset ) {\r
+ pPciExpCap = (PCI_PCIEXP_CAPABILITY*)(((UCHAR*)p_cfg) + cap_offset);\r
\r
p_uplink_info->bus_type = UPLINK_BUS_PCIE;\r
if ((pPciExpCap->LinkStatus & 15) == 1)\r