]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_mem.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / dev / cxgb / ulp / iw_cxgb / iw_cxgb_mem.c
1 /**************************************************************************
2
3 Copyright (c) 2007, Chelsio Inc.
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8
9  1. Redistributions of source code must retain the above copyright notice,
10     this list of conditions and the following disclaimer.
11
12  2. Neither the name of the Chelsio Corporation nor the names of its
13     contributors may be used to endorse or promote products derived from
14     this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 POSSIBILITY OF SUCH DAMAGE.
27
28 ***************************************************************************/
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/kernel.h>
35 #include <sys/bus.h>
36 #include <sys/module.h>
37 #include <sys/pciio.h>
38 #include <sys/conf.h>
39 #include <machine/bus.h>
40 #include <machine/resource.h>
41 #include <sys/bus_dma.h>
42 #include <sys/rman.h>
43 #include <sys/ioccom.h>
44 #include <sys/mbuf.h>
45 #include <sys/mutex.h>
46 #include <sys/rwlock.h>
47 #include <sys/linker.h>
48 #include <sys/firmware.h>
49 #include <sys/socket.h>
50 #include <sys/sockio.h>
51 #include <sys/smp.h>
52 #include <sys/sysctl.h>
53 #include <sys/syslog.h>
54 #include <sys/queue.h>
55 #include <sys/taskqueue.h>
56 #include <sys/proc.h>
57 #include <sys/queue.h>
58 #include <sys/libkern.h>
59
60 #include <netinet/in.h>
61
62 #include <contrib/rdma/ib_verbs.h>
63 #include <contrib/rdma/ib_umem.h>
64 #include <contrib/rdma/ib_user_verbs.h>
65
66
67 #ifdef CONFIG_DEFINED
68 #include <cxgb_include.h>
69 #include <ulp/iw_cxgb/iw_cxgb_wr.h>
70 #include <ulp/iw_cxgb/iw_cxgb_hal.h>
71 #include <ulp/iw_cxgb/iw_cxgb_provider.h>
72 #include <ulp/iw_cxgb/iw_cxgb_cm.h>
73 #include <ulp/iw_cxgb/iw_cxgb.h>
74 #include <ulp/iw_cxgb/iw_cxgb_resource.h>
75 #include <ulp/iw_cxgb/iw_cxgb_user.h>
76 #else
77 #include <dev/cxgb/cxgb_include.h>
78 #include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_wr.h>
79 #include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_hal.h>
80 #include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_provider.h>
81 #include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.h>
82 #include <dev/cxgb/ulp/iw_cxgb/iw_cxgb.h>
83 #include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_resource.h>
84 #include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_user.h>
85 #endif
86
87
88 int iwch_register_mem(struct iwch_dev *rhp, struct iwch_pd *php,
89                                         struct iwch_mr *mhp,
90                                         int shift,
91                                         __be64 *page_list)
92 {
93         u32 stag;
94         u32 mmid;
95
96
97         if (cxio_register_phys_mem(&rhp->rdev,
98                                    &stag, mhp->attr.pdid,
99                                    mhp->attr.perms,
100                                    mhp->attr.zbva,
101                                    mhp->attr.va_fbo,
102                                    mhp->attr.len,
103                                    shift-12,
104                                    page_list,
105                                    &mhp->attr.pbl_size, &mhp->attr.pbl_addr))
106                 return (-ENOMEM);
107         mhp->attr.state = 1;
108         mhp->attr.stag = stag;
109         mmid = stag >> 8;
110         mhp->ibmr.rkey = mhp->ibmr.lkey = stag;
111         insert_handle(rhp, &rhp->mmidr, mhp, mmid);
112         CTR3(KTR_IW_CXGB, "%s mmid 0x%x mhp %p", __FUNCTION__, mmid, mhp);
113         return 0;
114 }
115
116 int iwch_reregister_mem(struct iwch_dev *rhp, struct iwch_pd *php,
117                                         struct iwch_mr *mhp,
118                                         int shift,
119                                         __be64 *page_list,
120                                         int npages)
121 {
122         u32 stag;
123         u32 mmid;
124
125
126         /* We could support this... */
127         if (npages > mhp->attr.pbl_size)
128                 return (-ENOMEM);
129
130         stag = mhp->attr.stag;
131         if (cxio_reregister_phys_mem(&rhp->rdev,
132                                    &stag, mhp->attr.pdid,
133                                    mhp->attr.perms,
134                                    mhp->attr.zbva,
135                                    mhp->attr.va_fbo,
136                                    mhp->attr.len,
137                                    shift-12,
138                                    page_list,
139                                    &mhp->attr.pbl_size, &mhp->attr.pbl_addr))
140                 return (-ENOMEM);
141         mhp->attr.state = 1;
142         mhp->attr.stag = stag;
143         mmid = stag >> 8;
144         mhp->ibmr.rkey = mhp->ibmr.lkey = stag;
145         insert_handle(rhp, &rhp->mmidr, mhp, mmid);
146         CTR3(KTR_IW_CXGB, "%s mmid 0x%x mhp %p", __FUNCTION__, mmid, mhp);
147         return 0;
148 }
149
150 int build_phys_page_list(struct ib_phys_buf *buffer_list,
151                                         int num_phys_buf,
152                                         u64 *iova_start,
153                                         u64 *total_size,
154                                         int *npages,
155                                         int *shift,
156                                         __be64 **page_list)
157 {
158         u64 mask;
159         int i, j, n;
160
161         mask = 0;
162         *total_size = 0;
163         for (i = 0; i < num_phys_buf; ++i) {
164                 if (i != 0 && buffer_list[i].addr & ~PAGE_MASK)
165                         return (-EINVAL);
166                 if (i != 0 && i != num_phys_buf - 1 &&
167                     (buffer_list[i].size & ~PAGE_MASK))
168                         return (-EINVAL);
169                 *total_size += buffer_list[i].size;
170                 if (i > 0)
171                         mask |= buffer_list[i].addr;
172                 else
173                         mask |= buffer_list[i].addr & PAGE_MASK;
174                 if (i != num_phys_buf - 1)
175                         mask |= buffer_list[i].addr + buffer_list[i].size;
176                 else
177                         mask |= (buffer_list[i].addr + buffer_list[i].size +
178                                 PAGE_SIZE - 1) & PAGE_MASK;
179         }
180
181         if (*total_size > 0xFFFFFFFFULL)
182                 return (-ENOMEM);
183
184         /* Find largest page shift we can use to cover buffers */
185         for (*shift = PAGE_SHIFT; *shift < 27; ++(*shift))
186                 if ((1ULL << *shift) & mask)
187                         break;
188
189         buffer_list[0].size += buffer_list[0].addr & ((1ULL << *shift) - 1);
190         buffer_list[0].addr &= ~0ull << *shift;
191
192         *npages = 0;
193         for (i = 0; i < num_phys_buf; ++i)
194                 *npages += (buffer_list[i].size +
195                         (1ULL << *shift) - 1) >> *shift;
196
197         if (!*npages)
198                 return (-EINVAL);
199
200         *page_list = kmalloc(sizeof(u64) * *npages, M_NOWAIT);
201         if (!*page_list)
202                 return (-ENOMEM);
203
204         n = 0;
205         for (i = 0; i < num_phys_buf; ++i)
206                 for (j = 0;
207                      j < (buffer_list[i].size + (1ULL << *shift) - 1) >> *shift;
208                      ++j)
209                         (*page_list)[n++] = htobe64(buffer_list[i].addr +
210                             ((u64) j << *shift));
211
212         CTR6(KTR_IW_CXGB, "%s va 0x%llx mask 0x%llx shift %d len %lld pbl_size %d",
213              __FUNCTION__, (unsigned long long) *iova_start,
214              (unsigned long long) mask, *shift, (unsigned long long) *total_size,
215              *npages);
216
217         return 0;
218
219 }