ipath_mad.c
来自「LINUX 2.6.17.4的源码」· C语言 代码 · 共 1,353 行 · 第 1/3 页
C
1,353 行
if (cntrs.symbol_error_counter > 0xFFFFUL) p->symbol_error_counter = __constant_cpu_to_be16(0xFFFF); else p->symbol_error_counter = cpu_to_be16((u16)cntrs.symbol_error_counter); if (cntrs.link_error_recovery_counter > 0xFFUL) p->link_error_recovery_counter = 0xFF; else p->link_error_recovery_counter = (u8)cntrs.link_error_recovery_counter; if (cntrs.link_downed_counter > 0xFFUL) p->link_downed_counter = 0xFF; else p->link_downed_counter = (u8)cntrs.link_downed_counter; if (cntrs.port_rcv_errors > 0xFFFFUL) p->port_rcv_errors = __constant_cpu_to_be16(0xFFFF); else p->port_rcv_errors = cpu_to_be16((u16) cntrs.port_rcv_errors); if (cntrs.port_rcv_remphys_errors > 0xFFFFUL) p->port_rcv_remphys_errors = __constant_cpu_to_be16(0xFFFF); else p->port_rcv_remphys_errors = cpu_to_be16((u16)cntrs.port_rcv_remphys_errors); if (cntrs.port_xmit_discards > 0xFFFFUL) p->port_xmit_discards = __constant_cpu_to_be16(0xFFFF); else p->port_xmit_discards = cpu_to_be16((u16)cntrs.port_xmit_discards); if (cntrs.port_xmit_data > 0xFFFFFFFFUL) p->port_xmit_data = __constant_cpu_to_be32(0xFFFFFFFF); else p->port_xmit_data = cpu_to_be32((u32)cntrs.port_xmit_data); if (cntrs.port_rcv_data > 0xFFFFFFFFUL) p->port_rcv_data = __constant_cpu_to_be32(0xFFFFFFFF); else p->port_rcv_data = cpu_to_be32((u32)cntrs.port_rcv_data); if (cntrs.port_xmit_packets > 0xFFFFFFFFUL) p->port_xmit_packets = __constant_cpu_to_be32(0xFFFFFFFF); else p->port_xmit_packets = cpu_to_be32((u32)cntrs.port_xmit_packets); if (cntrs.port_rcv_packets > 0xFFFFFFFFUL) p->port_rcv_packets = __constant_cpu_to_be32(0xFFFFFFFF); else p->port_rcv_packets = cpu_to_be32((u32) cntrs.port_rcv_packets); return reply((struct ib_smp *) pmp);}static int recv_pma_get_portcounters_ext(struct ib_perf *pmp, struct ib_device *ibdev, u8 port){ struct ib_pma_portcounters_ext *p = (struct ib_pma_portcounters_ext *)pmp->data; struct ipath_ibdev *dev = to_idev(ibdev); u64 swords, rwords, spkts, rpkts, xwait; u8 port_select = p->port_select; ipath_layer_snapshot_counters(dev->dd, &swords, &rwords, &spkts, &rpkts, &xwait); /* Adjust counters for any resets done. */ swords -= dev->n_port_xmit_data; rwords -= dev->n_port_rcv_data; spkts -= dev->n_port_xmit_packets; rpkts -= dev->n_port_rcv_packets; memset(pmp->data, 0, sizeof(pmp->data)); p->port_select = port_select; if (pmp->attr_mod != 0 || (port_select != port && port_select != 0xFF)) pmp->status |= IB_SMP_INVALID_FIELD; p->port_xmit_data = cpu_to_be64(swords); p->port_rcv_data = cpu_to_be64(rwords); p->port_xmit_packets = cpu_to_be64(spkts); p->port_rcv_packets = cpu_to_be64(rpkts); p->port_unicast_xmit_packets = cpu_to_be64(dev->n_unicast_xmit); p->port_unicast_rcv_packets = cpu_to_be64(dev->n_unicast_rcv); p->port_multicast_xmit_packets = cpu_to_be64(dev->n_multicast_xmit); p->port_multicast_rcv_packets = cpu_to_be64(dev->n_multicast_rcv); return reply((struct ib_smp *) pmp);}static int recv_pma_set_portcounters(struct ib_perf *pmp, struct ib_device *ibdev, u8 port){ struct ib_pma_portcounters *p = (struct ib_pma_portcounters *) pmp->data; struct ipath_ibdev *dev = to_idev(ibdev); struct ipath_layer_counters cntrs; /* * Since the HW doesn't support clearing counters, we save the * current count and subtract it from future responses. */ ipath_layer_get_counters(dev->dd, &cntrs); if (p->counter_select & IB_PMA_SEL_SYMBOL_ERROR) dev->n_symbol_error_counter = cntrs.symbol_error_counter; if (p->counter_select & IB_PMA_SEL_LINK_ERROR_RECOVERY) dev->n_link_error_recovery_counter = cntrs.link_error_recovery_counter; if (p->counter_select & IB_PMA_SEL_LINK_DOWNED) dev->n_link_downed_counter = cntrs.link_downed_counter; if (p->counter_select & IB_PMA_SEL_PORT_RCV_ERRORS) dev->n_port_rcv_errors = cntrs.port_rcv_errors + dev->rcv_errors; if (p->counter_select & IB_PMA_SEL_PORT_RCV_REMPHYS_ERRORS) dev->n_port_rcv_remphys_errors = cntrs.port_rcv_remphys_errors; if (p->counter_select & IB_PMA_SEL_PORT_XMIT_DISCARDS) dev->n_port_xmit_discards = cntrs.port_xmit_discards; if (p->counter_select & IB_PMA_SEL_PORT_XMIT_DATA) dev->n_port_xmit_data = cntrs.port_xmit_data; if (p->counter_select & IB_PMA_SEL_PORT_RCV_DATA) dev->n_port_rcv_data = cntrs.port_rcv_data; if (p->counter_select & IB_PMA_SEL_PORT_XMIT_PACKETS) dev->n_port_xmit_packets = cntrs.port_xmit_packets; if (p->counter_select & IB_PMA_SEL_PORT_RCV_PACKETS) dev->n_port_rcv_packets = cntrs.port_rcv_packets; return recv_pma_get_portcounters(pmp, ibdev, port);}static int recv_pma_set_portcounters_ext(struct ib_perf *pmp, struct ib_device *ibdev, u8 port){ struct ib_pma_portcounters *p = (struct ib_pma_portcounters *) pmp->data; struct ipath_ibdev *dev = to_idev(ibdev); u64 swords, rwords, spkts, rpkts, xwait; ipath_layer_snapshot_counters(dev->dd, &swords, &rwords, &spkts, &rpkts, &xwait); if (p->counter_select & IB_PMA_SELX_PORT_XMIT_DATA) dev->n_port_xmit_data = swords; if (p->counter_select & IB_PMA_SELX_PORT_RCV_DATA) dev->n_port_rcv_data = rwords; if (p->counter_select & IB_PMA_SELX_PORT_XMIT_PACKETS) dev->n_port_xmit_packets = spkts; if (p->counter_select & IB_PMA_SELX_PORT_RCV_PACKETS) dev->n_port_rcv_packets = rpkts; if (p->counter_select & IB_PMA_SELX_PORT_UNI_XMIT_PACKETS) dev->n_unicast_xmit = 0; if (p->counter_select & IB_PMA_SELX_PORT_UNI_RCV_PACKETS) dev->n_unicast_rcv = 0; if (p->counter_select & IB_PMA_SELX_PORT_MULTI_XMIT_PACKETS) dev->n_multicast_xmit = 0; if (p->counter_select & IB_PMA_SELX_PORT_MULTI_RCV_PACKETS) dev->n_multicast_rcv = 0; return recv_pma_get_portcounters_ext(pmp, ibdev, port);}static int process_subn(struct ib_device *ibdev, int mad_flags, u8 port_num, struct ib_mad *in_mad, struct ib_mad *out_mad){ struct ib_smp *smp = (struct ib_smp *)out_mad; struct ipath_ibdev *dev = to_idev(ibdev); int ret; *out_mad = *in_mad; if (smp->class_version != 1) { smp->status |= IB_SMP_UNSUP_VERSION; ret = reply(smp); goto bail; } /* Is the mkey in the process of expiring? */ if (dev->mkey_lease_timeout && jiffies >= dev->mkey_lease_timeout) { /* Clear timeout and mkey protection field. */ dev->mkey_lease_timeout = 0; dev->mkeyprot_resv_lmc &= 0x3F; } /* * M_Key checking depends on * Portinfo:M_Key_protect_bits */ if ((mad_flags & IB_MAD_IGNORE_MKEY) == 0 && dev->mkey != 0 && dev->mkey != smp->mkey && (smp->method == IB_MGMT_METHOD_SET || (smp->method == IB_MGMT_METHOD_GET && (dev->mkeyprot_resv_lmc >> 7) != 0))) { if (dev->mkey_violations != 0xFFFF) ++dev->mkey_violations; if (dev->mkey_lease_timeout || dev->mkey_lease_period == 0) { ret = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED; goto bail; } dev->mkey_lease_timeout = jiffies + dev->mkey_lease_period * HZ; /* Future: Generate a trap notice. */ ret = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED; goto bail; } else if (dev->mkey_lease_timeout) dev->mkey_lease_timeout = 0; switch (smp->method) { case IB_MGMT_METHOD_GET: switch (smp->attr_id) { case IB_SMP_ATTR_NODE_DESC: ret = recv_subn_get_nodedescription(smp, ibdev); goto bail; case IB_SMP_ATTR_NODE_INFO: ret = recv_subn_get_nodeinfo(smp, ibdev, port_num); goto bail; case IB_SMP_ATTR_GUID_INFO: ret = recv_subn_get_guidinfo(smp, ibdev); goto bail; case IB_SMP_ATTR_PORT_INFO: ret = recv_subn_get_portinfo(smp, ibdev, port_num); goto bail; case IB_SMP_ATTR_PKEY_TABLE: ret = recv_subn_get_pkeytable(smp, ibdev); goto bail; case IB_SMP_ATTR_SM_INFO: if (dev->port_cap_flags & IB_PORT_SM_DISABLED) { ret = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED; goto bail; } if (dev->port_cap_flags & IB_PORT_SM) { ret = IB_MAD_RESULT_SUCCESS; goto bail; } /* FALLTHROUGH */ default: smp->status |= IB_SMP_UNSUP_METH_ATTR; ret = reply(smp); goto bail; } case IB_MGMT_METHOD_SET: switch (smp->attr_id) { case IB_SMP_ATTR_GUID_INFO: ret = recv_subn_set_guidinfo(smp, ibdev); goto bail; case IB_SMP_ATTR_PORT_INFO: ret = recv_subn_set_portinfo(smp, ibdev, port_num); goto bail; case IB_SMP_ATTR_PKEY_TABLE: ret = recv_subn_set_pkeytable(smp, ibdev); goto bail; case IB_SMP_ATTR_SM_INFO: if (dev->port_cap_flags & IB_PORT_SM_DISABLED) { ret = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED; goto bail; } if (dev->port_cap_flags & IB_PORT_SM) { ret = IB_MAD_RESULT_SUCCESS; goto bail; } /* FALLTHROUGH */ default: smp->status |= IB_SMP_UNSUP_METH_ATTR; ret = reply(smp); goto bail; } case IB_MGMT_METHOD_GET_RESP: /* * The ib_mad module will call us to process responses * before checking for other consumers. * Just tell the caller to process it normally. */ ret = IB_MAD_RESULT_FAILURE; goto bail; default: smp->status |= IB_SMP_UNSUP_METHOD; ret = reply(smp); }bail: return ret;}static int process_perf(struct ib_device *ibdev, u8 port_num, struct ib_mad *in_mad, struct ib_mad *out_mad){ struct ib_perf *pmp = (struct ib_perf *)out_mad; int ret; *out_mad = *in_mad; if (pmp->class_version != 1) { pmp->status |= IB_SMP_UNSUP_VERSION; ret = reply((struct ib_smp *) pmp); goto bail; } switch (pmp->method) { case IB_MGMT_METHOD_GET: switch (pmp->attr_id) { case IB_PMA_CLASS_PORT_INFO: ret = recv_pma_get_classportinfo(pmp); goto bail; case IB_PMA_PORT_SAMPLES_CONTROL: ret = recv_pma_get_portsamplescontrol(pmp, ibdev, port_num); goto bail; case IB_PMA_PORT_SAMPLES_RESULT: ret = recv_pma_get_portsamplesresult(pmp, ibdev); goto bail; case IB_PMA_PORT_SAMPLES_RESULT_EXT: ret = recv_pma_get_portsamplesresult_ext(pmp, ibdev); goto bail; case IB_PMA_PORT_COUNTERS: ret = recv_pma_get_portcounters(pmp, ibdev, port_num); goto bail; case IB_PMA_PORT_COUNTERS_EXT: ret = recv_pma_get_portcounters_ext(pmp, ibdev, port_num); goto bail; default: pmp->status |= IB_SMP_UNSUP_METH_ATTR; ret = reply((struct ib_smp *) pmp); goto bail; } case IB_MGMT_METHOD_SET: switch (pmp->attr_id) { case IB_PMA_PORT_SAMPLES_CONTROL: ret = recv_pma_set_portsamplescontrol(pmp, ibdev, port_num); goto bail; case IB_PMA_PORT_COUNTERS: ret = recv_pma_set_portcounters(pmp, ibdev, port_num); goto bail; case IB_PMA_PORT_COUNTERS_EXT: ret = recv_pma_set_portcounters_ext(pmp, ibdev, port_num); goto bail; default: pmp->status |= IB_SMP_UNSUP_METH_ATTR; ret = reply((struct ib_smp *) pmp); goto bail; } case IB_MGMT_METHOD_GET_RESP: /* * The ib_mad module will call us to process responses * before checking for other consumers. * Just tell the caller to process it normally. */ ret = IB_MAD_RESULT_FAILURE; goto bail; default: pmp->status |= IB_SMP_UNSUP_METHOD; ret = reply((struct ib_smp *) pmp); }bail: return ret;}/** * ipath_process_mad - process an incoming MAD packet * @ibdev: the infiniband device this packet came in on * @mad_flags: MAD flags * @port_num: the port number this packet came in on * @in_wc: the work completion entry for this packet * @in_grh: the global route header for this packet * @in_mad: the incoming MAD * @out_mad: any outgoing MAD reply * * Returns IB_MAD_RESULT_SUCCESS if this is a MAD that we are not * interested in processing. * * Note that the verbs framework has already done the MAD sanity checks, * and hop count/pointer updating for IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE * MADs. * * This is called by the ib_mad module. */int ipath_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, struct ib_wc *in_wc, struct ib_grh *in_grh, struct ib_mad *in_mad, struct ib_mad *out_mad){ struct ipath_ibdev *dev = to_idev(ibdev); int ret; /* * Snapshot current HW counters to "clear" them. * This should be done when the driver is loaded except that for * some reason we get a zillion errors when brining up the link. */ if (dev->rcv_errors == 0) { struct ipath_layer_counters cntrs; ipath_layer_get_counters(to_idev(ibdev)->dd, &cntrs); dev->rcv_errors++; dev->n_symbol_error_counter = cntrs.symbol_error_counter; dev->n_link_error_recovery_counter = cntrs.link_error_recovery_counter; dev->n_link_downed_counter = cntrs.link_downed_counter; dev->n_port_rcv_errors = cntrs.port_rcv_errors + 1; dev->n_port_rcv_remphys_errors = cntrs.port_rcv_remphys_errors; dev->n_port_xmit_discards = cntrs.port_xmit_discards; dev->n_port_xmit_data = cntrs.port_xmit_data; dev->n_port_rcv_data = cntrs.port_rcv_data; dev->n_port_xmit_packets = cntrs.port_xmit_packets; dev->n_port_rcv_packets = cntrs.port_rcv_packets; } switch (in_mad->mad_hdr.mgmt_class) { case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE: case IB_MGMT_CLASS_SUBN_LID_ROUTED: ret = process_subn(ibdev, mad_flags, port_num, in_mad, out_mad); goto bail; case IB_MGMT_CLASS_PERF_MGMT: ret = process_perf(ibdev, port_num, in_mad, out_mad); goto bail; default: ret = IB_MAD_RESULT_SUCCESS; }bail: return ret;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?