|
@@ -1,6 +1,6 @@
|
|
/*
|
|
/*
|
|
* Copyright (c) 2005 Intel Inc. All rights reserved.
|
|
* Copyright (c) 2005 Intel Inc. All rights reserved.
|
|
- * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
|
|
|
|
|
|
+ * Copyright (c) 2005-2006 Voltaire, Inc. All rights reserved.
|
|
*
|
|
*
|
|
* This software is available to you under a choice of one of two
|
|
* This software is available to you under a choice of one of two
|
|
* licenses. You may choose to be licensed under the terms of the GNU
|
|
* licenses. You may choose to be licensed under the terms of the GNU
|
|
@@ -100,17 +100,6 @@ void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-static int data_offset(u8 mgmt_class)
|
|
|
|
-{
|
|
|
|
- if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM)
|
|
|
|
- return IB_MGMT_SA_HDR;
|
|
|
|
- else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
|
|
|
|
- (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END))
|
|
|
|
- return IB_MGMT_VENDOR_HDR;
|
|
|
|
- else
|
|
|
|
- return IB_MGMT_RMPP_HDR;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static void format_ack(struct ib_mad_send_buf *msg,
|
|
static void format_ack(struct ib_mad_send_buf *msg,
|
|
struct ib_rmpp_mad *data,
|
|
struct ib_rmpp_mad *data,
|
|
struct mad_rmpp_recv *rmpp_recv)
|
|
struct mad_rmpp_recv *rmpp_recv)
|
|
@@ -137,7 +126,7 @@ static void ack_recv(struct mad_rmpp_recv *rmpp_recv,
|
|
struct ib_mad_send_buf *msg;
|
|
struct ib_mad_send_buf *msg;
|
|
int ret, hdr_len;
|
|
int ret, hdr_len;
|
|
|
|
|
|
- hdr_len = data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class);
|
|
|
|
|
|
+ hdr_len = ib_get_mad_data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class);
|
|
msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp,
|
|
msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp,
|
|
recv_wc->wc->pkey_index, 1, hdr_len,
|
|
recv_wc->wc->pkey_index, 1, hdr_len,
|
|
0, GFP_KERNEL);
|
|
0, GFP_KERNEL);
|
|
@@ -163,7 +152,7 @@ static struct ib_mad_send_buf *alloc_response_msg(struct ib_mad_agent *agent,
|
|
if (IS_ERR(ah))
|
|
if (IS_ERR(ah))
|
|
return (void *) ah;
|
|
return (void *) ah;
|
|
|
|
|
|
- hdr_len = data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class);
|
|
|
|
|
|
+ hdr_len = ib_get_mad_data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class);
|
|
msg = ib_create_send_mad(agent, recv_wc->wc->src_qp,
|
|
msg = ib_create_send_mad(agent, recv_wc->wc->src_qp,
|
|
recv_wc->wc->pkey_index, 1,
|
|
recv_wc->wc->pkey_index, 1,
|
|
hdr_len, 0, GFP_KERNEL);
|
|
hdr_len, 0, GFP_KERNEL);
|
|
@@ -408,7 +397,7 @@ static inline int get_mad_len(struct mad_rmpp_recv *rmpp_recv)
|
|
|
|
|
|
rmpp_mad = (struct ib_rmpp_mad *)rmpp_recv->cur_seg_buf->mad;
|
|
rmpp_mad = (struct ib_rmpp_mad *)rmpp_recv->cur_seg_buf->mad;
|
|
|
|
|
|
- hdr_size = data_offset(rmpp_mad->mad_hdr.mgmt_class);
|
|
|
|
|
|
+ hdr_size = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class);
|
|
data_size = sizeof(struct ib_rmpp_mad) - hdr_size;
|
|
data_size = sizeof(struct ib_rmpp_mad) - hdr_size;
|
|
pad = IB_MGMT_RMPP_DATA - be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
|
|
pad = IB_MGMT_RMPP_DATA - be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
|
|
if (pad > IB_MGMT_RMPP_DATA || pad < 0)
|
|
if (pad > IB_MGMT_RMPP_DATA || pad < 0)
|
|
@@ -562,15 +551,15 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr)
|
|
return ib_send_mad(mad_send_wr);
|
|
return ib_send_mad(mad_send_wr);
|
|
}
|
|
}
|
|
|
|
|
|
-static void abort_send(struct ib_mad_agent_private *agent, __be64 tid,
|
|
|
|
- u8 rmpp_status)
|
|
|
|
|
|
+static void abort_send(struct ib_mad_agent_private *agent,
|
|
|
|
+ struct ib_mad_recv_wc *mad_recv_wc, u8 rmpp_status)
|
|
{
|
|
{
|
|
struct ib_mad_send_wr_private *mad_send_wr;
|
|
struct ib_mad_send_wr_private *mad_send_wr;
|
|
struct ib_mad_send_wc wc;
|
|
struct ib_mad_send_wc wc;
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
|
|
spin_lock_irqsave(&agent->lock, flags);
|
|
spin_lock_irqsave(&agent->lock, flags);
|
|
- mad_send_wr = ib_find_send_mad(agent, tid);
|
|
|
|
|
|
+ mad_send_wr = ib_find_send_mad(agent, mad_recv_wc);
|
|
if (!mad_send_wr)
|
|
if (!mad_send_wr)
|
|
goto out; /* Unmatched send */
|
|
goto out; /* Unmatched send */
|
|
|
|
|
|
@@ -612,8 +601,7 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent,
|
|
|
|
|
|
rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
|
|
rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
|
|
if (rmpp_mad->rmpp_hdr.rmpp_status) {
|
|
if (rmpp_mad->rmpp_hdr.rmpp_status) {
|
|
- abort_send(agent, rmpp_mad->mad_hdr.tid,
|
|
|
|
- IB_MGMT_RMPP_STATUS_BAD_STATUS);
|
|
|
|
|
|
+ abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
|
|
nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
|
|
nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -621,14 +609,13 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent,
|
|
seg_num = be32_to_cpu(rmpp_mad->rmpp_hdr.seg_num);
|
|
seg_num = be32_to_cpu(rmpp_mad->rmpp_hdr.seg_num);
|
|
newwin = be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
|
|
newwin = be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
|
|
if (newwin < seg_num) {
|
|
if (newwin < seg_num) {
|
|
- abort_send(agent, rmpp_mad->mad_hdr.tid,
|
|
|
|
- IB_MGMT_RMPP_STATUS_W2S);
|
|
|
|
|
|
+ abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_W2S);
|
|
nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_W2S);
|
|
nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_W2S);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
spin_lock_irqsave(&agent->lock, flags);
|
|
spin_lock_irqsave(&agent->lock, flags);
|
|
- mad_send_wr = ib_find_send_mad(agent, rmpp_mad->mad_hdr.tid);
|
|
|
|
|
|
+ mad_send_wr = ib_find_send_mad(agent, mad_recv_wc);
|
|
if (!mad_send_wr)
|
|
if (!mad_send_wr)
|
|
goto out; /* Unmatched ACK */
|
|
goto out; /* Unmatched ACK */
|
|
|
|
|
|
@@ -639,8 +626,7 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent,
|
|
if (seg_num > mad_send_wr->send_buf.seg_count ||
|
|
if (seg_num > mad_send_wr->send_buf.seg_count ||
|
|
seg_num > mad_send_wr->newwin) {
|
|
seg_num > mad_send_wr->newwin) {
|
|
spin_unlock_irqrestore(&agent->lock, flags);
|
|
spin_unlock_irqrestore(&agent->lock, flags);
|
|
- abort_send(agent, rmpp_mad->mad_hdr.tid,
|
|
|
|
- IB_MGMT_RMPP_STATUS_S2B);
|
|
|
|
|
|
+ abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_S2B);
|
|
nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_S2B);
|
|
nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_S2B);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -728,12 +714,10 @@ static void process_rmpp_stop(struct ib_mad_agent_private *agent,
|
|
rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
|
|
rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
|
|
|
|
|
|
if (rmpp_mad->rmpp_hdr.rmpp_status != IB_MGMT_RMPP_STATUS_RESX) {
|
|
if (rmpp_mad->rmpp_hdr.rmpp_status != IB_MGMT_RMPP_STATUS_RESX) {
|
|
- abort_send(agent, rmpp_mad->mad_hdr.tid,
|
|
|
|
- IB_MGMT_RMPP_STATUS_BAD_STATUS);
|
|
|
|
|
|
+ abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
|
|
nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
|
|
nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
|
|
} else
|
|
} else
|
|
- abort_send(agent, rmpp_mad->mad_hdr.tid,
|
|
|
|
- rmpp_mad->rmpp_hdr.rmpp_status);
|
|
|
|
|
|
+ abort_send(agent, mad_recv_wc, rmpp_mad->rmpp_hdr.rmpp_status);
|
|
}
|
|
}
|
|
|
|
|
|
static void process_rmpp_abort(struct ib_mad_agent_private *agent,
|
|
static void process_rmpp_abort(struct ib_mad_agent_private *agent,
|
|
@@ -745,12 +729,10 @@ static void process_rmpp_abort(struct ib_mad_agent_private *agent,
|
|
|
|
|
|
if (rmpp_mad->rmpp_hdr.rmpp_status < IB_MGMT_RMPP_STATUS_ABORT_MIN ||
|
|
if (rmpp_mad->rmpp_hdr.rmpp_status < IB_MGMT_RMPP_STATUS_ABORT_MIN ||
|
|
rmpp_mad->rmpp_hdr.rmpp_status > IB_MGMT_RMPP_STATUS_ABORT_MAX) {
|
|
rmpp_mad->rmpp_hdr.rmpp_status > IB_MGMT_RMPP_STATUS_ABORT_MAX) {
|
|
- abort_send(agent, rmpp_mad->mad_hdr.tid,
|
|
|
|
- IB_MGMT_RMPP_STATUS_BAD_STATUS);
|
|
|
|
|
|
+ abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
|
|
nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
|
|
nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
|
|
} else
|
|
} else
|
|
- abort_send(agent, rmpp_mad->mad_hdr.tid,
|
|
|
|
- rmpp_mad->rmpp_hdr.rmpp_status);
|
|
|
|
|
|
+ abort_send(agent, mad_recv_wc, rmpp_mad->rmpp_hdr.rmpp_status);
|
|
}
|
|
}
|
|
|
|
|
|
struct ib_mad_recv_wc *
|
|
struct ib_mad_recv_wc *
|
|
@@ -764,8 +746,7 @@ ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent,
|
|
return mad_recv_wc;
|
|
return mad_recv_wc;
|
|
|
|
|
|
if (rmpp_mad->rmpp_hdr.rmpp_version != IB_MGMT_RMPP_VERSION) {
|
|
if (rmpp_mad->rmpp_hdr.rmpp_version != IB_MGMT_RMPP_VERSION) {
|
|
- abort_send(agent, rmpp_mad->mad_hdr.tid,
|
|
|
|
- IB_MGMT_RMPP_STATUS_UNV);
|
|
|
|
|
|
+ abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_UNV);
|
|
nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_UNV);
|
|
nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_UNV);
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
@@ -783,8 +764,7 @@ ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent,
|
|
process_rmpp_abort(agent, mad_recv_wc);
|
|
process_rmpp_abort(agent, mad_recv_wc);
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
- abort_send(agent, rmpp_mad->mad_hdr.tid,
|
|
|
|
- IB_MGMT_RMPP_STATUS_BADT);
|
|
|
|
|
|
+ abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BADT);
|
|
nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BADT);
|
|
nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BADT);
|
|
break;
|
|
break;
|
|
}
|
|
}
|