Whamcloud - gitweb
LU-1346 libcfs: cleanup macros in kp30.h
[fs/lustre-release.git] / lnet / klnds / socklnd / socklnd_lib-winnt.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2012, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lnet/klnds/socklnd/socklnd_lib-winnt.c
37  *
38  * windows socknal library
39  */
40
41 #include "socklnd.h"
42
43 # if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM
44 static cfs_sysctl_table_t ksocknal_ctl_table[21];
45
46 cfs_sysctl_table_t ksocknal_top_ctl_table[] = {
47         {
48                 /* ctl_name */  200,
49                 /* procname */  "socknal",
50                 /* data     */  NULL,
51                 /* maxlen   */  0,
52                 /* mode     */  0555,
53                 /* child    */  ksocknal_ctl_table
54         },
55         { 0 }
56 };
57
58 int
59 ksocknal_lib_tunables_init ()
60 {
61         int    i = 0;
62         int    j = 1;
63
64         ksocknal_ctl_table[i].ctl_name = j++;
65         ksocknal_ctl_table[i].procname = "timeout";
66         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_timeout;
67         ksocknal_ctl_table[i].maxlen   = sizeof (int);
68         ksocknal_ctl_table[i].mode     = 0644;
69         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
70         i++;
71
72         ksocknal_ctl_table[i].ctl_name = j++;
73         ksocknal_ctl_table[i].procname = "credits";
74         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_credits;
75         ksocknal_ctl_table[i].maxlen   = sizeof (int);
76         ksocknal_ctl_table[i].mode     = 0444;
77         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
78         i++;
79
80         ksocknal_ctl_table[i].ctl_name = j++;
81         ksocknal_ctl_table[i].procname = "peer_credits";
82         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_peertxcredits;
83         ksocknal_ctl_table[i].maxlen   = sizeof (int);
84         ksocknal_ctl_table[i].mode     = 0444;
85         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
86         i++;
87
88         ksocknal_ctl_table[i].ctl_name = j++;
89         ksocknal_ctl_table[i].procname = "peer_buffer_credits";
90         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_peerrtrcredits;
91         ksocknal_ctl_table[i].maxlen   = sizeof (int);
92         ksocknal_ctl_table[i].mode     = 0444;
93         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
94         i++;
95
96         ksocknal_ctl_table[i].ctl_name = j++;
97         ksocknal_ctl_table[i].procname = "nconnds";
98         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_nconnds;
99         ksocknal_ctl_table[i].maxlen   = sizeof (int);
100         ksocknal_ctl_table[i].mode     = 0444;
101         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
102         i++;
103
104
105         ksocknal_ctl_table[i].ctl_name = j++;
106         ksocknal_ctl_table[i].procname = "min_reconnectms";
107         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_min_reconnectms;
108         ksocknal_ctl_table[i].maxlen   = sizeof (int);
109         ksocknal_ctl_table[i].mode     = 0444;
110         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
111         i++;
112
113         ksocknal_ctl_table[i].ctl_name = j++;
114         ksocknal_ctl_table[i].procname = "max_reconnectms";
115         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_max_reconnectms;
116         ksocknal_ctl_table[i].maxlen   = sizeof (int);
117         ksocknal_ctl_table[i].mode     = 0444;
118         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
119         i++;
120
121         ksocknal_ctl_table[i].ctl_name = j++;
122         ksocknal_ctl_table[i].procname = "eager_ack";
123         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_eager_ack;
124         ksocknal_ctl_table[i].maxlen   = sizeof (int);
125         ksocknal_ctl_table[i].mode     = 0644;
126         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
127         i++;
128
129         ksocknal_ctl_table[i].ctl_name = j++;
130         ksocknal_ctl_table[i].procname = "zero_copy";
131         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_zc_min_payload;
132         ksocknal_ctl_table[i].maxlen   = sizeof (int);
133         ksocknal_ctl_table[i].mode     = 0644;
134         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
135         i++;
136
137         ksocknal_ctl_table[i].ctl_name = j++;
138         ksocknal_ctl_table[i].procname = "typed";
139         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_typed_conns;
140         ksocknal_ctl_table[i].maxlen   = sizeof (int);
141         ksocknal_ctl_table[i].mode     = 0444;
142         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
143         i++;
144
145         ksocknal_ctl_table[i].ctl_name = j++;
146         ksocknal_ctl_table[i].procname = "min_bulk";
147         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_min_bulk;
148         ksocknal_ctl_table[i].maxlen   = sizeof (int);
149         ksocknal_ctl_table[i].mode     = 0644;
150         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
151         i++;
152
153         ksocknal_ctl_table[i].ctl_name = j++;
154         ksocknal_ctl_table[i].procname = "rx_buffer_size";
155         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_rx_buffer_size;
156         ksocknal_ctl_table[i].maxlen   = sizeof(int);
157         ksocknal_ctl_table[i].mode     = 0644;
158         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
159         i++;
160
161         ksocknal_ctl_table[i].ctl_name = j++;
162         ksocknal_ctl_table[i].procname = "tx_buffer_size";
163         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_tx_buffer_size;
164         ksocknal_ctl_table[i].maxlen   = sizeof(int);
165         ksocknal_ctl_table[i].mode     = 0644;
166         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
167         i++;
168
169         ksocknal_ctl_table[i].ctl_name = j++;
170         ksocknal_ctl_table[i].procname = "nagle";
171         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_nagle;
172         ksocknal_ctl_table[i].maxlen   = sizeof(int);
173         ksocknal_ctl_table[i].mode     = 0644;
174         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
175         i++;
176
177         ksocknal_ctl_table[i].ctl_name = j++;
178         ksocknal_ctl_table[i].procname = "round_robin";
179         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_round_robin;
180         ksocknal_ctl_table[i].maxlen   = sizeof(int);
181         ksocknal_ctl_table[i].mode     = 0644;
182         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
183         i++;
184
185 #ifdef CPU_AFFINITY
186         ksocknal_ctl_table[i].ctl_name = j++;
187         ksocknal_ctl_table[i].procname = "irq_affinity";
188         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_irq_affinity;
189         ksocknal_ctl_table[i].maxlen   = sizeof(int);
190         ksocknal_ctl_table[i].mode     = 0644;
191         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
192         i++;
193 #endif
194
195         ksocknal_ctl_table[i].ctl_name = j++;
196         ksocknal_ctl_table[i].procname = "keepalive_idle";
197         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_keepalive_idle;
198         ksocknal_ctl_table[i].maxlen   = sizeof(int);
199         ksocknal_ctl_table[i].mode     = 0644;
200         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
201         i++;
202
203         ksocknal_ctl_table[i].ctl_name = j++;
204         ksocknal_ctl_table[i].procname = "keepalive_count";
205         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_keepalive_count;
206         ksocknal_ctl_table[i].maxlen   = sizeof(int);
207         ksocknal_ctl_table[i].mode     = 0644;
208         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
209         i++;
210
211         ksocknal_ctl_table[i].ctl_name = j++;
212         ksocknal_ctl_table[i].procname = "keepalive_intvl";
213         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_keepalive_intvl;
214         ksocknal_ctl_table[i].maxlen   = sizeof(int);
215         ksocknal_ctl_table[i].mode     = 0644;
216         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
217         i++;
218
219 #ifdef SOCKNAL_BACKOFF
220         ksocknal_ctl_table[i].ctl_name = j++;
221         ksocknal_ctl_table[i].procname = "backoff_init";
222         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_backoff_init;
223         ksocknal_ctl_table[i].maxlen   = sizeof(int);
224         ksocknal_ctl_table[i].mode     = 0644;
225         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
226         i++;
227
228         ksocknal_ctl_table[i].ctl_name = j++;
229         ksocknal_ctl_table[i].procname = "backoff_max";
230         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_backoff_max;
231         ksocknal_ctl_table[i].maxlen   = sizeof(int);
232         ksocknal_ctl_table[i].mode     = 0644;
233         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
234         i++;
235 #endif
236
237 #if SOCKNAL_VERSION_DEBUG
238         ksocknal_ctl_table[i].ctl_name = j++;
239         ksocknal_ctl_table[i].procname = "protocol";
240         ksocknal_ctl_table[i].data     = ksocknal_tunables.ksnd_protocol;
241         ksocknal_ctl_table[i].maxlen   = sizeof(int);
242         ksocknal_ctl_table[i].mode     = 0644;
243         ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
244         i++;
245 #endif
246
247         LASSERT (j == i + 1);
248         LASSERT (i <= sizeof(ksocknal_ctl_table)/sizeof(ksocknal_ctl_table[0]));
249
250         ksocknal_tunables.ksnd_sysctl =
251                 cfs_register_sysctl_table(ksocknal_top_ctl_table, 0);
252
253         if (ksocknal_tunables.ksnd_sysctl == NULL)
254                 CWARN("Can't setup /proc tunables\n");
255
256         return 0;
257 }
258
259 void
260 ksocknal_lib_tunables_fini ()
261 {
262         if (ksocknal_tunables.ksnd_sysctl != NULL)
263                 cfs_unregister_sysctl_table(ksocknal_tunables.ksnd_sysctl);
264 }
265 #else
266 int
267 ksocknal_lib_tunables_init ()
268 {
269         return 0;
270 }
271
272 void
273 ksocknal_lib_tunables_fini ()
274 {
275 }
276 #endif /* # if CONFIG_SYSCTL && !CFS_SYSFS_MODULE_PARM */
277
278 void
279 ksocknal_lib_bind_irq (unsigned int irq)
280 {
281 }
282
283 int
284 ksocknal_lib_get_conn_addrs (ksock_conn_t *conn)
285 {
286         int rc = libcfs_sock_getaddr(conn->ksnc_sock, 1,
287                                      &conn->ksnc_ipaddr,
288                                      &conn->ksnc_port);
289
290         /* Didn't need the {get,put}connsock dance to deref ksnc_sock... */
291         LASSERT (!conn->ksnc_closing);
292
293         if (rc != 0) {
294                 CERROR ("Error %d getting sock peer IP\n", rc);
295                 return rc;
296         }
297
298         rc = libcfs_sock_getaddr(conn->ksnc_sock, 0,
299                                  &conn->ksnc_myipaddr, NULL);
300         if (rc != 0) {
301                 CERROR ("Error %d getting sock local IP\n", rc);
302                 return rc;
303         }
304
305         return 0;
306 }
307
308 unsigned int
309 ksocknal_lib_sock_irq (struct socket *sock)
310 {
311         return 0;
312 }
313
314 int
315 ksocknal_lib_send_iov (ksock_conn_t *conn, ksock_tx_t *tx)
316 {
317         struct socket *sock = conn->ksnc_sock;
318
319         int            nob;
320         int            rc;
321         int            flags;
322
323
324         if (*ksocknal_tunables.ksnd_enable_csum        && /* checksum enabled */
325             conn->ksnc_proto == &ksocknal_protocol_v2x && /* V2.x connection  */
326             tx->tx_nob == tx->tx_resid                 && /* frist sending    */
327             tx->tx_msg.ksm_csum == 0)                     /* not checksummed  */
328                 ksocknal_lib_csum_tx(tx);
329
330         nob = ks_query_iovs_length(tx->tx_iov, tx->tx_niov);
331         flags = (!cfs_list_empty (&conn->ksnc_tx_queue) || nob < tx->tx_resid) ? 
332                 (MSG_DONTWAIT | MSG_MORE) : MSG_DONTWAIT;
333         rc = ks_send_iovs(sock, tx->tx_iov, tx->tx_niov, flags, 0);
334
335         KsPrint((4, "ksocknal_lib_send_iov: conn %p sock %p rc %d\n",
336                      conn, sock, rc));
337         return rc;
338 }
339
340 int
341 ksocknal_lib_send_kiov (ksock_conn_t *conn, ksock_tx_t *tx)
342 {
343         struct socket *sock = conn->ksnc_sock;
344         lnet_kiov_t    *kiov = tx->tx_kiov;
345         int            rc;
346         int            nob;
347         int            nkiov;
348         int            flags;
349
350         nkiov = tx->tx_nkiov;
351         nob = ks_query_kiovs_length(tx->tx_kiov, nkiov);
352         flags = (!cfs_list_empty (&conn->ksnc_tx_queue) || nob < tx->tx_resid) ? 
353                 (MSG_DONTWAIT | MSG_MORE) : MSG_DONTWAIT;
354         rc = ks_send_kiovs(sock, tx->tx_kiov, nkiov, flags, 0);
355
356         KsPrint((4, "ksocknal_lib_send_kiov: conn %p sock %p rc %d\n",
357                     conn, sock, rc));
358         return rc;
359 }
360
361 int
362 ksocknal_lib_recv_iov (ksock_conn_t *conn)
363 {
364         struct iovec *iov = conn->ksnc_rx_iov;
365         int           rc;
366         int           size;
367
368         /* receive payload from tsdu queue */
369         rc = ks_recv_iovs (conn->ksnc_sock, iov, conn->ksnc_rx_niov,
370                            MSG_DONTWAIT, 0);
371
372         /* calcuate package checksum */
373         if (rc > 0) {
374
375                 int     i;
376                 int     fragnob;
377                 int     sum;
378                 __u32   saved_csum = 0;
379
380                 if (conn->ksnc_proto == &ksocknal_protocol_v2x) {
381                         saved_csum = conn->ksnc_msg.ksm_csum;
382                         conn->ksnc_msg.ksm_csum = 0;
383                 }
384
385                 if (saved_csum != 0) {
386
387                         /* accumulate checksum */
388                         for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
389                                 LASSERT (i < conn->ksnc_rx_niov);
390
391                                 fragnob = iov[i].iov_len;
392                                 if (fragnob > sum)
393                                         fragnob = sum;
394
395                                 conn->ksnc_rx_csum = ksocknal_csum(conn->ksnc_rx_csum,
396                                                                    iov[i].iov_base, fragnob);
397                         }
398                         conn->ksnc_msg.ksm_csum = saved_csum;
399                 }
400         }
401
402         KsPrint((4, "ksocknal_lib_recv_iov: conn %p sock %p rc %d.\n",
403                     conn, conn->ksnc_sock, rc));
404         return rc;
405 }
406
407 int
408 ksocknal_lib_recv_kiov (ksock_conn_t *conn)
409 {
410         lnet_kiov_t  *kiov = conn->ksnc_rx_kiov;
411         int           rc;
412
413         /* NB we can't trust socket ops to either consume our iovs
414          * or leave them alone, so we only receive 1 frag at a time. */
415         LASSERT (conn->ksnc_rx_nkiov > 0);
416
417         /* receive payload from tsdu queue */
418         rc = ks_recv_kiovs (conn->ksnc_sock, kiov, conn->ksnc_rx_nkiov,
419                             MSG_DONTWAIT, 0);
420
421         if (rc > 0 && conn->ksnc_msg.ksm_csum != 0) {
422
423                 int          i;
424                 char        *base;
425                 int          sum;
426                 int          fragnob;
427
428                 for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
429
430                         LASSERT (i < conn->ksnc_rx_nkiov);
431
432                         base = (char *)(kiov[i].kiov_page->addr) + kiov[i].kiov_offset;
433                         fragnob = kiov[i].kiov_len;
434                         if (fragnob > sum)
435                                 fragnob = sum;
436
437                         conn->ksnc_rx_csum = ksocknal_csum(conn->ksnc_rx_csum,
438                                                            base, fragnob);
439                 }
440         }
441
442         KsPrint((4, "ksocknal_lib_recv_kiov: conn %p sock %p rc %d.\n",
443                     conn, conn->ksnc_sock, rc));
444         return rc;
445 }
446
447 void
448 ksocknal_lib_eager_ack (ksock_conn_t *conn)
449 {
450         __u32   option = 1;
451         int     rc = 0;
452                 
453         rc = ks_set_tcp_option(
454                 conn->ksnc_sock, TCP_SOCKET_NODELAY,
455                 &option, sizeof(option) );
456         if (rc != 0) {
457                 CERROR("Can't disable nagle: %d\n", rc);
458         }
459 }
460
461 int
462 ksocknal_lib_get_conn_tunables (ksock_conn_t *conn, int *txmem, int *rxmem, int *nagle)
463 {
464         ks_tconn_t *    tconn = conn->ksnc_sock;
465         int             len;
466         int             rc;
467
468         ks_get_tconn (tconn);
469         *txmem = *rxmem = 0;
470         len = sizeof(*nagle);
471         rc = ks_get_tcp_option(tconn, TCP_SOCKET_NODELAY, (__u32 *)nagle, &len);
472         ks_put_tconn (tconn);
473
474         KsPrint((2, "ksocknal_get_conn_tunables: nodelay = %d rc = %d\n", *nagle, rc));
475
476         if (rc == 0)
477                 *nagle = !*nagle;
478         else
479                 *txmem = *rxmem = *nagle = 0;
480                 
481         return (rc);
482 }
483
484 int
485 ksocknal_lib_setup_sock (struct socket *sock)
486 {
487         int             rc;
488
489         int             keep_idle;
490         int             keep_count;
491         int             keep_intvl;
492         int             keep_alive;
493
494         __u32           option;
495
496 #if 0
497         /* set the window size */
498         tconn->kstc_snd_wnd = ksocknal_tunables.ksnd_buffer_size;
499         tconn->kstc_rcv_wnd = ksocknal_tunables.ksnd_buffer_size;
500 #endif
501
502         /* disable nagle */
503         if (!ksocknal_tunables.ksnd_nagle) {
504                 option = 1;
505                 
506                 rc = ks_set_tcp_option(
507                             sock, TCP_SOCKET_NODELAY,
508                             &option, sizeof (option));
509                 if (rc != 0) {
510                         CERROR ("Can't disable nagle: %d\n", rc);
511                         return (rc);
512                 }
513         }
514
515         /* snapshot tunables */
516         keep_idle  = *ksocknal_tunables.ksnd_keepalive_idle;
517         keep_count = *ksocknal_tunables.ksnd_keepalive_count;
518         keep_intvl = *ksocknal_tunables.ksnd_keepalive_intvl;
519         
520         keep_alive = (keep_idle > 0 && keep_count > 0 && keep_intvl > 0);
521
522         option = (__u32)(keep_alive ? 1 : 0);
523
524         rc = ks_set_tcp_option(
525                     sock, TCP_SOCKET_KEEPALIVE,
526                     &option, sizeof (option));
527         if (rc != 0) {
528                 CERROR ("Can't disable nagle: %d\n", rc);
529                 return (rc);
530         }
531
532         return (0);
533 }
534
535 void
536 ksocknal_lib_push_conn (ksock_conn_t *conn)
537 {
538         ks_tconn_t *    tconn;
539         __u32           nagle;
540         __u32           val = 1;
541         int             rc;
542
543         tconn = conn->ksnc_sock;
544
545         ks_get_tconn(tconn);
546
547         spin_lock(&tconn->kstc_lock);
548         if (tconn->kstc_type == kstt_sender) {
549                 nagle = tconn->sender.kstc_info.nagle;
550                 tconn->sender.kstc_info.nagle = 0;
551         } else {
552                 LASSERT(tconn->kstc_type == kstt_child);
553                 nagle = tconn->child.kstc_info.nagle;
554                 tconn->child.kstc_info.nagle = 0;
555         }
556
557         spin_unlock(&tconn->kstc_lock);
558
559         val = 1;
560         rc = ks_set_tcp_option(
561                     tconn,
562                     TCP_SOCKET_NODELAY,
563                     &(val),
564                     sizeof(__u32)
565                     );
566
567         LASSERT (rc == 0);
568         spin_lock(&tconn->kstc_lock);
569
570         if (tconn->kstc_type == kstt_sender) {
571                 tconn->sender.kstc_info.nagle = nagle;
572         } else {
573                 LASSERT(tconn->kstc_type == kstt_child);
574                 tconn->child.kstc_info.nagle = nagle;
575         }
576         spin_unlock(&tconn->kstc_lock);
577         ks_put_tconn(tconn);
578 }
579
580 void
581 ksocknal_lib_csum_tx(ksock_tx_t *tx)
582 {
583         int          i;
584         __u32        csum;
585         void        *base;
586
587         LASSERT(tx->tx_iov[0].iov_base == (void *)&tx->tx_msg);
588         LASSERT(tx->tx_conn != NULL);
589         LASSERT(tx->tx_conn->ksnc_proto == &ksocknal_protocol_v2x);
590
591         tx->tx_msg.ksm_csum = 0;
592
593         csum = ksocknal_csum(~0, (void *)tx->tx_iov[0].iov_base,
594                              tx->tx_iov[0].iov_len);
595
596         if (tx->tx_kiov != NULL) {
597                 for (i = 0; i < tx->tx_nkiov; i++) {
598                         base = (PUCHAR)(tx->tx_kiov[i].kiov_page->addr) +
599                                tx->tx_kiov[i].kiov_offset;
600
601                         csum = ksocknal_csum(csum, base, tx->tx_kiov[i].kiov_len);
602                 }
603         } else {
604                 for (i = 1; i < tx->tx_niov; i++)
605                         csum = ksocknal_csum(csum, tx->tx_iov[i].iov_base,
606                                              tx->tx_iov[i].iov_len);
607         }
608
609         if (*ksocknal_tunables.ksnd_inject_csum_error) {
610                 csum++;
611                 *ksocknal_tunables.ksnd_inject_csum_error = 0;
612         }
613
614         tx->tx_msg.ksm_csum = csum;
615 }
616
617 void ksocknal_schedule_callback(struct socket*sock, int mode)
618 {
619         ksock_conn_t * conn = (ksock_conn_t *) sock->kstc_conn;
620
621         read_lock(&ksocknal_data.ksnd_global_lock);
622         if (mode) {
623                 ksocknal_write_callback(conn);
624         } else {
625                 ksocknal_read_callback(conn);
626         }
627         read_unlock(&ksocknal_data.ksnd_global_lock);
628 }
629
630 void
631 ksocknal_tx_fini_callback(ksock_conn_t * conn, ksock_tx_t * tx)
632 {
633         /* remove tx/conn from conn's outgoing queue */
634         spin_lock_bh(&conn->ksnc_scheduler->kss_lock);
635         cfs_list_del(&tx->tx_list);
636         if (cfs_list_empty(&conn->ksnc_tx_queue))
637                 cfs_list_del(&conn->ksnc_tx_list);
638
639         spin_unlock_bh(&conn->ksnc_scheduler->kss_lock);
640
641         /* complete send; tx -ref */
642         ksocknal_tx_decref(tx);
643 }
644
645 void
646 ksocknal_lib_save_callback(struct socket *sock, ksock_conn_t *conn)
647 {
648 }
649
650 void
651 ksocknal_lib_set_callback(struct socket *sock,  ksock_conn_t *conn)
652 {
653         sock->kstc_conn      = conn;
654         sock->kstc_sched_cb  = ksocknal_schedule_callback;
655 }
656
657 void
658 ksocknal_lib_reset_callback(struct socket *sock, ksock_conn_t *conn)
659 {
660         sock->kstc_conn      = NULL;
661         sock->kstc_sched_cb  = NULL;
662 }
663
664 int
665 ksocknal_lib_zc_capable(ksock_conn_t *conn)
666 {
667         return 0;
668 }
669
670 int
671 ksocknal_lib_memory_pressure(ksock_conn_t *conn)
672 {
673         return 0;
674 }
675
676 int
677 ksocknal_lib_bind_thread_to_cpu(int id)
678 {
679         return 0;
680 }