aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mthca/mthca_mad.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-03-26 18:47:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-03-26 18:47:08 -0400
commit39b566eedbe9e35d38502cc5e62ef7abf1aff9c9 (patch)
tree114d963f3eb4e8aff401ed74ae0429aefc55c9fd /drivers/infiniband/hw/mthca/mthca_mad.c
parent39f15003c7b268e4199d5ddce60a6944a74a14b7 (diff)
parent09f98bafea792644f2dea39eb080aa57d854f5b3 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: (30 commits) RDMA/cxgb3: Enforce required firmware IB/mlx4: Unregister IB device prior to CLOSE PORT command mlx4_core: Add link type autosensing mlx4_core: Don't perform SET_PORT command for Ethernet ports RDMA/nes: Handle MPA Reject message properly RDMA/nes: Improve use of PBLs RDMA/nes: Remove LLTX RDMA/nes: Inform hardware that asynchronous event has been handled RDMA/nes: Fix tmp_addr compilation warning RDMA/nes: Report correct vendor_id and vendor_part_id RDMA/nes: Update copyright to new legal entity and year RDMA/nes: Account for freed PBL after HW operation IB: Remove useless ibdev_is_alive() tests from sysfs code IB/sa_query: Fix AH leak due to update_sm_ah() race IB/mad: Fix ib_post_send_mad() returning 0 with no generate send comp IB/mad: initialize mad_agent_priv before putting on lists IB/mad: Fix null pointer dereference in local_completions() IB/mad: Fix RMPP header RRespTime manipulation IB/iser: Remove hard setting of path MTU mlx4_core: Add device IDs for MT25458 10GigE devices ...
Diffstat (limited to 'drivers/infiniband/hw/mthca/mthca_mad.c')
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mad.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c
index 640449582aba..5648659ff0b0 100644
--- a/drivers/infiniband/hw/mthca/mthca_mad.c
+++ b/drivers/infiniband/hw/mthca/mthca_mad.c
@@ -104,7 +104,8 @@ static void update_sm_ah(struct mthca_dev *dev,
104 */ 104 */
105static void smp_snoop(struct ib_device *ibdev, 105static void smp_snoop(struct ib_device *ibdev,
106 u8 port_num, 106 u8 port_num,
107 struct ib_mad *mad) 107 struct ib_mad *mad,
108 u16 prev_lid)
108{ 109{
109 struct ib_event event; 110 struct ib_event event;
110 111
@@ -114,6 +115,7 @@ static void smp_snoop(struct ib_device *ibdev,
114 if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO) { 115 if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO) {
115 struct ib_port_info *pinfo = 116 struct ib_port_info *pinfo =
116 (struct ib_port_info *) ((struct ib_smp *) mad)->data; 117 (struct ib_port_info *) ((struct ib_smp *) mad)->data;
118 u16 lid = be16_to_cpu(pinfo->lid);
117 119
118 mthca_update_rate(to_mdev(ibdev), port_num); 120 mthca_update_rate(to_mdev(ibdev), port_num);
119 update_sm_ah(to_mdev(ibdev), port_num, 121 update_sm_ah(to_mdev(ibdev), port_num,
@@ -123,12 +125,15 @@ static void smp_snoop(struct ib_device *ibdev,
123 event.device = ibdev; 125 event.device = ibdev;
124 event.element.port_num = port_num; 126 event.element.port_num = port_num;
125 127
126 if (pinfo->clientrereg_resv_subnetto & 0x80) 128 if (pinfo->clientrereg_resv_subnetto & 0x80) {
127 event.event = IB_EVENT_CLIENT_REREGISTER; 129 event.event = IB_EVENT_CLIENT_REREGISTER;
128 else 130 ib_dispatch_event(&event);
129 event.event = IB_EVENT_LID_CHANGE; 131 }
130 132
131 ib_dispatch_event(&event); 133 if (prev_lid != lid) {
134 event.event = IB_EVENT_LID_CHANGE;
135 ib_dispatch_event(&event);
136 }
132 } 137 }
133 138
134 if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PKEY_TABLE) { 139 if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PKEY_TABLE) {
@@ -196,6 +201,8 @@ int mthca_process_mad(struct ib_device *ibdev,
196 int err; 201 int err;
197 u8 status; 202 u8 status;
198 u16 slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE); 203 u16 slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
204 u16 prev_lid = 0;
205 struct ib_port_attr pattr;
199 206
200 /* Forward locally generated traps to the SM */ 207 /* Forward locally generated traps to the SM */
201 if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP && 208 if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP &&
@@ -233,6 +240,12 @@ int mthca_process_mad(struct ib_device *ibdev,
233 return IB_MAD_RESULT_SUCCESS; 240 return IB_MAD_RESULT_SUCCESS;
234 } else 241 } else
235 return IB_MAD_RESULT_SUCCESS; 242 return IB_MAD_RESULT_SUCCESS;
243 if ((in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED ||
244 in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) &&
245 in_mad->mad_hdr.method == IB_MGMT_METHOD_SET &&
246 in_mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO &&
247 !ib_query_port(ibdev, port_num, &pattr))
248 prev_lid = pattr.lid;
236 249
237 err = mthca_MAD_IFC(to_mdev(ibdev), 250 err = mthca_MAD_IFC(to_mdev(ibdev),
238 mad_flags & IB_MAD_IGNORE_MKEY, 251 mad_flags & IB_MAD_IGNORE_MKEY,
@@ -252,7 +265,7 @@ int mthca_process_mad(struct ib_device *ibdev,
252 } 265 }
253 266
254 if (!out_mad->mad_hdr.status) { 267 if (!out_mad->mad_hdr.status) {
255 smp_snoop(ibdev, port_num, in_mad); 268 smp_snoop(ibdev, port_num, in_mad, prev_lid);
256 node_desc_override(ibdev, out_mad); 269 node_desc_override(ibdev, out_mad);
257 } 270 }
258 271