aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
authorUpinder Malhi <umalhi@cisco.com>2014-01-09 17:48:16 -0500
committerRoland Dreier <roland@purestorage.com>2014-01-14 03:44:44 -0500
commit6214105460842759020bdd7f4dbb50afa1be9d17 (patch)
tree687d79c4b8b696d8ad08f9aa5cacc57fd24667b2 /drivers/infiniband/hw
parent3f92bed3d6c073f41efc0777ecd3442aa1f03d20 (diff)
IB:usnic: Add UDP support to usnic_transport.[hc]
This patch provides API for rest of usNIC code to increment or decrement socket's reference count. Auxiliary socket APIs are also provided. Signed-off-by: Upinder Malhi <umalhi@cisco.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/usnic/usnic_transport.c93
-rw-r--r--drivers/infiniband/hw/usnic/usnic_transport.h19
2 files changed, 105 insertions, 7 deletions
diff --git a/drivers/infiniband/hw/usnic/usnic_transport.c b/drivers/infiniband/hw/usnic/usnic_transport.c
index 723bd6c3a8f8..73dffc9c535a 100644
--- a/drivers/infiniband/hw/usnic/usnic_transport.c
+++ b/drivers/infiniband/hw/usnic/usnic_transport.c
@@ -16,8 +16,10 @@
16 * 16 *
17 */ 17 */
18#include <linux/bitmap.h> 18#include <linux/bitmap.h>
19#include <linux/file.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
22#include <net/inet_sock.h>
21 23
22#include "usnic_transport.h" 24#include "usnic_transport.h"
23#include "usnic_log.h" 25#include "usnic_log.h"
@@ -28,13 +30,15 @@ static u16 roce_next_port = 1;
28#define ROCE_BITMAP_SZ ((1 << (8 /*CHAR_BIT*/ * sizeof(u16)))/8 /*CHAR BIT*/) 30#define ROCE_BITMAP_SZ ((1 << (8 /*CHAR_BIT*/ * sizeof(u16)))/8 /*CHAR BIT*/)
29static DEFINE_SPINLOCK(roce_bitmap_lock); 31static DEFINE_SPINLOCK(roce_bitmap_lock);
30 32
31static const char *transport_to_str(enum usnic_transport_type type) 33const char *usnic_transport_to_str(enum usnic_transport_type type)
32{ 34{
33 switch (type) { 35 switch (type) {
34 case USNIC_TRANSPORT_UNKNOWN: 36 case USNIC_TRANSPORT_UNKNOWN:
35 return "Unknown"; 37 return "Unknown";
36 case USNIC_TRANSPORT_ROCE_CUSTOM: 38 case USNIC_TRANSPORT_ROCE_CUSTOM:
37 return "roce custom"; 39 return "roce custom";
40 case USNIC_TRANSPORT_IPV4_UDP:
41 return "IPv4 UDP";
38 case USNIC_TRANSPORT_MAX: 42 case USNIC_TRANSPORT_MAX:
39 return "Max?"; 43 return "Max?";
40 default: 44 default:
@@ -42,6 +46,24 @@ static const char *transport_to_str(enum usnic_transport_type type)
42 } 46 }
43} 47}
44 48
49int usnic_transport_sock_to_str(char *buf, int buf_sz,
50 struct socket *sock)
51{
52 int err;
53 uint32_t addr;
54 uint16_t port;
55 int proto;
56
57 memset(buf, 0, buf_sz);
58 err = usnic_transport_sock_get_addr(sock, &proto, &addr, &port);
59 if (err)
60 return 0;
61
62 addr = htonl(addr);
63 return scnprintf(buf, buf_sz, "Proto:%u Addr:%pI4 Port:%hu",
64 proto, &addr, port);
65}
66
45/* 67/*
46 * reserve a port number. if "0" specified, we will try to pick one 68 * reserve a port number. if "0" specified, we will try to pick one
47 * starting at roce_next_port. roce_next_port will take on the values 69 * starting at roce_next_port. roce_next_port will take on the values
@@ -60,7 +82,7 @@ u16 usnic_transport_rsrv_port(enum usnic_transport_type type, u16 port_num)
60 roce_next_port = (port_num & 4095) + 1; 82 roce_next_port = (port_num & 4095) + 1;
61 } else if (test_bit(port_num, roce_bitmap)) { 83 } else if (test_bit(port_num, roce_bitmap)) {
62 usnic_err("Failed to allocate port for %s\n", 84 usnic_err("Failed to allocate port for %s\n",
63 transport_to_str(type)); 85 usnic_transport_to_str(type));
64 spin_unlock(&roce_bitmap_lock); 86 spin_unlock(&roce_bitmap_lock);
65 goto out_fail; 87 goto out_fail;
66 } 88 }
@@ -68,12 +90,12 @@ u16 usnic_transport_rsrv_port(enum usnic_transport_type type, u16 port_num)
68 spin_unlock(&roce_bitmap_lock); 90 spin_unlock(&roce_bitmap_lock);
69 } else { 91 } else {
70 usnic_err("Failed to allocate port - transport %s unsupported\n", 92 usnic_err("Failed to allocate port - transport %s unsupported\n",
71 transport_to_str(type)); 93 usnic_transport_to_str(type));
72 goto out_fail; 94 goto out_fail;
73 } 95 }
74 96
75 usnic_dbg("Allocating port %hu for %s\n", port_num, 97 usnic_dbg("Allocating port %hu for %s\n", port_num,
76 transport_to_str(type)); 98 usnic_transport_to_str(type));
77 return port_num; 99 return port_num;
78 100
79out_fail: 101out_fail:
@@ -86,19 +108,19 @@ void usnic_transport_unrsrv_port(enum usnic_transport_type type, u16 port_num)
86 spin_lock(&roce_bitmap_lock); 108 spin_lock(&roce_bitmap_lock);
87 if (!port_num) { 109 if (!port_num) {
88 usnic_err("Unreserved unvalid port num 0 for %s\n", 110 usnic_err("Unreserved unvalid port num 0 for %s\n",
89 transport_to_str(type)); 111 usnic_transport_to_str(type));
90 goto out_roce_custom; 112 goto out_roce_custom;
91 } 113 }
92 114
93 if (!test_bit(port_num, roce_bitmap)) { 115 if (!test_bit(port_num, roce_bitmap)) {
94 usnic_err("Unreserving invalid %hu for %s\n", 116 usnic_err("Unreserving invalid %hu for %s\n",
95 port_num, 117 port_num,
96 transport_to_str(type)); 118 usnic_transport_to_str(type));
97 goto out_roce_custom; 119 goto out_roce_custom;
98 } 120 }
99 bitmap_clear(roce_bitmap, port_num, 1); 121 bitmap_clear(roce_bitmap, port_num, 1);
100 usnic_dbg("Freeing port %hu for %s\n", port_num, 122 usnic_dbg("Freeing port %hu for %s\n", port_num,
101 transport_to_str(type)); 123 usnic_transport_to_str(type));
102out_roce_custom: 124out_roce_custom:
103 spin_unlock(&roce_bitmap_lock); 125 spin_unlock(&roce_bitmap_lock);
104 } else { 126 } else {
@@ -106,6 +128,63 @@ out_roce_custom:
106 } 128 }
107} 129}
108 130
131struct socket *usnic_transport_get_socket(int sock_fd)
132{
133 struct socket *sock;
134 int err;
135 char buf[25];
136
137 /* sockfd_lookup will internally do a fget */
138 sock = sockfd_lookup(sock_fd, &err);
139 if (!sock) {
140 usnic_err("Unable to lookup socket for fd %d with err %d\n",
141 sock_fd, err);
142 return ERR_PTR(-ENOENT);
143 }
144
145 usnic_transport_sock_to_str(buf, sizeof(buf), sock);
146 usnic_dbg("Get sock %s\n", buf);
147
148 return sock;
149}
150
151void usnic_transport_put_socket(struct socket *sock)
152{
153 char buf[100];
154
155 usnic_transport_sock_to_str(buf, sizeof(buf), sock);
156 usnic_dbg("Put sock %s\n", buf);
157 sockfd_put(sock);
158}
159
160int usnic_transport_sock_get_addr(struct socket *sock, int *proto,
161 uint32_t *addr, uint16_t *port)
162{
163 int len;
164 int err;
165 struct sockaddr_in sock_addr;
166
167 err = sock->ops->getname(sock,
168 (struct sockaddr *)&sock_addr,
169 &len, 0);
170 if (err)
171 return err;
172
173 if (sock_addr.sin_family != AF_INET)
174 return -EINVAL;
175
176 if (proto)
177 *proto = sock->sk->sk_protocol;
178 if (port)
179 *port = ntohs(((struct sockaddr_in *)&sock_addr)->sin_port);
180 if (addr)
181 *addr = ntohl(((struct sockaddr_in *)
182 &sock_addr)->sin_addr.s_addr);
183
184 return 0;
185}
186
187
109int usnic_transport_init(void) 188int usnic_transport_init(void)
110{ 189{
111 roce_bitmap = kzalloc(ROCE_BITMAP_SZ, GFP_KERNEL); 190 roce_bitmap = kzalloc(ROCE_BITMAP_SZ, GFP_KERNEL);
diff --git a/drivers/infiniband/hw/usnic/usnic_transport.h b/drivers/infiniband/hw/usnic/usnic_transport.h
index 091fdaf4d25a..21371bb86c71 100644
--- a/drivers/infiniband/hw/usnic/usnic_transport.h
+++ b/drivers/infiniband/hw/usnic/usnic_transport.h
@@ -21,8 +21,27 @@
21 21
22#include "usnic_abi.h" 22#include "usnic_abi.h"
23 23
24const char *usnic_transport_to_str(enum usnic_transport_type trans_type);
25/*
26 * Returns number of bytes written, excluding null terminator. If
27 * nothing was written, the function returns 0.
28 */
29int usnic_transport_sock_to_str(char *buf, int buf_sz,
30 struct socket *sock);
24u16 usnic_transport_rsrv_port(enum usnic_transport_type type, u16 port_num); 31u16 usnic_transport_rsrv_port(enum usnic_transport_type type, u16 port_num);
25void usnic_transport_unrsrv_port(enum usnic_transport_type type, u16 port_num); 32void usnic_transport_unrsrv_port(enum usnic_transport_type type, u16 port_num);
33/*
34 * Do a fget on the socket refered to by sock_fd and returns the socket.
35 * Socket will not be destroyed before usnic_transport_put_socket has
36 * been called.
37 */
38struct socket *usnic_transport_get_socket(int sock_fd);
39void usnic_transport_put_socket(struct socket *sock);
40/*
41 * Call usnic_transport_get_socket before calling *_sock_get_addr
42 */
43int usnic_transport_sock_get_addr(struct socket *sock, int *proto,
44 uint32_t *addr, uint16_t *port);
26int usnic_transport_init(void); 45int usnic_transport_init(void);
27void usnic_transport_fini(void); 46void usnic_transport_fini(void);
28#endif /* !USNIC_TRANSPORT_H */ 47#endif /* !USNIC_TRANSPORT_H */