11/*
22 * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.
3+ * Copyright (c) 2005 Intel Corporation. All rights reserved.
4+ * Copyright (c) 2005 Mellanox Technologies Ltd. All rights reserved.
35 *
46 * This software is available to you under a choice of one of two
57 * licenses. You may choose to be licensed under the terms of the GNU
2931 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3032 * SOFTWARE.
3133 *
32- * $Id: mad.c 1389 2004-12-27 22:56:47Z roland $
34+ * $Id: mad.c 2817 2005-07-07 11:29:26Z halr $
3335 */
34-
3536#include <linux/dma-mapping.h>
3637
3738#include "mad_priv.h"
39+ #include "mad_rmpp.h"
3840#include "smi.h"
3941#include "agent.h"
4042
@@ -45,6 +47,7 @@ MODULE_AUTHOR("Sean Hefty");
4547
4648
4749kmem_cache_t * ib_mad_cache ;
50+
4851static struct list_head ib_mad_port_list ;
4952static u32 ib_mad_client_id = 0 ;
5053
@@ -62,8 +65,6 @@ static struct ib_mad_agent_private *find_mad_agent(
6265static int ib_mad_post_receive_mads (struct ib_mad_qp_info * qp_info ,
6366 struct ib_mad_private * mad );
6467static void cancel_mads (struct ib_mad_agent_private * mad_agent_priv );
65- static void ib_mad_complete_send_wr (struct ib_mad_send_wr_private * mad_send_wr ,
66- struct ib_mad_send_wc * mad_send_wc );
6768static void timeout_sends (void * data );
6869static void local_completions (void * data );
6970static int add_nonoui_reg_req (struct ib_mad_reg_req * mad_reg_req ,
@@ -195,8 +196,8 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
195196 if (qpn == -1 )
196197 goto error1 ;
197198
198- if (rmpp_version )
199- goto error1 ; /* XXX: until RMPP implemented */
199+ if (rmpp_version && rmpp_version != IB_MGMT_RMPP_VERSION )
200+ goto error1 ;
200201
201202 /* Validate MAD registration request if supplied */
202203 if (mad_reg_req ) {
@@ -281,7 +282,7 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
281282 /* Now, fill in the various structures */
282283 mad_agent_priv -> qp_info = & port_priv -> qp_info [qpn ];
283284 mad_agent_priv -> reg_req = reg_req ;
284- mad_agent_priv -> rmpp_version = rmpp_version ;
285+ mad_agent_priv -> agent . rmpp_version = rmpp_version ;
285286 mad_agent_priv -> agent .device = device ;
286287 mad_agent_priv -> agent .recv_handler = recv_handler ;
287288 mad_agent_priv -> agent .send_handler = send_handler ;
@@ -341,6 +342,7 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
341342 INIT_LIST_HEAD (& mad_agent_priv -> send_list );
342343 INIT_LIST_HEAD (& mad_agent_priv -> wait_list );
343344 INIT_LIST_HEAD (& mad_agent_priv -> done_list );
345+ INIT_LIST_HEAD (& mad_agent_priv -> rmpp_list );
344346 INIT_WORK (& mad_agent_priv -> timed_work , timeout_sends , mad_agent_priv );
345347 INIT_LIST_HEAD (& mad_agent_priv -> local_list );
346348 INIT_WORK (& mad_agent_priv -> local_work , local_completions ,
@@ -502,6 +504,7 @@ static void unregister_mad_agent(struct ib_mad_agent_private *mad_agent_priv)
502504 spin_unlock_irqrestore (& port_priv -> reg_lock , flags );
503505
504506 flush_workqueue (port_priv -> wq );
507+ ib_cancel_rmpp_recvs (mad_agent_priv );
505508
506509 atomic_dec (& mad_agent_priv -> refcount );
507510 wait_event (mad_agent_priv -> wait ,
@@ -786,12 +789,15 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
786789 int buf_size ;
787790 void * buf ;
788791
789- if (rmpp_active )
790- return ERR_PTR (- EINVAL ); /* until RMPP implemented */
791792 mad_agent_priv = container_of (mad_agent ,
792793 struct ib_mad_agent_private , agent );
793794 buf_size = get_buf_length (hdr_len , data_len );
794795
796+ if ((!mad_agent -> rmpp_version &&
797+ (rmpp_active || buf_size > sizeof (struct ib_mad ))) ||
798+ (!rmpp_active && buf_size > sizeof (struct ib_mad )))
799+ return ERR_PTR (- EINVAL );
800+
795801 buf = kmalloc (sizeof * send_buf + buf_size , gfp_mask );
796802 if (!buf )
797803 return ERR_PTR (- ENOMEM );
@@ -816,6 +822,18 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
816822 send_buf -> send_wr .wr .ud .remote_qpn = remote_qpn ;
817823 send_buf -> send_wr .wr .ud .remote_qkey = IB_QP_SET_QKEY ;
818824 send_buf -> send_wr .wr .ud .pkey_index = pkey_index ;
825+
826+ if (rmpp_active ) {
827+ struct ib_rmpp_mad * rmpp_mad ;
828+ rmpp_mad = (struct ib_rmpp_mad * )send_buf -> mad ;
829+ rmpp_mad -> rmpp_hdr .paylen_newwin = cpu_to_be32 (hdr_len -
830+ offsetof(struct ib_rmpp_mad , data ) + data_len );
831+ rmpp_mad -> rmpp_hdr .rmpp_version = mad_agent -> rmpp_version ;
832+ rmpp_mad -> rmpp_hdr .rmpp_type = IB_MGMT_RMPP_TYPE_DATA ;
833+ ib_set_rmpp_flags (& rmpp_mad -> rmpp_hdr ,
834+ IB_MGMT_RMPP_FLAG_ACTIVE );
835+ }
836+
819837 send_buf -> mad_agent = mad_agent ;
820838 atomic_inc (& mad_agent_priv -> refcount );
821839 return send_buf ;
@@ -839,7 +857,7 @@ void ib_free_send_mad(struct ib_mad_send_buf *send_buf)
839857}
840858EXPORT_SYMBOL (ib_free_send_mad );
841859
842- static int ib_send_mad (struct ib_mad_send_wr_private * mad_send_wr )
860+ int ib_send_mad (struct ib_mad_send_wr_private * mad_send_wr )
843861{
844862 struct ib_mad_qp_info * qp_info ;
845863 struct ib_send_wr * bad_send_wr ;
@@ -940,13 +958,13 @@ int ib_post_send_mad(struct ib_mad_agent *mad_agent,
940958 ret = - ENOMEM ;
941959 goto error2 ;
942960 }
961+ memset (mad_send_wr , 0 , sizeof * mad_send_wr );
943962
944963 mad_send_wr -> send_wr = * send_wr ;
945964 mad_send_wr -> send_wr .sg_list = mad_send_wr -> sg_list ;
946965 memcpy (mad_send_wr -> sg_list , send_wr -> sg_list ,
947966 sizeof * send_wr -> sg_list * send_wr -> num_sge );
948- mad_send_wr -> wr_id = mad_send_wr -> send_wr .wr_id ;
949- mad_send_wr -> send_wr .next = NULL ;
967+ mad_send_wr -> wr_id = send_wr -> wr_id ;
950968 mad_send_wr -> tid = send_wr -> wr .ud .mad_hdr -> tid ;
951969 mad_send_wr -> mad_agent_priv = mad_agent_priv ;
952970 /* Timeout will be updated after send completes */
@@ -964,8 +982,13 @@ int ib_post_send_mad(struct ib_mad_agent *mad_agent,
964982 & mad_agent_priv -> send_list );
965983 spin_unlock_irqrestore (& mad_agent_priv -> lock , flags );
966984
967- ret = ib_send_mad (mad_send_wr );
968- if (ret ) {
985+ if (mad_agent_priv -> agent .rmpp_version ) {
986+ ret = ib_send_rmpp_mad (mad_send_wr );
987+ if (ret >= 0 && ret != IB_RMPP_RESULT_CONSUMED )
988+ ret = ib_send_mad (mad_send_wr );
989+ } else
990+ ret = ib_send_mad (mad_send_wr );
991+ if (ret < 0 ) {
969992 /* Fail send request */
970993 spin_lock_irqsave (& mad_agent_priv -> lock , flags );
971994 list_del (& mad_send_wr -> agent_list );
@@ -991,31 +1014,25 @@ EXPORT_SYMBOL(ib_post_send_mad);
9911014 */
9921015void ib_free_recv_mad (struct ib_mad_recv_wc * mad_recv_wc )
9931016{
994- struct ib_mad_recv_buf * entry ;
1017+ struct ib_mad_recv_buf * mad_recv_buf , * temp_recv_buf ;
9951018 struct ib_mad_private_header * mad_priv_hdr ;
9961019 struct ib_mad_private * priv ;
1020+ struct list_head free_list ;
9971021
998- mad_priv_hdr = container_of (mad_recv_wc ,
999- struct ib_mad_private_header ,
1000- recv_wc );
1001- priv = container_of (mad_priv_hdr , struct ib_mad_private , header );
1022+ INIT_LIST_HEAD (& free_list );
1023+ list_splice_init (& mad_recv_wc -> rmpp_list , & free_list );
10021024
1003- /*
1004- * Walk receive buffer list associated with this WC
1005- * No need to remove them from list of receive buffers
1006- */
1007- list_for_each_entry (entry , & mad_recv_wc -> recv_buf .list , list ) {
1008- /* Free previous receive buffer */
1009- kmem_cache_free (ib_mad_cache , priv );
1025+ list_for_each_entry_safe (mad_recv_buf , temp_recv_buf ,
1026+ & free_list , list ) {
1027+ mad_recv_wc = container_of (mad_recv_buf , struct ib_mad_recv_wc ,
1028+ recv_buf );
10101029 mad_priv_hdr = container_of (mad_recv_wc ,
10111030 struct ib_mad_private_header ,
10121031 recv_wc );
10131032 priv = container_of (mad_priv_hdr , struct ib_mad_private ,
10141033 header );
1034+ kmem_cache_free (ib_mad_cache , priv );
10151035 }
1016-
1017- /* Free last buffer */
1018- kmem_cache_free (ib_mad_cache , priv );
10191036}
10201037EXPORT_SYMBOL (ib_free_recv_mad );
10211038
@@ -1524,9 +1541,20 @@ static int validate_mad(struct ib_mad *mad, u32 qp_num)
15241541 return valid ;
15251542}
15261543
1527- static struct ib_mad_send_wr_private *
1528- find_send_req (struct ib_mad_agent_private * mad_agent_priv ,
1529- u64 tid )
1544+ static int is_data_mad (struct ib_mad_agent_private * mad_agent_priv ,
1545+ struct ib_mad_hdr * mad_hdr )
1546+ {
1547+ struct ib_rmpp_mad * rmpp_mad ;
1548+
1549+ rmpp_mad = (struct ib_rmpp_mad * )mad_hdr ;
1550+ return !mad_agent_priv -> agent .rmpp_version ||
1551+ !(ib_get_rmpp_flags (& rmpp_mad -> rmpp_hdr ) &
1552+ IB_MGMT_RMPP_FLAG_ACTIVE ) ||
1553+ (rmpp_mad -> rmpp_hdr .rmpp_type == IB_MGMT_RMPP_TYPE_DATA );
1554+ }
1555+
1556+ struct ib_mad_send_wr_private *
1557+ ib_find_send_mad (struct ib_mad_agent_private * mad_agent_priv , u64 tid )
15301558{
15311559 struct ib_mad_send_wr_private * mad_send_wr ;
15321560
@@ -1542,7 +1570,9 @@ find_send_req(struct ib_mad_agent_private *mad_agent_priv,
15421570 */
15431571 list_for_each_entry (mad_send_wr , & mad_agent_priv -> send_list ,
15441572 agent_list ) {
1545- if (mad_send_wr -> tid == tid && mad_send_wr -> timeout ) {
1573+ if (is_data_mad (mad_agent_priv ,
1574+ mad_send_wr -> send_wr .wr .ud .mad_hdr ) &&
1575+ mad_send_wr -> tid == tid && mad_send_wr -> timeout ) {
15461576 /* Verify request has not been canceled */
15471577 return (mad_send_wr -> status == IB_WC_SUCCESS ) ?
15481578 mad_send_wr : NULL ;
@@ -1551,7 +1581,7 @@ find_send_req(struct ib_mad_agent_private *mad_agent_priv,
15511581 return NULL ;
15521582}
15531583
1554- static void ib_mark_req_done (struct ib_mad_send_wr_private * mad_send_wr )
1584+ void ib_mark_mad_done (struct ib_mad_send_wr_private * mad_send_wr )
15551585{
15561586 mad_send_wr -> timeout = 0 ;
15571587 if (mad_send_wr -> refcount == 1 ) {
@@ -1569,20 +1599,31 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
15691599 unsigned long flags ;
15701600 u64 tid ;
15711601
1572- INIT_LIST_HEAD (& mad_recv_wc -> recv_buf .list );
1602+ INIT_LIST_HEAD (& mad_recv_wc -> rmpp_list );
1603+ list_add (& mad_recv_wc -> recv_buf .list , & mad_recv_wc -> rmpp_list );
1604+ if (mad_agent_priv -> agent .rmpp_version ) {
1605+ mad_recv_wc = ib_process_rmpp_recv_wc (mad_agent_priv ,
1606+ mad_recv_wc );
1607+ if (!mad_recv_wc ) {
1608+ if (atomic_dec_and_test (& mad_agent_priv -> refcount ))
1609+ wake_up (& mad_agent_priv -> wait );
1610+ return ;
1611+ }
1612+ }
1613+
15731614 /* Complete corresponding request */
15741615 if (response_mad (mad_recv_wc -> recv_buf .mad )) {
15751616 tid = mad_recv_wc -> recv_buf .mad -> mad_hdr .tid ;
15761617 spin_lock_irqsave (& mad_agent_priv -> lock , flags );
1577- mad_send_wr = find_send_req (mad_agent_priv , tid );
1618+ mad_send_wr = ib_find_send_mad (mad_agent_priv , tid );
15781619 if (!mad_send_wr ) {
15791620 spin_unlock_irqrestore (& mad_agent_priv -> lock , flags );
15801621 ib_free_recv_mad (mad_recv_wc );
15811622 if (atomic_dec_and_test (& mad_agent_priv -> refcount ))
15821623 wake_up (& mad_agent_priv -> wait );
15831624 return ;
15841625 }
1585- ib_mark_req_done (mad_send_wr );
1626+ ib_mark_mad_done (mad_send_wr );
15861627 spin_unlock_irqrestore (& mad_agent_priv -> lock , flags );
15871628
15881629 /* Defined behavior is to complete response before request */
@@ -1787,14 +1828,22 @@ void ib_reset_mad_timeout(struct ib_mad_send_wr_private *mad_send_wr,
17871828/*
17881829 * Process a send work completion
17891830 */
1790- static void ib_mad_complete_send_wr (struct ib_mad_send_wr_private * mad_send_wr ,
1791- struct ib_mad_send_wc * mad_send_wc )
1831+ void ib_mad_complete_send_wr (struct ib_mad_send_wr_private * mad_send_wr ,
1832+ struct ib_mad_send_wc * mad_send_wc )
17921833{
17931834 struct ib_mad_agent_private * mad_agent_priv ;
17941835 unsigned long flags ;
1836+ int ret ;
17951837
17961838 mad_agent_priv = mad_send_wr -> mad_agent_priv ;
17971839 spin_lock_irqsave (& mad_agent_priv -> lock , flags );
1840+ if (mad_agent_priv -> agent .rmpp_version ) {
1841+ ret = ib_process_rmpp_send_wc (mad_send_wr , mad_send_wc );
1842+ if (ret == IB_RMPP_RESULT_CONSUMED )
1843+ goto done ;
1844+ } else
1845+ ret = IB_RMPP_RESULT_UNHANDLED ;
1846+
17981847 if (mad_send_wc -> status != IB_WC_SUCCESS &&
17991848 mad_send_wr -> status == IB_WC_SUCCESS ) {
18001849 mad_send_wr -> status = mad_send_wc -> status ;
@@ -1806,8 +1855,7 @@ static void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr,
18061855 mad_send_wr -> status == IB_WC_SUCCESS ) {
18071856 wait_for_response (mad_send_wr );
18081857 }
1809- spin_unlock_irqrestore (& mad_agent_priv -> lock , flags );
1810- return ;
1858+ goto done ;
18111859 }
18121860
18131861 /* Remove send from MAD agent and notify client of completion */
@@ -1817,14 +1865,18 @@ static void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr,
18171865
18181866 if (mad_send_wr -> status != IB_WC_SUCCESS )
18191867 mad_send_wc -> status = mad_send_wr -> status ;
1820- mad_agent_priv -> agent .send_handler (& mad_agent_priv -> agent ,
1821- mad_send_wc );
1868+ if (ret != IB_RMPP_RESULT_INTERNAL )
1869+ mad_agent_priv -> agent .send_handler (& mad_agent_priv -> agent ,
1870+ mad_send_wc );
18221871
18231872 /* Release reference on agent taken when sending */
18241873 if (atomic_dec_and_test (& mad_agent_priv -> refcount ))
18251874 wake_up (& mad_agent_priv -> wait );
18261875
18271876 kfree (mad_send_wr );
1877+ return ;
1878+ done :
1879+ spin_unlock_irqrestore (& mad_agent_priv -> lock , flags );
18281880}
18291881
18301882static void ib_mad_send_done_handler (struct ib_mad_port_private * port_priv ,
@@ -2036,7 +2088,9 @@ find_send_by_wr_id(struct ib_mad_agent_private *mad_agent_priv, u64 wr_id)
20362088
20372089 list_for_each_entry (mad_send_wr , & mad_agent_priv -> send_list ,
20382090 agent_list ) {
2039- if (mad_send_wr -> wr_id == wr_id )
2091+ if (is_data_mad (mad_agent_priv ,
2092+ mad_send_wr -> send_wr .wr .ud .mad_hdr ) &&
2093+ mad_send_wr -> wr_id == wr_id )
20402094 return mad_send_wr ;
20412095 }
20422096 return NULL ;
@@ -2118,7 +2172,9 @@ static void local_completions(void *data)
21182172 local -> mad_priv -> header .recv_wc .wc = & wc ;
21192173 local -> mad_priv -> header .recv_wc .mad_len =
21202174 sizeof (struct ib_mad );
2121- INIT_LIST_HEAD (& local -> mad_priv -> header .recv_wc .recv_buf .list );
2175+ INIT_LIST_HEAD (& local -> mad_priv -> header .recv_wc .rmpp_list );
2176+ list_add (& local -> mad_priv -> header .recv_wc .recv_buf .list ,
2177+ & local -> mad_priv -> header .recv_wc .rmpp_list );
21222178 local -> mad_priv -> header .recv_wc .recv_buf .grh = NULL ;
21232179 local -> mad_priv -> header .recv_wc .recv_buf .mad =
21242180 & local -> mad_priv -> mad .mad ;
@@ -2166,7 +2222,21 @@ static int retry_send(struct ib_mad_send_wr_private *mad_send_wr)
21662222 mad_send_wr -> timeout = msecs_to_jiffies (mad_send_wr -> send_wr .
21672223 wr .ud .timeout_ms );
21682224
2169- ret = ib_send_mad (mad_send_wr );
2225+ if (mad_send_wr -> mad_agent_priv -> agent .rmpp_version ) {
2226+ ret = ib_retry_rmpp (mad_send_wr );
2227+ switch (ret ) {
2228+ case IB_RMPP_RESULT_UNHANDLED :
2229+ ret = ib_send_mad (mad_send_wr );
2230+ break ;
2231+ case IB_RMPP_RESULT_CONSUMED :
2232+ ret = 0 ;
2233+ break ;
2234+ default :
2235+ ret = - ECOMM ;
2236+ break ;
2237+ }
2238+ } else
2239+ ret = ib_send_mad (mad_send_wr );
21702240
21712241 if (!ret ) {
21722242 mad_send_wr -> refcount ++ ;
@@ -2724,3 +2794,4 @@ static void __exit ib_mad_cleanup_module(void)
27242794
27252795module_init (ib_mad_init_module );
27262796module_exit (ib_mad_cleanup_module );
2797+
0 commit comments