1 /*
2 * Copyright (c) 2014, Cisco Systems, Inc. All rights reserved.
3 *
4 * LICENSE_BEGIN
5 *
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * BSD license below:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 *
38 * LICENSE_END
39 *
40 *
41 */
42
43 #ifndef _USD_POST_H_
44 #define _USD_POST_H_
45
46 #include <sys/uio.h>
47
48 #include "usd.h"
49 #include "usd_util.h"
50
51 static inline uint32_t
_usd_post_send_one(struct usd_wq * wq,const void * packet,size_t length,u_int8_t cq_entry)52 _usd_post_send_one(
53 struct usd_wq *wq,
54 const void *packet,
55 size_t length,
56 u_int8_t cq_entry)
57 {
58 struct vnic_wq *vwq;
59 uint32_t index;
60 struct wq_enet_desc *desc;
61 uint64_t wr;
62 u_int8_t offload_mode = 0, eop = 1;
63 u_int16_t mss = 7, header_length = 0, vlan_tag = 0;
64 u_int8_t vlan_tag_insert = 0, loopback = 0, fcoe_encap = 0;
65
66 vwq = &wq->uwq_vnic_wq;
67 desc = wq->uwq_next_desc;
68 index = wq->uwq_post_index;
69
70 wq_enet_desc_enc(desc, (uintptr_t)packet, length,
71 mss, header_length, offload_mode,
72 eop, cq_entry, fcoe_encap,
73 vlan_tag_insert, vlan_tag, loopback);
74 wmb();
75
76 wr = vnic_cached_posted_index((dma_addr_t)packet, length, index);
77 iowrite64(wr, &vwq->ctrl->posted_index);
78
79 wq->uwq_next_desc = (struct wq_enet_desc *)
80 ((uintptr_t)wq->uwq_desc_ring + (index<<4));
81 wq->uwq_post_index = (index+1) & wq->uwq_post_index_mask;
82 wq->uwq_send_credits--;
83
84 return index;
85 }
86
87 static inline uint32_t
_usd_post_send_two(struct usd_wq * wq,const void * hdr,size_t hdrlen,const void * pkt,size_t pktlen,u_int8_t cq_entry)88 _usd_post_send_two(
89 struct usd_wq *wq,
90 const void *hdr,
91 size_t hdrlen,
92 const void *pkt,
93 size_t pktlen,
94 u_int8_t cq_entry)
95 {
96 struct vnic_wq *vwq;
97 uint32_t index;
98 struct wq_enet_desc *desc;
99 u_int8_t offload_mode = 0, eop;
100 u_int16_t mss = 7, header_length = 0, vlan_tag = 0;
101 u_int8_t vlan_tag_insert = 0, loopback = 0, fcoe_encap = 0;
102
103 vwq = &wq->uwq_vnic_wq;
104 desc = wq->uwq_next_desc;
105 index = wq->uwq_post_index;
106
107 eop = 0;
108 wq_enet_desc_enc(desc, (uintptr_t)hdr, hdrlen,
109 mss, header_length, offload_mode,
110 eop, 0, fcoe_encap,
111 vlan_tag_insert, vlan_tag, loopback);
112
113 desc = (struct wq_enet_desc *) ((uintptr_t)wq->uwq_desc_ring + (index<<4));
114 index = (index+1) & wq->uwq_post_index_mask;
115
116 eop = 1;
117 wq_enet_desc_enc(desc, (uintptr_t)pkt, pktlen,
118 mss, header_length, offload_mode,
119 eop, cq_entry, fcoe_encap,
120 vlan_tag_insert, vlan_tag, loopback);
121 wmb();
122
123 iowrite32(index, &vwq->ctrl->posted_index);
124
125 wq->uwq_next_desc = (struct wq_enet_desc *)
126 ((uintptr_t)wq->uwq_desc_ring + (index<<4));
127 wq->uwq_post_index = (index+1) & wq->uwq_post_index_mask;
128 wq->uwq_send_credits -= 2;
129
130 return index;
131 }
132
133 static inline uint32_t
_usd_post_send_two_vlan(struct usd_wq * wq,const void * hdr,size_t hdrlen,const void * pkt,size_t pktlen,u_int8_t cq_entry,u_int16_t vlan_tag)134 _usd_post_send_two_vlan(
135 struct usd_wq *wq,
136 const void *hdr,
137 size_t hdrlen,
138 const void *pkt,
139 size_t pktlen,
140 u_int8_t cq_entry,
141 u_int16_t vlan_tag)
142 {
143 struct vnic_wq *vwq;
144 uint32_t index;
145 struct wq_enet_desc *desc;
146 u_int8_t offload_mode = 0, eop;
147 u_int16_t mss = 7, header_length = 0;
148 u_int8_t vlan_tag_insert = 1, loopback = 0, fcoe_encap = 0;
149
150 vwq = &wq->uwq_vnic_wq;
151 desc = wq->uwq_next_desc;
152 index = wq->uwq_post_index;
153
154 eop = 0;
155 wq_enet_desc_enc(desc, (uintptr_t)hdr, hdrlen,
156 mss, header_length, offload_mode,
157 eop, 0, fcoe_encap,
158 vlan_tag_insert, vlan_tag, loopback);
159
160 desc = (struct wq_enet_desc *) ((uintptr_t)wq->uwq_desc_ring + (index<<4));
161 index = (index+1) & wq->uwq_post_index_mask;
162
163 eop = 1;
164 wq_enet_desc_enc(desc, (uintptr_t)pkt, pktlen,
165 mss, header_length, offload_mode,
166 eop, cq_entry, fcoe_encap,
167 vlan_tag_insert, vlan_tag, loopback);
168 wmb();
169
170 iowrite32(index, &vwq->ctrl->posted_index);
171
172 wq->uwq_next_desc = (struct wq_enet_desc *)
173 ((uintptr_t)wq->uwq_desc_ring + (index<<4));
174 wq->uwq_post_index = (index+1) & wq->uwq_post_index_mask;
175 wq->uwq_send_credits -= 2;
176
177 return index;
178 }
179
180 /*
181 * Consume iov count credits, assumes that iov[0] includes usnic header
182 */
183 static inline uint32_t
_usd_post_send_iov(struct usd_wq * wq,const struct iovec * iov,size_t count,u_int8_t cq_entry)184 _usd_post_send_iov(
185 struct usd_wq *wq,
186 const struct iovec *iov,
187 size_t count,
188 u_int8_t cq_entry)
189 {
190 struct vnic_wq *vwq;
191 uint32_t index;
192 struct wq_enet_desc *desc;
193 u_int8_t offload_mode = 0;
194 u_int16_t mss = 7, header_length = 0, vlan_tag = 0;
195 u_int8_t vlan_tag_insert = 0, loopback = 0, fcoe_encap = 0;
196 unsigned i;
197
198 vwq = &wq->uwq_vnic_wq;
199 desc = wq->uwq_next_desc;
200 index = wq->uwq_post_index;
201
202 for (i = 0; i < count - 1; i++) {
203 wq_enet_desc_enc(desc, (uintptr_t)(iov[i].iov_base),
204 iov[i].iov_len, mss, header_length, offload_mode,
205 0, 0, fcoe_encap, vlan_tag_insert, vlan_tag, loopback);
206 desc = (struct wq_enet_desc *) ((uintptr_t)wq->uwq_desc_ring
207 + (index<<4));
208 index = (index+1) & wq->uwq_post_index_mask;
209 }
210
211 wq_enet_desc_enc(desc, (uintptr_t)(iov[i].iov_base),
212 iov[i].iov_len, mss, header_length, offload_mode,
213 1, cq_entry, fcoe_encap, vlan_tag_insert, vlan_tag, loopback);
214
215 wmb();
216
217 iowrite32(index, &vwq->ctrl->posted_index);
218
219 wq->uwq_next_desc = (struct wq_enet_desc *)
220 ((uintptr_t)wq->uwq_desc_ring + (index<<4));
221 wq->uwq_post_index = (index+1) & wq->uwq_post_index_mask;
222 wq->uwq_send_credits -= count;
223
224 return index;
225 }
226
227 #endif /* _USD_POST_H_ */
228