#include <complib/cl_pnp_po.h>\r
#include <complib/cl_mutex.h>\r
#include <iba/ib_ci_ifc.h>\r
+#include "mthca/mthca_vc.h"\r
#include "hca_data.h"\r
#include "mt_l2w.h"\r
#include "hca_debug.h"\r
*/\r
NTSTATUS\r
hca_tune_pci(\r
- IN DEVICE_OBJECT* const pDevObj )\r
+ IN DEVICE_OBJECT* const pDevObj,\r
+ OUT uplink_info_t *p_uplink_info )\r
{\r
NTSTATUS status;\r
PCI_COMMON_CONFIG hcaConfig;\r
if( capOffset )\r
{\r
pPciXCap = (PCI_PCIX_CAPABILITY*)(((UCHAR*)&hcaConfig) + capOffset);\r
+\r
+ /* fill uplink features */\r
+ p_uplink_info->bus_type = UPLINK_BUS_PCIX;\r
+ if (pPciXCap->Status & (1 << 17))\r
+ p_uplink_info->u.pci_x.capabilities = UPLINK_BUS_PCIX_133;\r
+ \r
/* Update the command field to max the read byte count if needed. */\r
if( (pPciXCap->Command & 0x000C) != 0x000C )\r
{\r
if( capOffset )\r
{\r
pPciExpCap = (PCI_PCIEXP_CAPABILITY*)(((UCHAR*)&hcaConfig) + capOffset);\r
+\r
+ /* fill uplink features */\r
+ p_uplink_info->bus_type = UPLINK_BUS_PCIE;\r
+ if ((pPciExpCap->LinkStatus & 15) == 1)\r
+ p_uplink_info->u.pci_e.link_speed = UPLINK_BUS_PCIE_SDR;\r
+ p_uplink_info->u.pci_e.link_width = (uint8_t)((pPciExpCap->LinkStatus >> 4) & 0x03f);\r
\r
/* Update Max_Read_Request_Size. */\r
HCA_PRINT( TRACE_LEVEL_WARNING ,HCA_DBG_PNP,\r
IN PBUS_INTERFACE_STANDARD phcaBusIfc);
NTSTATUS
-hca_tune_pci(
- IN DEVICE_OBJECT* const pDevObj );
+ hca_tune_pci(
+ IN DEVICE_OBJECT* const pDevObj,
+ OUT uplink_info_t *p_uplink_info );
#endif
required_size = PTR_ALIGN(sizeof(ib_ca_attr_t)) +\r
PTR_ALIGN(sizeof(uint32_t) * num_page_sizes) +\r
PTR_ALIGN(sizeof(ib_port_attr_t) * num_ports)+\r
- PTR_ALIGN(MTHCA_BOARD_ID_LEN);\r
+ PTR_ALIGN(MTHCA_BOARD_ID_LEN)+\r
+ sizeof(uplink_info_t); /* uplink info */\r
+ \r
// get port properties\r
for (port_num = 0; port_num <= end_port(ib_dev) - start_port(ib_dev); ++port_num) {\r
// request\r
//copy vendor specific data\r
cl_memcpy(last_p,to_mdev(ib_dev)->board_id, MTHCA_BOARD_ID_LEN);\r
last_p += PTR_ALIGN(MTHCA_BOARD_ID_LEN);\r
+ *(uplink_info_t*)last_p = to_mdev(ib_dev)->uplink_info;\r
+ last_p += sizeof(uplink_info_t); /* uplink info */\r
\r
// Separate the loops to ensure that table pointers are always setup\r
for (port_num = 0; port_num < num_ports; port_num++) {\r
struct mthca_dev {
struct ib_device ib_dev;
hca_dev_ext_t *ext;
+ uplink_info_t uplink_info;
int hca_type;
unsigned long mthca_flags;
static NTSTATUS mthca_tune_pci(struct mthca_dev *mdev)
{
PDEVICE_OBJECT pdo = mdev->ext->cl_ext.p_self_do;
- return hca_tune_pci(pdo);
+ return hca_tune_pci(pdo, &mdev->uplink_info);
}
int mthca_get_dev_info(struct mthca_dev *mdev, __be64 *node_guid, u32 *hw_id)
#define FW_OPEN_IF 0xe7
#define FW_CLOSE_IF 0x7e
+/* uplink info */
+typedef struct {
+ uint8_t bus_type; /* 1 - PCI, 2 - PCI-X, 3 - PCI_E */
+#define UPLINK_BUS_PCI 1
+#define UPLINK_BUS_PCIX 2
+#define UPLINK_BUS_PCIE 3
+ union {
+ struct {
+ uint8_t capabilities;
+#define UPLINK_BUS_PCIX_133 2 /* 133 MHz capable */
+ uint16_t frequency; /* in MHz */
+ } pci_x;
+ struct {
+ uint8_t reserve;
+ uint8_t link_speed; /* 1X link speed */
+#define UPLINK_BUS_PCIE_SDR 1 /* 2.5 Gbps */
+ uint8_t link_width; /* x1, x2, x4, x8, x12, x16, x32 */
+ } pci_e;
+ } u;
+} uplink_info_t;
/* Defines for get data for vendor specific */
-#define MTHCA_BOARD_ID_LEN 64
+#define MTHCA_BRD_ID_LEN 64
inline char* mthca_get_board_id(ib_ca_attr_t *ca_attr)
{
- return (char*)(ca_attr)+(ca_attr->size - MTHCA_BOARD_ID_LEN);
+ return (char*)(ca_attr)+(ca_attr->size - MTHCA_BRD_ID_LEN - sizeof(uplink_info_t));
}
+inline void* mthca_get_uplink_info(ib_ca_attr_t *ca_attr)
+{
+ return (char*)(ca_attr)+(ca_attr->size - sizeof(uplink_info_t));
+}
#endif
}\r
\r
\r
+void print_uplink_info(ib_ca_attr_t* ca_attr)\r
+{\r
+ uplink_info_t*p_uplink_info = mthca_get_uplink_info(ca_attr);\r
+ char *bus_type, *link_speed;\r
+ int freq;\r
+\r
+ switch (p_uplink_info->bus_type) {\r
+ case UPLINK_BUS_PCI: bus_type = "PCI"; break;\r
+ case UPLINK_BUS_PCIX: bus_type = "PCI_X"; break;\r
+ case UPLINK_BUS_PCIE: bus_type = "PCI_E"; break;\r
+ default: printf("\tuplink={BUS=UNRECOGNIZED (%d)}\n", p_uplink_info->bus_type); return;\r
+ }\r
\r
+ switch (p_uplink_info->bus_type) {\r
+ case UPLINK_BUS_PCI: \r
+ case UPLINK_BUS_PCIX:\r
+ if (p_uplink_info->u.pci_x.capabilities == UPLINK_BUS_PCIX_133)\r
+ freq = 133;\r
+ else\r
+ freq = 66;\r
+ printf("\tuplink={BUS=%s, CAPS=%d MHz}\n", bus_type, freq ); \r
+ return;\r
+\r
+ case UPLINK_BUS_PCIE:\r
+ if (p_uplink_info->u.pci_e.link_speed == UPLINK_BUS_PCIE_SDR)\r
+ link_speed = "2.5 Gbps";\r
+ else\r
+ link_speed = "unknown";\r
+ printf("\tuplink={BUS=%s, SPEED=%s, WIDTH=x%d}\n",\r
+ bus_type, link_speed, p_uplink_info->u.pci_e.link_width ); \r
+ return;\r
+ }\r
+}\r
\r
void vstat_print_ca_attr(int idx, ib_ca_attr_t* ca_attr, BOOLEAN fullPrint){\r
int i;\r
\r
printf("\n\thca_idx=%d\n",idx);\r
printf("\tpci_location={BUS=NA,DEV/FUNC=NA}\n");\r
+ print_uplink_info(ca_attr);\r
printf("\tvendor_id=0x%04x\n", ca_attr->vend_id);\r
printf("\tvendor_part_id=0x%04x\n", ca_attr->dev_id);\r
printf("\thw_ver=0x%x\n", ca_attr->revision); //TODO: ???\r