2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 * $Id: mthca_av.c 1349 2004-12-16 21:09:43Z roland $
36 #include <linux/init.h>
41 #include "mthca_dev.h"
52 u32 sl_tclass_flowlabel
;
56 int mthca_create_ah(struct mthca_dev
*dev
,
58 struct ib_ah_attr
*ah_attr
,
62 struct mthca_av
*av
= NULL
;
64 ah
->type
= MTHCA_AH_PCI_POOL
;
66 if (mthca_is_memfree(dev
)) {
67 ah
->av
= kmalloc(sizeof *ah
->av
, GFP_ATOMIC
);
71 ah
->type
= MTHCA_AH_KMALLOC
;
73 } else if (!atomic_read(&pd
->sqp_count
) &&
74 !(dev
->mthca_flags
& MTHCA_FLAG_DDR_HIDDEN
)) {
75 index
= mthca_alloc(&dev
->av_table
.alloc
);
77 /* fall back to allocate in host memory */
81 av
= kmalloc(sizeof *av
, GFP_ATOMIC
);
85 ah
->type
= MTHCA_AH_ON_HCA
;
86 ah
->avdma
= dev
->av_table
.ddr_av_base
+
87 index
* MTHCA_AV_SIZE
;
91 if (ah
->type
== MTHCA_AH_PCI_POOL
) {
92 ah
->av
= pci_pool_alloc(dev
->av_table
.pool
,
93 SLAB_ATOMIC
, &ah
->avdma
);
100 ah
->key
= pd
->ntmr
.ibmr
.lkey
;
102 memset(av
, 0, MTHCA_AV_SIZE
);
104 av
->port_pd
= cpu_to_be32(pd
->pd_num
| (ah_attr
->port_num
<< 24));
105 av
->g_slid
= ah_attr
->src_path_bits
;
106 av
->dlid
= cpu_to_be16(ah_attr
->dlid
);
107 av
->msg_sr
= (3 << 4) | /* 2K message */
108 ah_attr
->static_rate
;
109 av
->sl_tclass_flowlabel
= cpu_to_be32(ah_attr
->sl
<< 28);
110 if (ah_attr
->ah_flags
& IB_AH_GRH
) {
112 av
->gid_index
= (ah_attr
->port_num
- 1) * dev
->limits
.gid_table_len
+
113 ah_attr
->grh
.sgid_index
;
114 av
->hop_limit
= ah_attr
->grh
.hop_limit
;
115 av
->sl_tclass_flowlabel
|=
116 cpu_to_be32((ah_attr
->grh
.traffic_class
<< 20) |
117 ah_attr
->grh
.flow_label
);
118 memcpy(av
->dgid
, ah_attr
->grh
.dgid
.raw
, 16);
120 /* Arbel workaround -- low byte of GID must be 2 */
121 av
->dgid
[3] = cpu_to_be32(2);
127 mthca_dbg(dev
, "Created UDAV at %p/%08lx:\n",
128 av
, (unsigned long) ah
->avdma
);
129 for (j
= 0; j
< 8; ++j
)
130 printk(KERN_DEBUG
" [%2x] %08x\n",
131 j
* 4, be32_to_cpu(((u32
*) av
)[j
]));
134 if (ah
->type
== MTHCA_AH_ON_HCA
) {
135 memcpy_toio(dev
->av_table
.av_map
+ index
* MTHCA_AV_SIZE
,
143 int mthca_destroy_ah(struct mthca_dev
*dev
, struct mthca_ah
*ah
)
146 case MTHCA_AH_ON_HCA
:
147 mthca_free(&dev
->av_table
.alloc
,
148 (ah
->avdma
- dev
->av_table
.ddr_av_base
) /
152 case MTHCA_AH_PCI_POOL
:
153 pci_pool_free(dev
->av_table
.pool
, ah
->av
, ah
->avdma
);
156 case MTHCA_AH_KMALLOC
:
164 int mthca_read_ah(struct mthca_dev
*dev
, struct mthca_ah
*ah
,
165 struct ib_ud_header
*header
)
167 if (ah
->type
== MTHCA_AH_ON_HCA
)
170 header
->lrh
.service_level
= be32_to_cpu(ah
->av
->sl_tclass_flowlabel
) >> 28;
171 header
->lrh
.destination_lid
= ah
->av
->dlid
;
172 header
->lrh
.source_lid
= ah
->av
->g_slid
& 0x7f;
173 if (ah
->av
->g_slid
& 0x80) {
174 header
->grh_present
= 1;
175 header
->grh
.traffic_class
=
176 (be32_to_cpu(ah
->av
->sl_tclass_flowlabel
) >> 20) & 0xff;
177 header
->grh
.flow_label
=
178 ah
->av
->sl_tclass_flowlabel
& cpu_to_be32(0xfffff);
179 ib_get_cached_gid(&dev
->ib_dev
,
180 be32_to_cpu(ah
->av
->port_pd
) >> 24,
182 &header
->grh
.source_gid
);
183 memcpy(header
->grh
.destination_gid
.raw
,
186 header
->grh_present
= 0;
192 int __devinit
mthca_init_av_table(struct mthca_dev
*dev
)
196 if (mthca_is_memfree(dev
))
199 err
= mthca_alloc_init(&dev
->av_table
.alloc
,
200 dev
->av_table
.num_ddr_avs
,
201 dev
->av_table
.num_ddr_avs
- 1,
206 dev
->av_table
.pool
= pci_pool_create("mthca_av", dev
->pdev
,
209 if (!dev
->av_table
.pool
)
212 if (!(dev
->mthca_flags
& MTHCA_FLAG_DDR_HIDDEN
)) {
213 dev
->av_table
.av_map
= ioremap(pci_resource_start(dev
->pdev
, 4) +
214 dev
->av_table
.ddr_av_base
-
216 dev
->av_table
.num_ddr_avs
*
218 if (!dev
->av_table
.av_map
)
221 dev
->av_table
.av_map
= NULL
;
226 pci_pool_destroy(dev
->av_table
.pool
);
229 mthca_alloc_cleanup(&dev
->av_table
.alloc
);
233 void __devexit
mthca_cleanup_av_table(struct mthca_dev
*dev
)
235 if (mthca_is_memfree(dev
))
238 if (dev
->av_table
.av_map
)
239 iounmap(dev
->av_table
.av_map
);
240 pci_pool_destroy(dev
->av_table
.pool
);
241 mthca_alloc_cleanup(&dev
->av_table
.alloc
);
This page took 0.036004 seconds and 5 git commands to generate.