Quellcode durchsuchen

Merge from Etherboot 5.4

tags/v0.9.3
Michael Brown vor 18 Jahren
Ursprung
Commit
28cefdccc4

+ 2800
- 0
src/drivers/net/mlx_ipoib/MT23108_PRM.h
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 199
- 0
src/drivers/net/mlx_ipoib/MT23108_PRM_append.h Datei anzeigen

@@ -0,0 +1,199 @@
1
+/*
2
+  This software is available to you under a choice of one of two
3
+  licenses.  You may choose to be licensed under the terms of the GNU
4
+  General Public License (GPL) Version 2, available at
5
+  <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6
+  license, available in the LICENSE.TXT file accompanying this
7
+  software.  These details are also available at
8
+  <http://openib.org/license.html>.
9
+
10
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
+  SOFTWARE.
18
+
19
+  Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
20
+*/
21
+
22
+/***
23
+ *** This file was generated at "Tue Nov 16 17:03:53 2004"
24
+ *** by:
25
+ ***    % csp_bf -copyright=/mswg/misc/license-header.txt -bits MT23108_PRM_append.csp
26
+ ***/
27
+
28
+#ifndef H_bits_MT23108_PRM_append_csp_H
29
+#define H_bits_MT23108_PRM_append_csp_H
30
+
31
+
32
+/* Gather entry with inline data */
33
+
34
+struct wqe_segment_data_inline_st {	/* Little Endian */
35
+    pseudo_bit_t	byte_count[0x0000a];   /* Not including padding for 16Byte chunks */
36
+    pseudo_bit_t	reserved0[0x00015];
37
+    pseudo_bit_t	always1[0x00001];
38
+/* -------------- */
39
+    pseudo_bit_t	data[0x00020];         /* Data may be more this segment size - in 16Byte chunks */
40
+/* -------------- */
41
+}; 
42
+
43
+/* Scatter/Gather entry with a pointer */
44
+
45
+struct wqe_segment_data_ptr_st {	/* Little Endian */
46
+    pseudo_bit_t	byte_count[0x0001f];
47
+    pseudo_bit_t	always0[0x00001];
48
+/* -------------- */
49
+    pseudo_bit_t	l_key[0x00020];
50
+/* -------------- */
51
+    pseudo_bit_t	local_address_h[0x00020];
52
+/* -------------- */
53
+    pseudo_bit_t	local_address_l[0x00020];
54
+/* -------------- */
55
+}; 
56
+
57
+/*  */
58
+
59
+struct wqe_segment_atomic_st {	/* Little Endian */
60
+    pseudo_bit_t	swap_add_h[0x00020];
61
+/* -------------- */
62
+    pseudo_bit_t	swap_add_l[0x00020];
63
+/* -------------- */
64
+    pseudo_bit_t	compare_h[0x00020];
65
+/* -------------- */
66
+    pseudo_bit_t	compare_l[0x00020];
67
+/* -------------- */
68
+}; 
69
+
70
+/*  */
71
+
72
+struct wqe_segment_remote_address_st {	/* Little Endian */
73
+    pseudo_bit_t	remote_virt_addr_h[0x00020];
74
+/* -------------- */
75
+    pseudo_bit_t	remote_virt_addr_l[0x00020];
76
+/* -------------- */
77
+    pseudo_bit_t	rkey[0x00020];
78
+/* -------------- */
79
+    pseudo_bit_t	reserved0[0x00020];
80
+/* -------------- */
81
+}; 
82
+
83
+/* Bind memory window segment */
84
+
85
+struct wqe_segment_bind_st {	/* Little Endian */
86
+    pseudo_bit_t	reserved0[0x0001d];
87
+    pseudo_bit_t	rr[0x00001];           /* Remote read */
88
+    pseudo_bit_t	rw[0x00001];           /* Remote write */
89
+    pseudo_bit_t	a[0x00001];            /* atomic */
90
+/* -------------- */
91
+    pseudo_bit_t	reserved1[0x00020];
92
+/* -------------- */
93
+    pseudo_bit_t	new_rkey[0x00020];
94
+/* -------------- */
95
+    pseudo_bit_t	region_lkey[0x00020];
96
+/* -------------- */
97
+    pseudo_bit_t	start_address_h[0x00020];
98
+/* -------------- */
99
+    pseudo_bit_t	start_address_l[0x00020];
100
+/* -------------- */
101
+    pseudo_bit_t	length_h[0x00020];
102
+/* -------------- */
103
+    pseudo_bit_t	length_l[0x00020];
104
+/* -------------- */
105
+}; 
106
+
107
+/*  */
108
+
109
+struct wqe_segment_ud_st {	/* Little Endian */
110
+    pseudo_bit_t	reserved0[0x00020];
111
+/* -------------- */
112
+    pseudo_bit_t	l_key[0x00020];        /* memory key for UD AV */
113
+/* -------------- */
114
+    pseudo_bit_t	av_address_63_32[0x00020];
115
+/* -------------- */
116
+    pseudo_bit_t	reserved1[0x00005];
117
+    pseudo_bit_t	av_address_31_5[0x0001b];
118
+/* -------------- */
119
+    pseudo_bit_t	reserved2[0x00080];
120
+/* -------------- */
121
+    pseudo_bit_t	destination_qp[0x00018];
122
+    pseudo_bit_t	reserved3[0x00008];
123
+/* -------------- */
124
+    pseudo_bit_t	q_key[0x00020];
125
+/* -------------- */
126
+    pseudo_bit_t	reserved4[0x00040];
127
+/* -------------- */
128
+}; 
129
+
130
+/*  */
131
+
132
+struct wqe_segment_rd_st {	/* Little Endian */
133
+    pseudo_bit_t	destination_qp[0x00018];
134
+    pseudo_bit_t	reserved0[0x00008];
135
+/* -------------- */
136
+    pseudo_bit_t	q_key[0x00020];
137
+/* -------------- */
138
+    pseudo_bit_t	reserved1[0x00040];
139
+/* -------------- */
140
+}; 
141
+
142
+/*  */
143
+
144
+struct wqe_segment_ctrl_recv_st {	/* Little Endian */
145
+    pseudo_bit_t	reserved0[0x00002];
146
+    pseudo_bit_t	e[0x00001];            /* WQE event */
147
+    pseudo_bit_t	c[0x00001];            /* Create CQE (for "requested signalling" QP) */
148
+    pseudo_bit_t	reserved1[0x0001c];
149
+/* -------------- */
150
+    pseudo_bit_t	reserved2[0x00020];
151
+/* -------------- */
152
+}; 
153
+
154
+/*  */
155
+
156
+struct wqe_segment_ctrl_mlx_st {	/* Little Endian */
157
+    pseudo_bit_t	reserved0[0x00002];
158
+    pseudo_bit_t	e[0x00001];            /* WQE event */
159
+    pseudo_bit_t	c[0x00001];            /* Create CQE (for "requested signalling" QP) */
160
+    pseudo_bit_t	reserved1[0x00004];
161
+    pseudo_bit_t	sl[0x00004];
162
+    pseudo_bit_t	max_statrate[0x00003];
163
+    pseudo_bit_t	reserved2[0x00001];
164
+    pseudo_bit_t	slr[0x00001];          /* 0= take slid from port. 1= take slid from given headers */
165
+    pseudo_bit_t	v15[0x00001];          /* Send packet over VL15 */
166
+    pseudo_bit_t	reserved3[0x0000e];
167
+/* -------------- */
168
+    pseudo_bit_t	vcrc[0x00010];         /* Packet's VCRC (if not 0 - otherwise computed by HW) */
169
+    pseudo_bit_t	rlid[0x00010];         /* Destination LID (must match given headers) */
170
+/* -------------- */
171
+}; 
172
+
173
+/*  */
174
+
175
+struct wqe_segment_ctrl_send_st {	/* Little Endian */
176
+    pseudo_bit_t	always1[0x00001];
177
+    pseudo_bit_t	s[0x00001];            /* Solicited event */
178
+    pseudo_bit_t	e[0x00001];            /* WQE event */
179
+    pseudo_bit_t	c[0x00001];            /* Create CQE (for "requested signalling" QP) */
180
+    pseudo_bit_t	reserved0[0x0001c];
181
+/* -------------- */
182
+    pseudo_bit_t	immediate[0x00020];
183
+/* -------------- */
184
+}; 
185
+
186
+/*  */
187
+
188
+struct wqe_segment_next_st {	/* Little Endian */
189
+    pseudo_bit_t	nopcode[0x00005];      /* next opcode */
190
+    pseudo_bit_t	reserved0[0x00001];
191
+    pseudo_bit_t	nda_31_6[0x0001a];     /* NDA[31:6] */
192
+/* -------------- */
193
+    pseudo_bit_t	nds[0x00006];
194
+    pseudo_bit_t	f[0x00001];            /* fence bit */
195
+    pseudo_bit_t	dbd[0x00001];          /* doorbell rung */
196
+    pseudo_bit_t	nee[0x00018];          /* next EE */
197
+/* -------------- */
198
+}; 
199
+#endif /* H_bits_MT23108_PRM_append_csp_H */

+ 3463
- 0
src/drivers/net/mlx_ipoib/MT25218_PRM.h
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 126
- 0
src/drivers/net/mlx_ipoib/bit_ops.h Datei anzeigen

@@ -0,0 +1,126 @@
1
+/*
2
+  This software is available to you under a choice of one of two
3
+  licenses.  You may choose to be licensed under the terms of the GNU
4
+  General Public License (GPL) Version 2, available at
5
+  <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6
+  license, available in the LICENSE.TXT file accompanying this
7
+  software.  These details are also available at
8
+  <http://openib.org/license.html>.
9
+
10
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
+  SOFTWARE.
18
+
19
+  Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
20
+*/
21
+
22
+#ifndef __bit_ops_h__
23
+#define __bit_ops_h__
24
+
25
+typedef unsigned long MT_offset_t;
26
+typedef unsigned long MT_size_t;
27
+typedef unsigned char pseudo_bit_t;
28
+struct addr_64_st {
29
+	__u32 addr_l;
30
+	__u32 addr_h;
31
+};
32
+
33
+#define MT_BIT_OFFSET(object_struct,reg_path) \
34
+    ((MT_offset_t) &( ((struct object_struct *)(0))-> reg_path ))
35
+
36
+#define MT_BIT_SIZE(object_struct,reg_path) \
37
+    ((MT_size_t) sizeof( ((struct object_struct *)(0))-> reg_path ))
38
+
39
+#define MT_BIT_OFFSET_SIZE(object_struct,reg_path) \
40
+    MT_BIT_OFFSET(object_struct,reg_path),MT_BIT_SIZE(object_struct,reg_path)
41
+
42
+#define MT_BYTE_OFFSET(object_struct,reg_path) \
43
+    ((MT_offset_t) (MT_BIT_OFFSET(object_struct,reg_path)/8))
44
+
45
+#define MT_BYTE_SIZE(object_struct,reg_path) \
46
+    ((MT_size_t) MT_BIT_SIZE(object_struct,reg_path)/8)
47
+
48
+#define MT_BYTE_OFFSET_SIZE(object_struct,reg_path) \
49
+    MT_BYTE_OFFSET(object_struct,reg_path),MT_BYTE_SIZE(object_struct,reg_path)
50
+
51
+#define MT_STRUCT_SIZE(object_struct) (sizeof(struct object_struct) >> 3)
52
+
53
+/*****************************************************************************************
54
+ * Bit manipulation macros
55
+ *****************************************************************************************/
56
+
57
+/* MASK generate a bit mask S bits width */
58
+#define MASK32(S)         ( ((__u32) ~0L) >> (32-(S)) )
59
+
60
+/*
61
+ * BITS generate a bit mask with bits O+S..O set (assumes 32 bit integer).
62
+ *      numbering bits as following:    31........................76543210
63
+ */
64
+#define BITS32(O,S)       ( MASK32(S) << (O) )
65
+
66
+/* 
67
+ * MT_EXTRACT32 macro extracts S bits from (__u32)W with offset O 
68
+ *  and shifts them O places to the right (right justifies the field extracted).
69
+ */
70
+#define MT_EXTRACT32(W,O,S)  ( ((W)>>(O)) & MASK32(S) )
71
+
72
+/*
73
+ * MT_INSERT32 macro inserts S bits with offset O from field F into word W (__u32)
74
+ */
75
+#define MT_INSERT32(W,F,O,S) ((W)= ( ( (W) & (~BITS32(O,S)) ) | (((F) & MASK32(S))<<(O)) ))
76
+
77
+/*
78
+ * MT_EXTRACT_ARRAY32 macro is similar to EXTRACT but works on an array of (__u32),
79
+ * thus offset may be larger than 32 (but not size).
80
+ */
81
+#define MT_EXTRACT_ARRAY32(A,O,S) MT_EXTRACT32(((__u32*)A)[O >> 5],(O & MASK32(5)),S)
82
+
83
+/*
84
+ * MT_INSERT_ARRAY32 macro is similar to INSERT but works on an array of (__u32),
85
+ * thus offset may be larger than 32 (but not size).
86
+ */
87
+#define MT_INSERT_ARRAY32(A,F,O,S) MT_INSERT32(((__u32*)A)[O >> 5],F,(O & MASK32(5)),S)
88
+
89
+#define INS_FLD(src, a, st, fld) MT_INSERT_ARRAY32(a, src, MT_BIT_OFFSET(st, fld), MT_BIT_SIZE(st, fld))
90
+
91
+#define EX_FLD(a, st, fld) MT_EXTRACT_ARRAY32(a, MT_BIT_OFFSET(st, fld), MT_BIT_SIZE(st, fld))
92
+
93
+/* return the address of the dword holding the field 
94
+
95
+	buf = pointer to buffer where to place the value
96
+	st = struct describing the buffer
97
+	fld = field in the struct where to insert the value */
98
+
99
+#define FLD_DW_ADDR(buf, st, fld) ((__u32 *)((__u32 *)(buf)+(((__u32)(&(((struct st *)(0))->fld))) >> 5)))
100
+
101
+/*
102
+	val = value to insert
103
+	buf = pointer to buffer where to place the value
104
+	st = struct describing the buffer
105
+	fld = field in the struct where to insert the value */
106
+
107
+#define INS_FLD_TO_BE(val, buf, st, fld) \
108
+	do { \
109
+		*FLD_DW_ADDR(buf, st, fld) = be32_to_cpu(*FLD_DW_ADDR(buf, st, fld)); \
110
+		INS_FLD(val, buf, st, fld); \
111
+		*FLD_DW_ADDR(buf, st, fld) = cpu_to_be32(*FLD_DW_ADDR(buf, st, fld)); \
112
+	} \
113
+	while(0)
114
+
115
+#define EX_FLD_FROM_BE(buf, st, fld, type) \
116
+({ \
117
+	type field; \
118
+				 \
119
+	*FLD_DW_ADDR(buf, st, fld) = be32_to_cpu(*FLD_DW_ADDR(buf, st, fld)); \
120
+	field= EX_FLD(buf, st, fld); \
121
+	*FLD_DW_ADDR(buf, st, fld) = cpu_to_be32(*FLD_DW_ADDR(buf, st, fld)); \
122
+																		  \
123
+	field; \
124
+})
125
+
126
+#endif				/* __bit_ops_h__ */

+ 50
- 0
src/drivers/net/mlx_ipoib/cmdif.h Datei anzeigen

@@ -0,0 +1,50 @@
1
+/*
2
+  This software is available to you under a choice of one of two
3
+  licenses.  You may choose to be licensed under the terms of the GNU
4
+  General Public License (GPL) Version 2, available at
5
+  <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6
+  license, available in the LICENSE.TXT file accompanying this
7
+  software.  These details are also available at
8
+  <http://openib.org/license.html>.
9
+
10
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
+  SOFTWARE.
18
+
19
+  Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
20
+*/
21
+
22
+#ifndef __cmdif_h_
23
+#define __cmdif_h_
24
+
25
+#include "ib_mad.h"
26
+
27
+static int cmd_init_hca(__u32 * inprm, __u32 in_prm_size);
28
+static int cmd_close_hca(int panic);
29
+static int cmd_sw2hw_eq(__u32 inprm_sz);
30
+static int cmd_hw2sw_eq(__u8 eqn);
31
+static int cmd_map_eq(__u8 eqn, __u32 mask, int map);
32
+static int cmd_sw2hw_mpt(__u32 * lkey, __u32 in_key, __u32 * inprm,
33
+			 __u32 inprm_sz);
34
+static int cmd_hw2sw_mpt(__u32 key);
35
+static int cmd_init_ib(__u32 port, __u32 * inprm, __u32 inprm_sz);
36
+static int cmd_close_ib(__u32 port);
37
+static int cmd_sw2hw_cq(__u32 cqn, __u32 * inprm, __u32 inprm_sz);
38
+static int cmd_hw2sw_cq(__u32 cqn);
39
+static int cmd_rst2init_qpee(__u32 qpn, __u32 * inprm, __u32 inprm_sz);
40
+static int cmd_init2rtr_qpee(__u32 qpn, __u32 * inprm, __u32 inprm_sz);
41
+static int cmd_rtr2rts_qpee(__u32 qpn, __u32 * inprm, __u32 inprm_sz);
42
+static int cmd_2rst_qpee(__u32 qpn);
43
+static int cmd_2err_qpee(__u32 qpn);
44
+static int cmd_post_doorbell(void *inprm, __u32 offset);
45
+static int cmd_mad_ifc(void *inprm, struct ib_mad_st *mad, __u8 port);
46
+static int cmd_write_mgm( /*struct mg_member_layout_st */ void *mg,
47
+			 __u16 index);
48
+static int cmd_mgid_hash(__u8 * gid, __u16 * mgid_hash_p);
49
+
50
+#endif				/* __cmdif_h_ */

+ 564
- 0
src/drivers/net/mlx_ipoib/cmdif_comm.c Datei anzeigen

@@ -0,0 +1,564 @@
1
+/*
2
+  This software is available to you under a choice of one of two
3
+  licenses.  You may choose to be licensed under the terms of the GNU
4
+  General Public License (GPL) Version 2, available at
5
+  <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6
+  license, available in the LICENSE.TXT file accompanying this
7
+  software.  These details are also available at
8
+  <http://openib.org/license.html>.
9
+
10
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
+  SOFTWARE.
18
+
19
+  Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
20
+*/
21
+
22
+#include "cmdif.h"
23
+#include "cmdif_comm.h"
24
+#include "cmdif_priv.h"
25
+
26
+static int cmdif_is_free(int *is_free)
27
+{
28
+	int rc;
29
+	__u32 result;
30
+
31
+	rc = gw_read_cr(HCR_OFFSET_GO, &result);
32
+	if (rc) {
33
+		eprintf("");
34
+		return rc;
35
+	}
36
+	*is_free = (result & 0x800000) == 0;
37
+
38
+	return 0;
39
+}
40
+
41
+static void edit_hcr(command_fields_t * cmd_prms, __u32 * buf)
42
+{
43
+	unsigned int i;
44
+
45
+	switch (cmd_prms->in_trans) {
46
+	case TRANS_NA:
47
+		/* note! since these are zeroes I do not bother to deal with endianess */
48
+		buf[0] = 0;
49
+		buf[1] = 0;
50
+		break;
51
+
52
+	case TRANS_IMMEDIATE:
53
+		buf[0] = cmd_prms->in_param[0];
54
+		buf[1] = cmd_prms->in_param[1];
55
+		break;
56
+
57
+	case TRANS_MAILBOX:
58
+		buf[0] = 0;
59
+		buf[1] = virt_to_bus(cmd_prms->in_param);
60
+
61
+		for (i = 0; i < cmd_prms->in_param_size; i += 4)
62
+			cmd_prms->in_param[i >> 2] =
63
+			    cpu_to_be32(cmd_prms->in_param[i >> 2]);
64
+		break;
65
+	}
66
+
67
+	buf[2] = cmd_prms->input_modifier;
68
+
69
+	switch (cmd_prms->out_trans) {
70
+	case TRANS_NA:
71
+		/* note! since these are zeroes I do not bother to deal with endianess */
72
+		buf[3] = 0;
73
+		buf[4] = 0;
74
+		break;
75
+
76
+	case TRANS_IMMEDIATE:
77
+		break;
78
+	case TRANS_MAILBOX:
79
+		buf[3] = 0;
80
+		buf[4] = virt_to_bus(cmd_prms->out_param);
81
+		break;
82
+	}
83
+
84
+	buf[5] = 0;		/* token is always 0 */
85
+	buf[6] = cmd_prms->opcode |	/* opcode */
86
+	    0x800000 |		/* go bit */
87
+	    ((cmd_prms->opcode_modifier & 0xf) << 12);	/* opcode modifier 
88
+*/ }
89
+
90
+static int wait_cmdif_free(void)
91
+{
92
+	int ret, is_free;
93
+	unsigned int i, relax_time = 1, max_time = 5000;
94
+
95
+	/* wait until go bit is free */
96
+	for (i = 0; i < max_time; i += relax_time) {
97
+		ret = cmdif_is_free(&is_free);
98
+		if (ret)
99
+			return ret;
100
+		if (is_free)
101
+			break;
102
+		mdelay(relax_time);
103
+	}
104
+	if (i >= max_time)
105
+		return -1;
106
+	return 0;
107
+}
108
+
109
+static XHH_cmd_status_t cmd_invoke(command_fields_t * cmd_prms)
110
+{
111
+	int ret, is_free, i;
112
+	__u32 hcr[7], data;
113
+	__u8 status;
114
+
115
+	/* check if go bit is free */
116
+	ret = cmdif_is_free(&is_free);
117
+	if (ret) {
118
+		eprintf("");
119
+		return -1;
120
+	}
121
+
122
+	__asm__ __volatile__("":::"memory");
123
+	/* it must be free */
124
+	if (!is_free) {
125
+		eprintf("");
126
+		return -1;
127
+	}
128
+	__asm__ __volatile__("":::"memory");
129
+	edit_hcr(cmd_prms, hcr);
130
+	__asm__ __volatile__("":::"memory");
131
+
132
+	for (i = 0; i < 7; ++i) {
133
+		ret = gw_write_cr(HCR_BASE + i * 4, hcr[i]);
134
+		if (ret) {
135
+			eprintf("");
136
+			return -1;
137
+		}
138
+	}
139
+
140
+	__asm__ __volatile__("":::"memory");
141
+	/* wait for completion */
142
+	ret = wait_cmdif_free();
143
+	if (ret) {
144
+		eprintf("");
145
+		return -1;
146
+	}
147
+
148
+	__asm__ __volatile__("":::"memory");
149
+	ret = gw_read_cr(HCR_OFFSET_STATUS, &data);
150
+	if (ret) {
151
+		eprintf("");
152
+		return -1;
153
+	}
154
+
155
+	status = data >> 24;
156
+
157
+	if (status) {
158
+		tprintf("status=0x%x", status);
159
+		return status;
160
+	}
161
+
162
+	if (cmd_prms->out_trans == TRANS_MAILBOX)
163
+		be_to_cpu_buf(cmd_prms->out_param, cmd_prms->out_param_size);
164
+	else if (cmd_prms->out_trans == TRANS_IMMEDIATE) {
165
+		if (gw_read_cr(HCR_OFFSET_OUTPRM_H, &cmd_prms->out_param[0]))
166
+			return -1;
167
+		if (gw_read_cr(HCR_OFFSET_OUTPRM_L, &cmd_prms->out_param[1]))
168
+			return -1;
169
+	}
170
+
171
+	return 0;
172
+}
173
+
174
+/*************************************************
175
+					commands
176
+*************************************************/
177
+
178
+/*
179
+ *  cmd_close_hca
180
+ */
181
+static int cmd_close_hca(int panic)
182
+{
183
+	int rc;
184
+	command_fields_t cmd_desc;
185
+
186
+	memset(&cmd_desc, 0, sizeof cmd_desc);
187
+	cmd_desc.opcode = XDEV_CMD_CLOSE_HCA;
188
+	cmd_desc.opcode_modifier= panic;
189
+	rc = cmd_invoke(&cmd_desc);
190
+
191
+	return rc;
192
+}
193
+
194
+/*
195
+ *  cmd_init_hca
196
+ */
197
+static int cmd_init_hca(__u32 * inprm, __u32 in_prm_size)
198
+{
199
+	int rc;
200
+
201
+	command_fields_t cmd_desc;
202
+
203
+	memset(&cmd_desc, 0, sizeof cmd_desc);
204
+	cmd_desc.in_trans = TRANS_MAILBOX;
205
+	cmd_desc.opcode = XDEV_CMD_INIT_HCA;
206
+	cmd_desc.in_param = inprm;
207
+	cmd_desc.in_param_size = in_prm_size;
208
+
209
+	rc = cmd_invoke(&cmd_desc);
210
+
211
+	return rc;
212
+}
213
+
214
+/*
215
+ *  cmd_sw2hw_eq
216
+ */
217
+static int cmd_sw2hw_eq(__u32 inprm_sz)
218
+{
219
+	int rc;
220
+	command_fields_t cmd_desc;
221
+	void *inprm;
222
+
223
+	memset(&cmd_desc, 0, sizeof cmd_desc);
224
+
225
+	inprm = get_inprm_buf();
226
+	cmd_desc.in_trans = TRANS_MAILBOX;
227
+	cmd_desc.opcode = XDEV_CMD_SW2HW_EQ;
228
+	cmd_desc.in_param = inprm;
229
+	cmd_desc.in_param_size = inprm_sz;
230
+
231
+	rc = cmd_invoke(&cmd_desc);
232
+
233
+	return rc;
234
+}
235
+
236
+/*
237
+ *  cmd_hw2sw_eq
238
+ */
239
+static int cmd_hw2sw_eq(__u8 eqn)
240
+{
241
+	int rc;
242
+	command_fields_t cmd_desc;
243
+	void *outprm;
244
+
245
+	memset(&cmd_desc, 0, sizeof cmd_desc);
246
+
247
+	outprm = get_outprm_buf();
248
+	cmd_desc.opcode = XDEV_CMD_HW2SW_EQ;
249
+	cmd_desc.input_modifier = eqn;
250
+	cmd_desc.out_trans = TRANS_MAILBOX;
251
+	cmd_desc.out_param = outprm;
252
+	cmd_desc.out_param_size = 0x40;
253
+	rc = cmd_invoke(&cmd_desc);
254
+
255
+	return rc;
256
+}
257
+
258
+/*
259
+ *  cmd_map_eq
260
+ */
261
+static int cmd_map_eq(__u8 eqn, __u32 mask, int map)
262
+{
263
+	int rc;
264
+	command_fields_t cmd_desc;
265
+	__u32 *inprm;
266
+
267
+	memset(&cmd_desc, 0, sizeof cmd_desc);
268
+
269
+	inprm = get_inprm_buf();
270
+
271
+	inprm[1] = mask;
272
+	inprm[0] = 0;
273
+
274
+	cmd_desc.opcode = XDEV_CMD_MAP_EQ;
275
+	cmd_desc.in_trans = TRANS_IMMEDIATE;
276
+	cmd_desc.in_param = inprm;
277
+	cmd_desc.input_modifier = ((map ? 0 : 1) << 31) | eqn;
278
+
279
+	rc = cmd_invoke(&cmd_desc);
280
+
281
+	return rc;
282
+}
283
+
284
+/*
285
+ *  cmd_sw2hw_mpt
286
+ */
287
+static int cmd_sw2hw_mpt(__u32 * lkey, __u32 in_key, __u32 * inprm,
288
+			 __u32 inprm_sz)
289
+{
290
+	int rc;
291
+	command_fields_t cmd_desc;
292
+
293
+	memset(&cmd_desc, 0, sizeof cmd_desc);
294
+	cmd_desc.in_trans = TRANS_MAILBOX;
295
+	cmd_desc.opcode = XDEV_CMD_SW2HW_MPT;
296
+	cmd_desc.input_modifier = in_key & MKEY_IDX_MASK;	/* only one MR for the whole driver */
297
+	cmd_desc.in_param = inprm;
298
+	cmd_desc.in_param_size = inprm_sz;
299
+
300
+	rc = cmd_invoke(&cmd_desc);
301
+	if (!rc)
302
+		*lkey = in_key;
303
+
304
+	return rc;
305
+}
306
+
307
+/*
308
+ *  cmd_hw2sw_mpt
309
+ */
310
+static int cmd_hw2sw_mpt(__u32 key)
311
+{
312
+	int rc;
313
+	command_fields_t cmd_desc;
314
+
315
+	memset(&cmd_desc, 0, sizeof cmd_desc);
316
+	cmd_desc.opcode = XDEV_CMD_HW2SW_MPT;
317
+	cmd_desc.input_modifier = key & MKEY_IDX_MASK;
318
+	cmd_desc.opcode_modifier = 1;
319
+
320
+	rc = cmd_invoke(&cmd_desc);
321
+
322
+	return rc;
323
+}
324
+
325
+/*
326
+ *  cmd_init_ib
327
+ */
328
+static int cmd_init_ib(__u32 port, __u32 * inprm, __u32 inprm_sz)
329
+{
330
+	int rc;
331
+	command_fields_t cmd_desc;
332
+
333
+	memset(&cmd_desc, 0, sizeof cmd_desc);
334
+	cmd_desc.opcode = XDEV_CMD_INIT_IB;
335
+	cmd_desc.input_modifier = port;
336
+	cmd_desc.in_trans = TRANS_MAILBOX;
337
+	cmd_desc.in_param = inprm;
338
+	cmd_desc.in_param_size = inprm_sz;
339
+
340
+	rc = cmd_invoke(&cmd_desc);
341
+
342
+	return rc;
343
+}
344
+
345
+/*
346
+ *  cmd_close_ib
347
+ */
348
+static int cmd_close_ib(__u32 port)
349
+{
350
+	int rc;
351
+	command_fields_t cmd_desc;
352
+
353
+	memset(&cmd_desc, 0, sizeof cmd_desc);
354
+	cmd_desc.opcode = XDEV_CMD_CLOSE_IB;
355
+	cmd_desc.input_modifier = port;
356
+
357
+	rc = cmd_invoke(&cmd_desc);
358
+
359
+	return rc;
360
+}
361
+
362
+/*
363
+ *  cmd_sw2hw_cq
364
+ */
365
+static int cmd_sw2hw_cq(__u32 cqn, __u32 * inprm, __u32 inprm_sz)
366
+{
367
+	int rc;
368
+	command_fields_t cmd_desc;
369
+
370
+	memset(&cmd_desc, 0, sizeof cmd_desc);
371
+	cmd_desc.opcode = XDEV_CMD_SW2HW_CQ;
372
+	cmd_desc.in_trans = TRANS_MAILBOX;
373
+	cmd_desc.in_param = inprm;
374
+	cmd_desc.in_param_size = inprm_sz;
375
+	cmd_desc.input_modifier = cqn;
376
+
377
+	rc = cmd_invoke(&cmd_desc);
378
+
379
+	return rc;
380
+}
381
+
382
+/*
383
+ *  cmd_hw2sw_cq
384
+ */
385
+static int cmd_hw2sw_cq(__u32 cqn)
386
+{
387
+	int rc;
388
+	command_fields_t cmd_desc;
389
+
390
+	memset(&cmd_desc, 0, sizeof cmd_desc);
391
+	cmd_desc.opcode = XDEV_CMD_HW2SW_CQ;
392
+	cmd_desc.input_modifier = cqn;
393
+	cmd_desc.out_trans = TRANS_MAILBOX;
394
+	cmd_desc.out_param = get_outprm_buf();
395
+
396
+	rc = cmd_invoke(&cmd_desc);
397
+
398
+	return rc;
399
+}
400
+
401
+/*
402
+ *  cmd_rst2init_qpee
403
+ */
404
+static int cmd_rst2init_qpee(__u32 qpn, __u32 * inprm, __u32 inprm_sz)
405
+{
406
+	int rc;
407
+	command_fields_t cmd_desc;
408
+
409
+	memset(&cmd_desc, 0, sizeof cmd_desc);
410
+	cmd_desc.opcode = XDEV_CMD_RST2INIT_QPEE;
411
+	cmd_desc.in_trans = TRANS_MAILBOX;
412
+	cmd_desc.in_param = inprm;
413
+	cmd_desc.in_param_size = inprm_sz;
414
+	cmd_desc.input_modifier = qpn;
415
+
416
+	rc = cmd_invoke(&cmd_desc);
417
+
418
+	return rc;
419
+}
420
+
421
+/*
422
+ *  cmd_init2rtr_qpee
423
+ */
424
+static int cmd_init2rtr_qpee(__u32 qpn, __u32 * inprm, __u32 inprm_sz)
425
+{
426
+	int rc;
427
+	command_fields_t cmd_desc;
428
+
429
+	memset(&cmd_desc, 0, sizeof cmd_desc);
430
+	cmd_desc.opcode = XDEV_CMD_INIT2RTR_QPEE;
431
+	cmd_desc.in_trans = TRANS_MAILBOX;
432
+	cmd_desc.in_param = inprm;
433
+	cmd_desc.in_param_size = inprm_sz;
434
+	cmd_desc.input_modifier = qpn;;
435
+
436
+	rc = cmd_invoke(&cmd_desc);
437
+
438
+	return rc;
439
+}
440
+
441
+/*
442
+ *  cmd_rtr2rts_qpee
443
+ */
444
+static int cmd_rtr2rts_qpee(__u32 qpn, __u32 * inprm, __u32 inprm_sz)
445
+{
446
+	int rc;
447
+	command_fields_t cmd_desc;
448
+
449
+	memset(&cmd_desc, 0, sizeof cmd_desc);
450
+	cmd_desc.opcode = XDEV_CMD_RTR2RTS_QPEE;
451
+	cmd_desc.in_trans = TRANS_MAILBOX;
452
+	cmd_desc.in_param = inprm;
453
+	cmd_desc.in_param_size = inprm_sz;
454
+	cmd_desc.input_modifier = qpn;
455
+
456
+	rc = cmd_invoke(&cmd_desc);
457
+
458
+	return rc;
459
+}
460
+
461
+/*
462
+ *  cmd_2rst_qpee
463
+ */
464
+static int cmd_2rst_qpee(__u32 qpn)
465
+{
466
+	int rc;
467
+	command_fields_t cmd_desc;
468
+
469
+	memset(&cmd_desc, 0, sizeof cmd_desc);
470
+	cmd_desc.opcode = XDEV_CMD_ERR2RST_QPEE;
471
+	cmd_desc.opcode_modifier = 0;
472
+	cmd_desc.input_modifier = qpn;
473
+	cmd_desc.out_trans = TRANS_MAILBOX;
474
+	cmd_desc.out_param = get_outprm_buf();
475
+
476
+	rc = cmd_invoke(&cmd_desc);
477
+
478
+	return rc;
479
+}
480
+
481
+/*
482
+ *  cmd_2err_qpee
483
+ */
484
+static int cmd_2err_qpee(__u32 qpn)
485
+{
486
+	int rc;
487
+	command_fields_t cmd_desc;
488
+
489
+	memset(&cmd_desc, 0, sizeof cmd_desc);
490
+	cmd_desc.opcode = XDEV_CMD_2ERR_QPEE;
491
+	cmd_desc.input_modifier = qpn;
492
+
493
+	rc = cmd_invoke(&cmd_desc);
494
+
495
+	return rc;
496
+}
497
+
498
+/*
499
+ *  cmd_post_doorbell
500
+ */
501
+static int cmd_post_doorbell(void *inprm, __u32 offset)
502
+{
503
+	int rc;
504
+	command_fields_t cmd_desc;
505
+
506
+	memset(&cmd_desc, 0, sizeof cmd_desc);
507
+	cmd_desc.opcode = XDEV_CMD_POST_DOORBELL;
508
+	cmd_desc.in_trans = TRANS_IMMEDIATE;
509
+	cmd_desc.in_param = inprm;
510
+	cmd_desc.input_modifier = offset;
511
+	if (0) {
512
+		rc = cmd_invoke(&cmd_desc);
513
+	} else {
514
+		dev_post_dbell(inprm, offset);
515
+		rc = 0;
516
+	}
517
+
518
+	return rc;
519
+}
520
+
521
+static int cmd_mad_ifc(void *inprm, struct ib_mad_st *mad, __u8 port)
522
+{
523
+	int rc;
524
+	command_fields_t cmd_desc;
525
+
526
+	memset(&cmd_desc, 0, sizeof cmd_desc);
527
+	cmd_desc.opcode = XDEV_CMD_MAD_IFC;
528
+	cmd_desc.opcode_modifier = 1;	/* no mkey/bkey validation */
529
+	cmd_desc.input_modifier = port;
530
+	cmd_desc.in_trans = TRANS_MAILBOX;
531
+	cmd_desc.in_param_size = 256;
532
+	cmd_desc.in_param = (__u32 *) inprm;
533
+	cmd_desc.out_trans = TRANS_MAILBOX;
534
+	cmd_desc.out_param = (__u32 *) mad;
535
+	cmd_desc.out_param_size = 256;
536
+	rc = cmd_invoke(&cmd_desc);
537
+
538
+	return rc;
539
+}
540
+
541
+static int cmd_mgid_hash(__u8 * gid, __u16 * mgid_hash_p)
542
+{
543
+	int rc;
544
+	command_fields_t cmd_desc;
545
+	__u16 result[2];
546
+
547
+	memset(&cmd_desc, 0, sizeof cmd_desc);
548
+
549
+	cmd_desc.opcode = XDEV_CMD_MGID_HASH;
550
+	cmd_desc.in_trans = TRANS_MAILBOX;
551
+	cmd_desc.in_param = (__u32 *) gid;
552
+	cmd_desc.in_param_size = 16;
553
+	cmd_desc.out_trans = TRANS_IMMEDIATE;
554
+
555
+	rc = cmd_invoke(&cmd_desc);
556
+	if (!rc) {
557
+		rc = gw_read_cr(HCR_BASE + 16, (__u32 *) result);
558
+		if (!rc) {
559
+			*mgid_hash_p = result[0];
560
+		}
561
+	}
562
+
563
+	return rc;
564
+}

+ 60
- 0
src/drivers/net/mlx_ipoib/cmdif_comm.h Datei anzeigen

@@ -0,0 +1,60 @@
1
+/*
2
+  This software is available to you under a choice of one of two
3
+  licenses.  You may choose to be licensed under the terms of the GNU
4
+  General Public License (GPL) Version 2, available at
5
+  <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6
+  license, available in the LICENSE.TXT file accompanying this
7
+  software.  These details are also available at
8
+  <http://openib.org/license.html>.
9
+
10
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
+  SOFTWARE.
18
+
19
+  Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
20
+*/
21
+
22
+#ifndef __cmdif_comm_h__
23
+#define __cmdif_comm_h__
24
+
25
+  /* initialization and general commands */
26
+#define XDEV_CMD_INIT_HCA			0x7
27
+#define XDEV_CMD_CLOSE_HCA			0x8
28
+#define XDEV_CMD_INIT_IB				0x9
29
+#define XDEV_CMD_CLOSE_IB			0xa
30
+
31
+  /* TPT commands */
32
+#define XDEV_CMD_SW2HW_MPT			0xd
33
+#define	XDEV_CMD_HW2SW_MPT			0xf
34
+
35
+  /* EQ commands */
36
+#define XDEV_CMD_MAP_EQ				0x12
37
+#define XDEV_CMD_SW2HW_EQ			0x13
38
+#define XDEV_CMD_HW2SW_EQ			0x14
39
+
40
+  /* CQ commands */
41
+#define XDEV_CMD_SW2HW_CQ			0x16
42
+#define	XDEV_CMD_HW2SW_CQ			0x17
43
+
44
+  /* QP/EE commands */
45
+#define	XDEV_CMD_RST2INIT_QPEE		0x19
46
+#define XDEV_CMD_INIT2RTR_QPEE		0x1a
47
+#define XDEV_CMD_RTR2RTS_QPEE		0x1b
48
+#define XDEV_CMD_2ERR_QPEE			0x1e
49
+#define XDEV_CMD_ERR2RST_QPEE		0x21
50
+
51
+  /* special QPs and management commands */
52
+#define XDEV_CMD_MAD_IFC				0x24
53
+
54
+  /* multicast commands */
55
+#define XDEV_CMD_READ_MGM			0x25
56
+#define XDEV_CMD_MGID_HASH			0x27
57
+
58
+#define XDEV_CMD_POST_DOORBELL		0x41
59
+
60
+#endif				/* __cmdif_comm_h__ */

+ 193
- 0
src/drivers/net/mlx_ipoib/cmdif_mt23108.c Datei anzeigen

@@ -0,0 +1,193 @@
1
+/*
2
+  This software is available to you under a choice of one of two
3
+  licenses.  You may choose to be licensed under the terms of the GNU
4
+  General Public License (GPL) Version 2, available at
5
+  <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6
+  license, available in the LICENSE.TXT file accompanying this
7
+  software.  These details are also available at
8
+  <http://openib.org/license.html>.
9
+
10
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
+  SOFTWARE.
18
+
19
+  Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
20
+*/
21
+#include "cmdif.h"
22
+#include "cmdif_priv.h"
23
+#include "mt23108.h"
24
+
25
+/*
26
+ *  cmd_sys_en
27
+ */
28
+static int cmd_sys_en(void)
29
+{
30
+	int rc;
31
+	command_fields_t cmd_desc;
32
+
33
+	memset(&cmd_desc, 0, sizeof cmd_desc);
34
+	cmd_desc.opcode = TAVOR_CMD_SYS_EN;
35
+	rc = cmd_invoke(&cmd_desc);
36
+
37
+	return rc;
38
+}
39
+
40
+/*
41
+ *  cmd_sys_dis
42
+ */
43
+static int cmd_sys_dis(void)
44
+{
45
+	int rc;
46
+	command_fields_t cmd_desc;
47
+
48
+	memset(&cmd_desc, 0, sizeof cmd_desc);
49
+	cmd_desc.in_trans = TRANS_NA;
50
+	cmd_desc.out_trans = TRANS_NA;
51
+	cmd_desc.opcode = TAVOR_CMD_SYS_DIS;
52
+	rc = cmd_invoke(&cmd_desc);
53
+
54
+	return rc;
55
+}
56
+
57
+/*
58
+ *  cmd_query_dev_lim
59
+ */
60
+static int cmd_query_dev_lim(struct dev_lim_st *dev_lim_p)
61
+{
62
+	int rc;
63
+	command_fields_t cmd_desc;
64
+
65
+	memset(&cmd_desc, 0, sizeof cmd_desc);
66
+
67
+	cmd_desc.opcode = TAVOR_CMD_QUERY_DEV_LIM;
68
+	cmd_desc.out_trans = TRANS_MAILBOX;
69
+	cmd_desc.out_param = get_outprm_buf();
70
+	cmd_desc.out_param_size = MT_STRUCT_SIZE(tavorprm_query_dev_lim_st);
71
+
72
+	rc = cmd_invoke(&cmd_desc);
73
+	if (!rc) {
74
+		dev_lim_p->log2_rsvd_qps =
75
+		    EX_FLD(cmd_desc.out_param, tavorprm_query_dev_lim_st,
76
+			   log2_rsvd_qps);
77
+		dev_lim_p->qpc_entry_sz =
78
+		    EX_FLD(cmd_desc.out_param, tavorprm_query_dev_lim_st,
79
+			   qpc_entry_sz);
80
+
81
+		dev_lim_p->log2_rsvd_srqs =
82
+		    EX_FLD(cmd_desc.out_param, tavorprm_query_dev_lim_st,
83
+			   log2_rsvd_srqs);
84
+		dev_lim_p->srq_entry_sz =
85
+		    EX_FLD(cmd_desc.out_param, tavorprm_query_dev_lim_st,
86
+			   srq_entry_sz);
87
+
88
+		dev_lim_p->log2_rsvd_ees =
89
+		    EX_FLD(cmd_desc.out_param, tavorprm_query_dev_lim_st,
90
+			   log2_rsvd_ees);
91
+		dev_lim_p->eec_entry_sz =
92
+		    EX_FLD(cmd_desc.out_param, tavorprm_query_dev_lim_st,
93
+			   eec_entry_sz);
94
+
95
+		dev_lim_p->log2_rsvd_cqs =
96
+		    EX_FLD(cmd_desc.out_param, tavorprm_query_dev_lim_st,
97
+			   log2_rsvd_cqs);
98
+		dev_lim_p->cqc_entry_sz =
99
+		    EX_FLD(cmd_desc.out_param, tavorprm_query_dev_lim_st,
100
+			   cqc_entry_sz);
101
+
102
+		dev_lim_p->log2_rsvd_mtts =
103
+		    EX_FLD(cmd_desc.out_param, tavorprm_query_dev_lim_st,
104
+			   log2_rsvd_mtts);
105
+		dev_lim_p->mtt_entry_sz = 64;	/* segment size is set to zero in init_hca */
106
+
107
+		dev_lim_p->log2_rsvd_mrws =
108
+		    EX_FLD(cmd_desc.out_param, tavorprm_query_dev_lim_st,
109
+			   log2_rsvd_mrws);
110
+		dev_lim_p->mpt_entry_sz = MT_STRUCT_SIZE(tavorprm_mpt_st);
111
+
112
+		dev_lim_p->eqc_entry_sz =
113
+		    EX_FLD(cmd_desc.out_param, tavorprm_query_dev_lim_st,
114
+			   eqc_entry_sz);
115
+	}
116
+
117
+	return rc;
118
+}
119
+
120
+/*
121
+ *  cmd_write_mgm
122
+ */
123
+static int cmd_write_mgm(void *mg, __u16 index)
124
+{
125
+	int rc;
126
+	command_fields_t cmd_desc;
127
+
128
+	memset(&cmd_desc, 0, sizeof cmd_desc);
129
+	cmd_desc.opcode = TAVOR_CMD_WRITE_MGM;
130
+	cmd_desc.in_trans = TRANS_MAILBOX;
131
+	cmd_desc.in_param_size = MT_STRUCT_SIZE(tavorprm_mgm_entry_st);
132
+	cmd_desc.in_param = (__u32 *) mg;
133
+	cmd_desc.input_modifier = index;
134
+
135
+	rc = cmd_invoke(&cmd_desc);
136
+
137
+	return rc;
138
+}
139
+
140
+/*
141
+ *  cmd_mod_stat_cfg
142
+ */
143
+static int cmd_mod_stat_cfg(void *cfg)
144
+{
145
+	int rc;
146
+	command_fields_t cmd_desc;
147
+
148
+	memset(&cmd_desc, 0, sizeof cmd_desc);
149
+	cmd_desc.opcode = TAVOR_CMD_MOD_STAT_CFG;
150
+	cmd_desc.in_trans = TRANS_MAILBOX;
151
+	cmd_desc.in_param_size = MT_STRUCT_SIZE(tavorprm_mod_stat_cfg_st);
152
+	cmd_desc.in_param = (__u32 *) cfg;
153
+
154
+	rc = cmd_invoke(&cmd_desc);
155
+
156
+	return rc;
157
+}
158
+
159
+
160
+/*
161
+ *  cmd_query_fw
162
+ */
163
+static int cmd_query_fw(struct query_fw_st *qfw)
164
+{
165
+	int rc;
166
+	command_fields_t cmd_desc;
167
+
168
+	memset(&cmd_desc, 0, sizeof cmd_desc);
169
+
170
+	cmd_desc.opcode = TAVOR_CMD_QUERY_FW;
171
+	cmd_desc.out_trans = TRANS_MAILBOX;
172
+	cmd_desc.out_param = get_outprm_buf();
173
+	cmd_desc.out_param_size = MT_STRUCT_SIZE(tavorprm_query_fw_st);
174
+
175
+	rc = cmd_invoke(&cmd_desc);
176
+	if (!rc) {
177
+		qfw->fw_rev_major =
178
+		    EX_FLD(cmd_desc.out_param, tavorprm_query_fw_st, fw_rev_major);
179
+		qfw->fw_rev_minor =
180
+		    EX_FLD(cmd_desc.out_param, tavorprm_query_fw_st, fw_rev_minor);
181
+		qfw->fw_rev_subminor =
182
+		    EX_FLD(cmd_desc.out_param, tavorprm_query_fw_st, fw_rev_subminor);
183
+
184
+		qfw->error_buf_start_h =
185
+		    EX_FLD(cmd_desc.out_param, tavorprm_query_fw_st, error_buf_start_h);
186
+		qfw->error_buf_start_l =
187
+		    EX_FLD(cmd_desc.out_param, tavorprm_query_fw_st, error_buf_start_l);
188
+		qfw->error_buf_size =
189
+		    EX_FLD(cmd_desc.out_param, tavorprm_query_fw_st, error_buf_size);
190
+	}
191
+
192
+	return rc;
193
+}

+ 457
- 0
src/drivers/net/mlx_ipoib/cmdif_mt25218.c Datei anzeigen

@@ -0,0 +1,457 @@
1
+/*
2
+  This software is available to you under a choice of one of two
3
+  licenses.  You may choose to be licensed under the terms of the GNU
4
+  General Public License (GPL) Version 2, available at
5
+  <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6
+  license, available in the LICENSE.TXT file accompanying this
7
+  software.  These details are also available at
8
+  <http://openib.org/license.html>.
9
+
10
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
+  SOFTWARE.
18
+
19
+  Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
20
+*/
21
+#include "cmdif.h"
22
+#include "cmdif_priv.h"
23
+#include "mt25218.h"
24
+
25
+/*
26
+ *  cmd_sys_dis
27
+ */
28
+static int cmd_sys_dis(void)
29
+{
30
+	return 0;
31
+}
32
+
33
+/*
34
+ *  cmd_write_mgm
35
+ */
36
+static int cmd_write_mgm(void *mg, __u16 index)
37
+{
38
+	int rc;
39
+	command_fields_t cmd_desc;
40
+
41
+	memset(&cmd_desc, 0, sizeof cmd_desc);
42
+	cmd_desc.opcode = MEMFREE_CMD_WRITE_MGM;
43
+	cmd_desc.in_trans = TRANS_MAILBOX;
44
+	cmd_desc.in_param_size = MT_STRUCT_SIZE(arbelprm_mgm_entry_st);
45
+	cmd_desc.in_param = (__u32 *) mg;
46
+	cmd_desc.input_modifier = index;
47
+
48
+	rc = cmd_invoke(&cmd_desc);
49
+
50
+	return rc;
51
+}
52
+
53
+/*
54
+ *  cmd_mod_stat_cfg
55
+ */
56
+static int cmd_mod_stat_cfg(void)
57
+{
58
+	int rc;
59
+	command_fields_t cmd_desc;
60
+
61
+	memset(&cmd_desc, 0, sizeof cmd_desc);
62
+	cmd_desc.opcode = MEMFREE_CMD_MOD_STAT_CFG;
63
+	cmd_desc.in_trans = TRANS_MAILBOX;
64
+	cmd_desc.in_param_size = MT_STRUCT_SIZE(arbelprm_mod_stat_cfg_st);
65
+	cmd_desc.in_param = get_inprm_buf();
66
+	memset(cmd_desc.in_param, 0, cmd_desc.in_param_size);
67
+
68
+	rc = cmd_invoke(&cmd_desc);
69
+
70
+	return rc;
71
+}
72
+
73
+/*
74
+ *  cmd_query_fw
75
+ */
76
+static int cmd_query_fw(struct query_fw_st *qfw)
77
+{
78
+	int rc;
79
+	command_fields_t cmd_desc;
80
+
81
+	memset(&cmd_desc, 0, sizeof cmd_desc);
82
+
83
+	cmd_desc.opcode = MEMFREE_CMD_QUERY_FW;
84
+	cmd_desc.out_trans = TRANS_MAILBOX;
85
+	cmd_desc.out_param = get_outprm_buf();
86
+	cmd_desc.out_param_size = MT_STRUCT_SIZE(arbelprm_query_fw_st);
87
+
88
+	rc = cmd_invoke(&cmd_desc);
89
+	if (!rc) {
90
+		qfw->fw_rev_major =
91
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st, fw_rev_major);
92
+		qfw->fw_rev_minor =
93
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st, fw_rev_minor);
94
+		qfw->fw_rev_subminor =
95
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st, fw_rev_subminor);
96
+
97
+		qfw->error_buf_start_h =
98
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st, error_buf_start_h);
99
+		qfw->error_buf_start_l =
100
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st, error_buf_start_l);
101
+		qfw->error_buf_size =
102
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st, error_buf_size);
103
+
104
+		qfw->fw_pages =
105
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st, fw_pages);
106
+		qfw->eq_ci_table.addr_h =
107
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st,
108
+			   eq_set_ci_base_addr_h);
109
+		qfw->eq_ci_table.addr_l =
110
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st,
111
+			   eq_set_ci_base_addr_l);
112
+		qfw->clear_int_addr.addr_h =
113
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st,
114
+			   clr_int_base_addr_h);
115
+		qfw->clear_int_addr.addr_l =
116
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st,
117
+			   clr_int_base_addr_l);
118
+	}
119
+
120
+	return rc;
121
+}
122
+
123
+/*
124
+ *  cmd_query_adapter
125
+ */
126
+static int cmd_query_adapter(struct query_adapter_st *qa)
127
+{
128
+	int rc;
129
+	command_fields_t cmd_desc;
130
+
131
+	memset(&cmd_desc, 0, sizeof cmd_desc);
132
+
133
+	cmd_desc.opcode = MEMFREE_CMD_QUERY_ADAPTER;
134
+	cmd_desc.out_trans = TRANS_MAILBOX;
135
+	cmd_desc.out_param = get_outprm_buf();
136
+	cmd_desc.out_param_size = MT_STRUCT_SIZE(arbelprm_query_adapter_st);
137
+
138
+	rc = cmd_invoke(&cmd_desc);
139
+	if (!rc) {
140
+		qa->intapin =
141
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_adapter_st,
142
+			   intapin);
143
+	}
144
+
145
+	return rc;
146
+}
147
+
148
+/*
149
+ *  cmd_enable_lam
150
+ */
151
+static int cmd_enable_lam(void)
152
+{
153
+	int rc;
154
+	command_fields_t cmd_desc;
155
+
156
+	memset(&cmd_desc, 0, sizeof cmd_desc);
157
+
158
+	cmd_desc.opcode = MEMFREE_CMD_ENABLE_LAM;
159
+	cmd_desc.opcode_modifier = 1;	/* zero locally attached memory */
160
+	cmd_desc.input_modifier = 0;	/* disable fast refresh */
161
+	cmd_desc.out_trans = TRANS_MAILBOX;
162
+	cmd_desc.out_param = get_outprm_buf();
163
+	cmd_desc.out_param_size = MT_STRUCT_SIZE(arbelprm_enable_lam_st);
164
+
165
+	rc = cmd_invoke(&cmd_desc);
166
+	if (rc) {
167
+	}
168
+
169
+	return rc;
170
+}
171
+
172
+/*
173
+ *  cmd_map_fa
174
+ */
175
+static int cmd_map_fa(struct map_icm_st *map_fa_p)
176
+{
177
+	int rc;
178
+	command_fields_t cmd_desc;
179
+	unsigned int in_param_size, i;
180
+	unsigned long off;
181
+
182
+	if (map_fa_p->num_vpm > MAX_VPM_PER_CALL) {
183
+		return -1;
184
+	}
185
+
186
+	memset(&cmd_desc, 0, sizeof cmd_desc);
187
+
188
+	cmd_desc.opcode = MEMFREE_CMD_MAP_FA;
189
+	cmd_desc.input_modifier = map_fa_p->num_vpm;
190
+	cmd_desc.in_trans = TRANS_MAILBOX;
191
+	cmd_desc.in_param = get_inprm_buf();
192
+	in_param_size =
193
+	    MT_STRUCT_SIZE(arbelprm_virtual_physical_mapping_st) *
194
+	    map_fa_p->num_vpm;
195
+	cmd_desc.in_param_size = in_param_size;
196
+	memset(cmd_desc.in_param, 0, in_param_size);
197
+
198
+	for (i = 0; i < map_fa_p->num_vpm; ++i) {
199
+		off = (unsigned long)(cmd_desc.in_param) +
200
+		    MT_STRUCT_SIZE(arbelprm_virtual_physical_mapping_st) * i;
201
+		INS_FLD(map_fa_p->vpm_arr[i].va_h, off,
202
+			arbelprm_virtual_physical_mapping_st, va_h);
203
+		INS_FLD(map_fa_p->vpm_arr[i].va_l >> 12, off,
204
+			arbelprm_virtual_physical_mapping_st, va_l);
205
+		INS_FLD(map_fa_p->vpm_arr[i].pa_h, off,
206
+			arbelprm_virtual_physical_mapping_st, pa_h);
207
+		INS_FLD(map_fa_p->vpm_arr[i].pa_l >> 12, off,
208
+			arbelprm_virtual_physical_mapping_st, pa_l);
209
+		INS_FLD(map_fa_p->vpm_arr[i].log2_size, off,
210
+			arbelprm_virtual_physical_mapping_st, log2size);
211
+	}
212
+
213
+	rc = cmd_invoke(&cmd_desc);
214
+
215
+	return rc;
216
+}
217
+
218
+/*
219
+ *  cmd_unmap_fa
220
+ */
221
+static int cmd_unmap_fa(void)
222
+{
223
+	int rc;
224
+	command_fields_t cmd_desc;
225
+
226
+	memset(&cmd_desc, 0, sizeof cmd_desc);
227
+
228
+	cmd_desc.opcode = MEMFREE_CMD_UNMAP_FA;
229
+
230
+	rc = cmd_invoke(&cmd_desc);
231
+
232
+	return rc;
233
+}
234
+
235
+/*
236
+ *  cmd_run_fw
237
+ */
238
+static int cmd_run_fw(void)
239
+{
240
+	int rc;
241
+	command_fields_t cmd_desc;
242
+
243
+	memset(&cmd_desc, 0, sizeof cmd_desc);
244
+
245
+	cmd_desc.opcode = MEMFREE_CMD_RUN_FW;
246
+	rc = cmd_invoke(&cmd_desc);
247
+
248
+	return rc;
249
+}
250
+
251
+/*
252
+ *  cmd_set_icm_size
253
+ */
254
+static int cmd_set_icm_size(__u32 icm_size, __u32 * aux_pages_p)
255
+{
256
+	int rc;
257
+	command_fields_t cmd_desc;
258
+	__u32 iprm[2], oprm[2];
259
+
260
+	memset(&cmd_desc, 0, sizeof cmd_desc);
261
+
262
+	cmd_desc.opcode = MEMFREE_CMD_SET_ICM_SIZE;
263
+
264
+	iprm[1] = icm_size;
265
+	iprm[0] = 0;
266
+	cmd_desc.in_trans = TRANS_IMMEDIATE;
267
+	cmd_desc.in_param = iprm;
268
+	cmd_desc.out_trans = TRANS_IMMEDIATE;
269
+	cmd_desc.out_param = oprm;
270
+	rc = cmd_invoke(&cmd_desc);
271
+	if (!rc) {
272
+		if (oprm[0]) {
273
+			/* too many pages required */
274
+			return -1;
275
+		}
276
+		*aux_pages_p = oprm[1];
277
+	}
278
+
279
+	return rc;
280
+}
281
+
282
+/*
283
+ *  cmd_map_icm_aux
284
+ */
285
+static int cmd_map_icm_aux(struct map_icm_st *map_icm_aux_p)
286
+{
287
+	int rc;
288
+	command_fields_t cmd_desc;
289
+	unsigned int in_param_size, i;
290
+	unsigned long off;
291
+
292
+	if (map_icm_aux_p->num_vpm > MAX_VPM_PER_CALL) {
293
+		return -1;
294
+	}
295
+
296
+	memset(&cmd_desc, 0, sizeof cmd_desc);
297
+
298
+	cmd_desc.opcode = MEMFREE_CMD_MAP_ICM_AUX;
299
+	cmd_desc.input_modifier = map_icm_aux_p->num_vpm;
300
+	cmd_desc.in_trans = TRANS_MAILBOX;
301
+	cmd_desc.in_param = get_inprm_buf();
302
+	in_param_size =
303
+	    MT_STRUCT_SIZE(arbelprm_virtual_physical_mapping_st) *
304
+	    map_icm_aux_p->num_vpm;
305
+	cmd_desc.in_param_size = in_param_size;
306
+	memset(cmd_desc.in_param, 0, in_param_size);
307
+
308
+	for (i = 0; i < map_icm_aux_p->num_vpm; ++i) {
309
+		off = (unsigned long)(cmd_desc.in_param) +
310
+		    MT_STRUCT_SIZE(arbelprm_virtual_physical_mapping_st) * i;
311
+		INS_FLD(map_icm_aux_p->vpm_arr[i].va_h, off,
312
+			arbelprm_virtual_physical_mapping_st, va_h);
313
+		INS_FLD(map_icm_aux_p->vpm_arr[i].va_l >> 12, off,
314
+			arbelprm_virtual_physical_mapping_st, va_l);
315
+		INS_FLD(map_icm_aux_p->vpm_arr[i].pa_h, off,
316
+			arbelprm_virtual_physical_mapping_st, pa_h);
317
+		INS_FLD(map_icm_aux_p->vpm_arr[i].pa_l >> 12, off,
318
+			arbelprm_virtual_physical_mapping_st, pa_l);
319
+		INS_FLD(map_icm_aux_p->vpm_arr[i].log2_size, off,
320
+			arbelprm_virtual_physical_mapping_st, log2size);
321
+	}
322
+
323
+	rc = cmd_invoke(&cmd_desc);
324
+
325
+	return rc;
326
+}
327
+
328
+/*
329
+ *  cmd_map_icm
330
+ */
331
+static int cmd_map_icm(struct map_icm_st *map_icm_p)
332
+{
333
+	int rc;
334
+	command_fields_t cmd_desc;
335
+	unsigned int in_param_size, i;
336
+	unsigned long off;
337
+
338
+	if (map_icm_p->num_vpm > MAX_VPM_PER_CALL) {
339
+		return -1;
340
+	}
341
+
342
+	memset(&cmd_desc, 0, sizeof cmd_desc);
343
+
344
+	cmd_desc.opcode = MEMFREE_CMD_MAP_ICM;
345
+	cmd_desc.input_modifier = map_icm_p->num_vpm;
346
+	cmd_desc.in_trans = TRANS_MAILBOX;
347
+	cmd_desc.in_param = get_inprm_buf();
348
+	in_param_size =
349
+	    MT_STRUCT_SIZE(arbelprm_virtual_physical_mapping_st) *
350
+	    map_icm_p->num_vpm;
351
+	cmd_desc.in_param_size = in_param_size;
352
+	memset(cmd_desc.in_param, 0, in_param_size);
353
+
354
+	for (i = 0; i < map_icm_p->num_vpm; ++i) {
355
+		off = (unsigned long)(cmd_desc.in_param) +
356
+		    MT_STRUCT_SIZE(arbelprm_virtual_physical_mapping_st) * i;
357
+		INS_FLD(map_icm_p->vpm_arr[i].va_h, off,
358
+			arbelprm_virtual_physical_mapping_st, va_h);
359
+		INS_FLD(map_icm_p->vpm_arr[i].va_l >> 12, off,
360
+			arbelprm_virtual_physical_mapping_st, va_l);
361
+		INS_FLD(map_icm_p->vpm_arr[i].pa_h, off,
362
+			arbelprm_virtual_physical_mapping_st, pa_h);
363
+		INS_FLD(map_icm_p->vpm_arr[i].pa_l >> 12, off,
364
+			arbelprm_virtual_physical_mapping_st, pa_l);
365
+		INS_FLD(map_icm_p->vpm_arr[i].log2_size, off,
366
+			arbelprm_virtual_physical_mapping_st, log2size);
367
+	}
368
+
369
+	rc = cmd_invoke(&cmd_desc);
370
+
371
+	return rc;
372
+}
373
+
374
+/*
375
+ *  cmd_query_dev_lim
376
+ */
377
+static int cmd_query_dev_lim(struct dev_lim_st *dev_lim_p)
378
+{
379
+	int rc;
380
+	command_fields_t cmd_desc;
381
+
382
+	memset(&cmd_desc, 0, sizeof cmd_desc);
383
+
384
+	cmd_desc.opcode = MEMFREE_CMD_QUERY_DEV_LIM;
385
+	cmd_desc.out_trans = TRANS_MAILBOX;
386
+	cmd_desc.out_param = get_outprm_buf();
387
+	cmd_desc.out_param_size = MT_STRUCT_SIZE(arbelprm_query_dev_lim_st);
388
+
389
+	rc = cmd_invoke(&cmd_desc);
390
+	if (!rc) {
391
+		dev_lim_p->log2_rsvd_qps =
392
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
393
+			   log2_rsvd_qps);
394
+		dev_lim_p->qpc_entry_sz =
395
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
396
+			   qpc_entry_sz);
397
+
398
+		dev_lim_p->log2_rsvd_srqs =
399
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
400
+			   log2_rsvd_srqs);
401
+		dev_lim_p->srq_entry_sz =
402
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
403
+			   srq_entry_sz);
404
+
405
+		dev_lim_p->log2_rsvd_ees =
406
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
407
+			   log2_rsvd_ees);
408
+		dev_lim_p->eec_entry_sz =
409
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
410
+			   eec_entry_sz);
411
+
412
+		dev_lim_p->log2_rsvd_cqs =
413
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
414
+			   log2_rsvd_cqs);
415
+		dev_lim_p->cqc_entry_sz =
416
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
417
+			   cqc_entry_sz);
418
+
419
+		dev_lim_p->log2_rsvd_mtts =
420
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
421
+			   log2_rsvd_mtts);
422
+		dev_lim_p->mtt_entry_sz =
423
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
424
+			   mtt_entry_sz);
425
+
426
+		dev_lim_p->log2_rsvd_mrws =
427
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
428
+			   log2_rsvd_mrws);
429
+		dev_lim_p->mpt_entry_sz =
430
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
431
+			   mpt_entry_sz);
432
+
433
+		dev_lim_p->log2_rsvd_rdbs =
434
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
435
+			   log2_rsvd_rdbs);
436
+
437
+		dev_lim_p->eqc_entry_sz =
438
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
439
+			   eqc_entry_sz);
440
+
441
+		dev_lim_p->max_icm_size_l =
442
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
443
+			   max_icm_size_l);
444
+		dev_lim_p->max_icm_size_h =
445
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
446
+			   max_icm_size_h);
447
+
448
+		dev_lim_p->num_rsvd_uars =
449
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
450
+			   num_rsvd_uars);
451
+		dev_lim_p->uar_sz =
452
+		    EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
453
+			   uar_sz);
454
+	}
455
+
456
+	return rc;
457
+}

+ 50
- 0
src/drivers/net/mlx_ipoib/cmdif_priv.h Datei anzeigen

@@ -0,0 +1,50 @@
1
+/*
2
+  This software is available to you under a choice of one of two
3
+  licenses.  You may choose to be licensed under the terms of the GNU
4
+  General Public License (GPL) Version 2, available at
5
+  <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6
+  license, available in the LICENSE.TXT file accompanying this
7
+  software.  These details are also available at
8
+  <http://openib.org/license.html>.
9
+
10
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
+  SOFTWARE.
18
+
19
+  Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
20
+*/
21
+
22
+#ifndef __cmdif_priv__h__
23
+#define __cmdif_priv__h__
24
+
25
+typedef enum {
26
+	TRANS_NA,
27
+	TRANS_IMMEDIATE,
28
+	TRANS_MAILBOX
29
+} trans_type_t;
30
+
31
+typedef struct {
32
+	__u32 *in_param;	/* holds the virtually contigious buffer of the parameter block passed */
33
+	unsigned int in_param_size;
34
+	trans_type_t in_trans;
35
+
36
+	__u32 input_modifier;
37
+
38
+	__u32 *out_param;	/* holds the virtually contigious buffer of the parameter block passed */
39
+	unsigned int out_param_size;
40
+	trans_type_t out_trans;
41
+
42
+	__u32 opcode;
43
+	__u8 opcode_modifier;
44
+} command_fields_t;
45
+
46
+typedef int XHH_cmd_status_t;
47
+
48
+static XHH_cmd_status_t cmd_invoke(command_fields_t * cmd_prms);
49
+
50
+#endif

+ 176
- 0
src/drivers/net/mlx_ipoib/doc/README.boot_over_ib Datei anzeigen

@@ -0,0 +1,176 @@
1
+.Boot over IB over Mellanox HCAs README - Pre-Alpha release
2
+==========================================================
3
+Document #2442, Rev 0.10, December 2005
4
+
5
+
6
+1. General
7
+-----------
8
+This README describes the Boot over IB package which enables booting a Linux 
9
+kernel from a remote server using one of the Mellanox Technologies HCA 
10
+devices. The package is based on Etherboot 5.4.1.
11
+
12
+The package actually implements a network driver for Etherboot. The wire 
13
+protocol is compliant with IP Over IB 
14
+(see http://www.ietf.org/html.charters/ipoib-charter.html for related 
15
+documents).
16
+
17
+Etherboot uses a traditional setup of a DHCP server and a TFTP server to 
18
+perform a remote boot in a similar manner to Ethernet NICs. The binary code is 
19
+exported by the device as an expansion ROM image.
20
+
21
+
22
+2. Supported Devices
23
+---------------------
24
+The following Mellanox Technologies HCA devices are supported:
25
+
26
+	PCI Device ID		Mellanox HCA Device
27
+	----------------------------------------------
28
+	23108			InfiniHost (P/N MT23108)
29
+	25208			InfiniHost III Ex (P/N MT25208) (InfiniHost)
30
+	25218			InfiniHost III Ex (P/N MT25208) (MemFree)
31
+	25204			InfiniHost III Lx (P/N MT25204)
32
+
33
+	
34
+	Note:	For devices with more than one IB port, port 1 is used for 
35
+	communications.
36
+
37
+
38
+3. Compiling
39
+----------------
40
+From the src directory:
41
+Run" make bin/<device>.<ext>
42
+where device can be any of:
43
+	MT23108
44
+	MT25218
45
+	MT25208
46
+	MT25204
47
+	
48
+and ext can be rom, zrom etc. (see Etherbot doumentation for more details)
49
+
50
+4. Directory Structure
51
+-----------------------
52
+All driver files are available under src/drivers/net/mlx_ipoib/. Under this 
53
+directory the following files can be found:
54
+	
55
+	*** 	doc - Contains related documents including this file.
56
+	***		patches - Contains needed patch files.
57
+	*** 	samples - Contains sample files.
58
+	*** 	. Contains driver source files.
59
+	
60
+
61
+5. Burning the Flash Memory
62
+----------------------------
63
+The binary code resides in the same Flash device of the device firmware. 
64
+However the binary files are distinct and do not affect each other. Mellanox's 
65
+'mlxburn' tool is available for burning, however, it is not possible to burn 
66
+the expansion ROM image by itself; rather, both the firmware and expansion ROM 
67
+images must be burnt simultaneously.
68
+
69
+'mlxburn' is part of the Mellanox Firmware Tools (MFT) package 	available for 
70
+download from www.mellanox.com under 'Firmware Downloads'.
71
+
72
+Example:
73
+The following command burns a firmware image and an expansion ROM image to an 
74
+InfiniHost Adapter Card (P/N MHX-CE128-T.ini):
75
+	  
76
+   mlxburn -fw fw-23108-a1-rel.mlx -exp_rom MT23108.bin
77
+			 /dev/mst/mt23108_pci_cr0 -conf MHX-CE128-T.ini
78
+
79
+*** Important Note: The .ini file must support burning expansion ROMs. For 
80
+example, the following lines must appear in the .ini file. If they do not, 
81
+please add them	manually.
82
+
83
+[ADAPTER]
84
+exp_rom_en = true
85
+
86
+Mellanox's web site contains firmware binary files with extension .bin.gz. 
87
+These files contain contain EVERYTHING the goes in the flash memory and thus 
88
+are NOT suitable for including the expansion rom image. Therefore, one use the 
89
+files with .mlx extension also available from Mellanox's web site.
90
+
91
+	
92
+
93
+6. Preparing the DHCP Server
94
+-----------------------------
95
+DHCP messages over IP Over IB are transmitted as broadcasts. In order to 
96
+distinguish between messages belonging to a certain DHCP session, the messages 
97
+must carry the client identifier option (see ietf documentation	referred to 
98
+above). As of November 2005, ISC DHCP servers do not support this feature. 
99
+They are expected to support this at the end of 2005. In order to work this 
100
+out, the appropriate patch must be applied (see patches directory). It has 
101
+been tested on version isc-dhcpd-V3.0.4b2.
102
+
103
+The DHCP server must run on a machine which supports IP Over IB. The Mellanox 
104
+IBGD package (gen1 or gen2) can be used to provide this.
105
+To run the DHCP server from the command line use: dhcpd ib0
106
+
107
+7. DHCP Server Configuration File
108
+----------------------------------
109
+In order for the DHCP server to provide configuration records for clients, an 
110
+appropriate configuration file dhcpd.conf must be created and put under /etc/. 
111
+A sample configuration file with comments can be found in the samples directory.
112
+
113
+
114
+8. OpenSM
115
+----------
116
+To successfully boot over IB, the IB network must contain a Subnet Manager 
117
+which configures the IB network. OpenSM is part of the IBGD distribution and 
118
+can be used to accomplish that. Note that OpenSM may be run on the same host 
119
+running the DHCP server but it is not mandatory.
120
+
121
+
122
+9. TFTP Server
123
+---------------
124
+When the DHCP session is completed, the client has the IP address of the TFTP 
125
+server from which it should download the kernel image. This TFTP server must 
126
+run on a machine with InfiniBand support. The client loads first a loader 
127
+image based on PXE API which then loads the kernel image. The image can be 
128
+found in the Linux kernel homepage:
129
+
130
+http://www.kernel.org/pub/linux/boot/syslinux/
131
+
132
+
133
+10. BIOS Configuration
134
+-----------------------
135
+The expansion ROM image presents itself to the BIOS as a boot device. As a 
136
+result, the BIOS will add it to the list of boot devices. The priority of this 
137
+list can be modified when entering the BIOS setup. The boot over IB	image must 
138
+be set first for the BIOS to attempt to use it first.
139
+
140
+
141
+11. Operation
142
+--------------
143
+When booting the client, a message appears on the screen describing the device 
144
+found and the revision of the code. The user has 3 seconds to press a key for 
145
+increased functionality:
146
+'V' will increase verbosity.
147
+'I' will prinit some information to aid in configuring the DHCP configuration 
148
+    file. In this case the display will hold for 5 seconds to let the user 
149
+	grasp the information.
150
+	
151
+Note that increasing verbosity will significantly slow boot time and will 
152
+print lots of debug messages to the screen.
153
+
154
+
155
+12. Diskless Machines
156
+----------------------
157
+Most often it is required to boot a diskless machine. In these 	cases the 
158
+kernel mounts its root file system over NFS over one of the interfaces. For 
159
+this to happen on a client with only InfiniBand interfaces, the kernel image 
160
+must be configured accordingly and must include IP Over IB support. This can 
161
+be achieved either by compiling this into the kernel or using initrd images 
162
+that contain IP Over IB support.
163
+
164
+
165
+13. Changing Defaults
166
+----------------------
167
+As stated the driver uses port 1 for its communications. To use another port 
168
+edit the file src/drivers/net/ib_driver.h and modify the definition of 
169
+PXE_IB_PORT.
170
+
171
+
172
+14. Installing a package from Mellanox
173
+--------------------------------------
174
+When using a package obtained from Mellanox Technologies' web site, the
175
+directory src/bin will contain the driver binary files. The files have a .bin
176
+extension and are equivalent to the same files with .zrom extension.

+ 342
- 0
src/drivers/net/mlx_ipoib/ib_driver.c Datei anzeigen

@@ -0,0 +1,342 @@
1
+/*
2
+  This software is available to you under a choice of one of two
3
+  licenses.  You may choose to be licensed under the terms of the GNU
4
+  General Public License (GPL) Version 2, available at
5
+  <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6
+  license, available in the LICENSE.TXT file accompanying this
7
+  software.  These details are also available at
8
+  <http://openib.org/license.html>.
9
+
10
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
+  SOFTWARE.
18
+
19
+  Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
20
+*/
21
+
22
+#include "ib_driver.h"
23
+
24
+static const __u8 ipv4_bcast_gid[] = {
25
+	0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
26
+	0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff
27
+};
28
+
29
+static int wait_logic_link_up(__u8 port)
30
+{
31
+	unsigned int relax_time, max_time;
32
+	relax_time = 500;
33
+	max_time = 30000;	/* 30 seconds */
34
+	int rc;
35
+	unsigned int i, error = 1;
36
+	__u16 status;
37
+	struct port_info_st pi_var;
38
+	__u8 port_state;
39
+
40
+	for (i = 0; i < max_time; i += relax_time) {
41
+		rc = get_port_info(port, &pi_var, &status);
42
+		if (rc) {
43
+			eprintf("");
44
+			return rc;
45
+		} else {
46
+			if (status == 0) {
47
+				port_state = (pi_var.combined4 >> 24) & 0xf;
48
+				//port_state= pi_var.port_state;
49
+				if (port_state == 4) {
50
+					error = 0;
51
+					break;
52
+				}
53
+			}
54
+		}
55
+		printf("+");
56
+		mdelay(relax_time);
57
+	}
58
+
59
+	if (i >= max_time)
60
+		return -1;
61
+
62
+	return 0;
63
+}
64
+
65
+static int ib_driver_init(struct pci_device *pci, udqp_t * ipoib_qph_p)
66
+{
67
+	int rc;
68
+	__u8 port;
69
+	__u16 status;
70
+	__u32 qkey;
71
+	__u16 mlid;
72
+	ud_av_t av;
73
+	struct ib_eqe_st ib_eqe;
74
+	__u8 num_eqe;
75
+
76
+	tprintf("");
77
+	rc = ib_device_init(pci);
78
+	if (rc)
79
+		return rc;
80
+
81
+	tprintf("");
82
+
83
+	memcpy(ib_data.bcast_gid.raw, ipv4_bcast_gid, sizeof(ipv4_bcast_gid));
84
+
85
+	port = PXE_IB_PORT;
86
+	rc = setup_hca(port, &ib_data.eq);
87
+	if (rc)
88
+		return rc;
89
+	tprintf("setup_hca() success");
90
+
91
+	ib_data.port = port;
92
+
93
+	if(print_info)
94
+		printf("boot port = %d\n", ib_data.port);
95
+
96
+	rc = wait_logic_link_up(port);
97
+	if (rc)
98
+		return rc;
99
+
100
+	tprintf("wait_logic_link_up() success");
101
+
102
+	rc = get_guid_info(&status);
103
+	if (rc) {
104
+		eprintf("");
105
+		return rc;
106
+	} else if (status) {
107
+		eprintf("");
108
+		return rc;
109
+	}
110
+
111
+	tprintf("get_guid_info() success");
112
+
113
+	/* this to flush stdout that contains previous chars */
114
+	printf("    \n");
115
+	if(print_info) {
116
+		__u8 *gid=ib_data.port_gid.raw;
117
+
118
+		printf("\n");
119
+		printf("port GID=%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:"
120
+		       "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\n",
121
+		       gid[0],gid[1],gid[2],gid[3],gid[4],gid[5],gid[6],gid[7],
122
+		       gid[8],gid[9],gid[10],gid[11],gid[12],gid[13],gid[14],gid[15]);
123
+	}
124
+
125
+	rc = get_pkey_tbl(NULL, &status);
126
+	if (rc) {
127
+		eprintf("");
128
+		return rc;
129
+	} else if (status) {
130
+		eprintf("");
131
+		return rc;
132
+	}
133
+	rc = create_mads_qp(&ib_data.mads_qp,
134
+			    &ib_data.mads_snd_cq, &ib_data.mads_rcv_cq);
135
+	if (rc) {
136
+		eprintf("");
137
+		return rc;
138
+	}
139
+
140
+	tprintf("attempt to join mcast group ...");
141
+	rc = join_mc_group(&qkey, &mlid, 1);
142
+	if (rc) {
143
+		eprintf("");
144
+		return rc;
145
+	} else {
146
+		tprintf("join_mc_group() successfull qkey=0x%lx, mlid=0x%x",
147
+			qkey, mlid);
148
+	}
149
+
150
+	rc = create_ipoib_qp(&ib_data.ipoib_qp,
151
+			     &ib_data.ipoib_snd_cq,
152
+			     &ib_data.ipoib_rcv_cq, qkey);
153
+	if (rc) {
154
+		eprintf("");
155
+		return rc;
156
+	}
157
+
158
+	tprintf("create_ipoib_qp() success");
159
+	*ipoib_qph_p = ib_data.ipoib_qp;
160
+
161
+	tprintf("register qp to receive mcast...");
162
+	rc = add_qp_to_mcast_group(ib_data.bcast_gid, 1);
163
+	if (rc) {
164
+		eprintf("");
165
+		return rc;
166
+	} else {
167
+		tprintf("add_qp_to_mcast_group() success");
168
+	}
169
+
170
+	/* create a broadcast group ud AV */
171
+	av = alloc_ud_av();
172
+	if (!av) {
173
+		eprintf("");
174
+		return -1;
175
+	}
176
+	tprintf("alloc_ud_av() success");
177
+	modify_av_params(av, mlid, 1, 0, 0, &ib_data.bcast_gid, BCAST_QPN);
178
+	tprintf("modify_av_params() success");
179
+	ib_data.bcast_av = av;
180
+
181
+	do {
182
+		rc = poll_eq(&ib_eqe, &num_eqe);
183
+		if (rc) {
184
+			eprintf("");
185
+			return -1;
186
+		}
187
+		if (num_eqe) {
188
+			tprintf("num_eqe=%d", num_eqe);
189
+		}
190
+		tprintf("num_eqe=%d", num_eqe);
191
+	} while (num_eqe);
192
+	tprintf("eq is drained");
193
+
194
+	clear_interrupt();
195
+
196
+	return rc;
197
+}
198
+
199
+static int ib_driver_close(int fw_fatal)
200
+{
201
+	int rc, ret = 0;
202
+	__u32 qkey;
203
+	__u16 mlid;
204
+
205
+	rc = ib_device_close();
206
+	if (rc) {
207
+		eprintf("ib_device_close() failed");
208
+		ret = 1;
209
+	}
210
+
211
+	tprintf("");
212
+	if (!fw_fatal) {
213
+		rc = join_mc_group(&qkey, &mlid, 0);
214
+		if (rc) {
215
+			eprintf("");
216
+			ret = 1;
217
+		}
218
+		tprintf("join_mc_group(leave) success");
219
+
220
+		rc = add_qp_to_mcast_group(ib_data.bcast_gid, 0);
221
+		if (rc) {
222
+			eprintf("");
223
+			ret = 1;
224
+		}
225
+		tprintf("add_qp_to_mcast_group(remove) success");
226
+
227
+		rc = cmd_close_ib(ib_data.port);
228
+		if (rc) {
229
+			eprintf("");
230
+			ret = 1;
231
+		}
232
+		tprintf("cmd_close_ib(%d) success", ib_data.port);
233
+
234
+		if (destroy_udqp(ib_data.mads_qp)) {
235
+			eprintf("");
236
+			ret = 1;
237
+		}
238
+
239
+		if (destroy_udqp(ib_data.ipoib_qp)) {
240
+			eprintf("");
241
+			ret = 1;
242
+		}
243
+	}
244
+
245
+	rc = cmd_close_hca(fw_fatal);
246
+	if (rc) {
247
+		eprintf("");
248
+		ret = 1;
249
+	}
250
+
251
+	if (!fw_fatal) {
252
+		rc = cmd_sys_dis();
253
+		if (rc) {
254
+			eprintf("");
255
+			ret = 1;
256
+		}
257
+	}
258
+
259
+	return ret;
260
+}
261
+
262
+static int poll_cqe_tout(cq_t cqh, __u16 tout, void **wqe, int *good_p)
263
+{
264
+	int rc;
265
+	struct ib_cqe_st ib_cqe;
266
+	__u8 num_cqes;
267
+	unsigned long end;
268
+
269
+	end = currticks() + tout;
270
+	do {
271
+		rc = ib_poll_cq(cqh, &ib_cqe, &num_cqes);
272
+		if (rc)
273
+			return rc;
274
+
275
+		if (num_cqes == 1) {
276
+			if (good_p) {
277
+				*good_p = ib_cqe.is_error ? 0 : 1;
278
+			}
279
+			if (wqe)
280
+				*wqe = ib_cqe.wqe;
281
+			return 0;
282
+		}
283
+	}
284
+	while (currticks() < end);
285
+
286
+	return -1;
287
+}
288
+
289
+static u8 *get_port_gid(void)
290
+{
291
+	return ib_data.port_gid.raw;
292
+}
293
+
294
+static __u32 ib_get_qpn(udqp_t qph)
295
+{
296
+	__u32 qpn;
297
+
298
+	qpn = dev_get_qpn(qph);
299
+
300
+	return qpn;
301
+}
302
+
303
+static int drain_eq(void)
304
+{
305
+	__u8 num_eqe = 0, tot_eqe = 0;
306
+	int rc;
307
+
308
+	do {
309
+		tot_eqe += num_eqe;
310
+		rc = poll_eq(ib_data.eq, &num_eqe);
311
+		if (rc) {
312
+			eprintf("");
313
+			return -1;
314
+		}
315
+
316
+		tprintf("num_eqe=%d", num_eqe);
317
+	} while (num_eqe);
318
+	tprintf("eq is drained");
319
+	if (tot_eqe) {
320
+		tprintf("got %d eqes", tot_eqe);
321
+		return -1;
322
+	}
323
+
324
+	return 0;
325
+}
326
+
327
+
328
+static int poll_error_buf(void)
329
+{
330
+	__u32 *ptr= dev_ib_data.error_buf_addr;
331
+	__u32 i;
332
+
333
+	for (i=0; i<dev_ib_data.error_buf_size; ++i, ptr++) {
334
+		if ( readl(ptr) ) {
335
+			return -1;
336
+		}
337
+	}
338
+
339
+	return 0;
340
+}
341
+
342
+

+ 169
- 0
src/drivers/net/mlx_ipoib/ib_driver.h Datei anzeigen

@@ -0,0 +1,169 @@
1
+/*
2
+  This software is available to you under a choice of one of two
3
+  licenses.  You may choose to be licensed under the terms of the GNU
4
+  General Public License (GPL) Version 2, available at
5
+  <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6
+  license, available in the LICENSE.TXT file accompanying this
7
+  software.  These details are also available at
8
+  <http://openib.org/license.html>.
9
+
10
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
+  SOFTWARE.
18
+
19
+  Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
20
+*/
21
+
22
+#ifndef __ib_driver_h__
23
+#define __ib_driver_h__
24
+
25
+#define MELLANOX_VENDOR_ID	0x15b3
26
+
27
+#define GLOBAL_PD   0x123456
28
+#define GLOBAL_QKEY   0x80010000
29
+
30
+#define MAD_BUF_SZ 256
31
+#define IPOIB_RCV_BUF_SZ 2048
32
+#define IPOIB_SND_BUF_SZ 2048
33
+#define GRH_SIZE 40
34
+
35
+#define ARP_BUF_SZ 56
36
+
37
+#define FL_EOL 255		/* end of free list */
38
+
39
+#define SEND_CQE_POLL_TOUT 38	/* 2 sec */
40
+#define SA_RESP_POLL_TOUT 91	/* 5 seconds */
41
+
42
+#define NUM_AVS 10
43
+
44
+#define PXE_IB_PORT 1
45
+
46
+#define SA_QPN 1
47
+#define BCAST_QPN 0xffffff
48
+
49
+#define QPN_BASE 0x550000
50
+
51
+enum {
52
+	MADS_QPN_SN,
53
+	IPOIB_QPN_SN,
54
+	MAX_APP_QPS
55
+};
56
+
57
+enum {
58
+	MADS_SND_CQN_SN,
59
+	MADS_RCV_CQN_SN,
60
+	IPOIB_SND_CQN_SN,
61
+	IPOIB_RCV_CQN_SN,
62
+	MAX_APP_CQS
63
+};
64
+
65
+enum {
66
+	MTU_256 = 1,
67
+	MTU_512 = 2,
68
+	MTU_1024 = 3,
69
+	MTU_2048 = 4,
70
+};
71
+
72
+#define HCR_BASE 0x80680
73
+#define HCR_OFFSET_GO 0x80698
74
+#define HCR_OFFSET_STATUS 0x80698
75
+#define HCR_OFFSET_OUTPRM_H 0x8068C
76
+#define HCR_OFFSET_OUTPRM_L 0x80690
77
+
78
+#define MKEY_PREFIX 0x77000000
79
+#define MKEY_IDX_MASK 0xffffff
80
+
81
+/* event types */
82
+/*=============*/
83
+/* Completion Events */
84
+#define XDEV_EV_TYPE_CQ_COMP					0
85
+
86
+  /* IB - affiliated errors CQ  */
87
+#define XDEV_EV_TYPE_CQ_ERR						0x04
88
+#define XDEV_EV_TYPE_LOCAL_WQ_CATAS_ERR			0x05
89
+
90
+  /* Unaffiliated errors */
91
+#define XDEV_EV_TYPE_PORT_ERR					0x09
92
+#define XDEV_EV_TYPE_LOCAL_WQ_INVALID_REQ_ERR	0x10
93
+#define XDEV_EV_TYPE_LOCAL_WQ_ACCESS_VIOL_ERR	0x11
94
+
95
+/* NOPCODE field enumeration for doorbells and send-WQEs */
96
+#define XDEV_NOPCODE_SEND	10	/* Send */
97
+
98
+struct ib_gid_u32_st {
99
+	__u32 dw[4];
100
+};
101
+
102
+union ib_gid_u {
103
+	__u8 raw[16];
104
+	struct ib_gid_u32_st as_u32;
105
+} __attribute__ ((packed));
106
+
107
+struct ib_cqe_st {
108
+	__u8 is_error;
109
+	__u8 is_send;
110
+	void *wqe;
111
+	__u32 count;
112
+};
113
+
114
+typedef void *udqp_t;
115
+typedef void *cq_t;
116
+typedef void *ud_av_t;
117
+typedef void *ud_send_wqe_t;
118
+typedef void *eq_t;
119
+
120
+struct ib_data_st {
121
+//      __u32 mkey;
122
+//      __u32 pd;
123
+//      __u32 qkey;
124
+	udqp_t mads_qp;
125
+	udqp_t ipoib_qp;
126
+	cq_t mads_snd_cq;
127
+	cq_t mads_rcv_cq;
128
+	cq_t ipoib_snd_cq;
129
+	cq_t ipoib_rcv_cq;
130
+	eq_t eq;
131
+	__u16 sm_lid;
132
+	__u16 pkey;
133
+	union ib_gid_u port_gid;
134
+	union ib_gid_u bcast_gid;
135
+	ud_av_t bcast_av;	/* av allocated and used solely for broadcast */
136
+	__u8 port;
137
+};
138
+
139
+static int setup_hca(__u8 port, void **eq_p);
140
+static int post_send_req(udqp_t qp, ud_send_wqe_t wqe, __u8 num_gather);
141
+static void prep_send_wqe_buf(udqp_t qp,
142
+			      ud_av_t av,
143
+			      ud_send_wqe_t wqe,
144
+			      const void *buf,
145
+			      unsigned int offset, __u16 len, __u8 e);
146
+
147
+static int create_mads_qp(void **qp_pp, void **snd_cq_pp, void **rcv_cq_pp);
148
+
149
+static int create_ipoib_qp(udqp_t * qp_p,
150
+			   void **snd_cq_pp, void **rcv_cq_pp, __u32 qkey);
151
+
152
+static int gw_read_cr(__u32 addr, __u32 * result);
153
+static int gw_write_cr(__u32 addr, __u32 data);
154
+static ud_av_t alloc_ud_av(void);
155
+static void free_ud_av(ud_av_t av);
156
+static int ib_poll_cq(cq_t cq, struct ib_cqe_st *ib_cqe_p, __u8 * num_cqes);
157
+static int add_qp_to_mcast_group(union ib_gid_u mcast_gid, __u8 add);
158
+static int clear_interrupt(void);
159
+static int poll_cqe_tout(cq_t cqh, __u16 tout, void **wqe, int *good_p);
160
+
161
+static void *get_inprm_buf(void);
162
+static void *get_outprm_buf(void);
163
+static __u32 ib_get_qpn(udqp_t qph);
164
+
165
+static void dev_post_dbell(void *dbell, __u32 offset);
166
+
167
+static struct ib_data_st ib_data;
168
+
169
+#endif				/* __ib_driver_h__ */

+ 396
- 0
src/drivers/net/mlx_ipoib/ib_mad.c Datei anzeigen

@@ -0,0 +1,396 @@
1
+/*
2
+  This software is available to you under a choice of one of two
3
+  licenses.  You may choose to be licensed under the terms of the GNU
4
+  General Public License (GPL) Version 2, available at
5
+  <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6
+  license, available in the LICENSE.TXT file accompanying this
7
+  software.  These details are also available at
8
+  <http://openib.org/license.html>.
9
+
10
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
+  SOFTWARE.
18
+
19
+  Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
20
+*/
21
+
22
+#include "ib_mad.h"
23
+#include "mad_attrib.h"
24
+#include "cmdif.h"
25
+#include "ib_driver.h"
26
+
27
+#define TID_START 0x1234
28
+#define TID_INC 117
29
+
30
+static u32 next_tid = TID_START;
31
+
32
+/*
33
+ *  get_port_info
34
+ *
35
+ *	query the local device for the portinfo attribute
36
+ *
37
+ *	port(in) port number to query
38
+ *  buf(out) buffer to hold the result
39
+ */
40
+static int get_port_info(__u8 port, struct port_info_st *buf, __u16 * status)
41
+{
42
+	union port_info_mad_u *inprm;
43
+	union port_info_mad_u *outprm;
44
+	int rc;
45
+
46
+	inprm = get_inprm_buf();
47
+	outprm = get_outprm_buf();
48
+	memset(inprm, 0, sizeof *inprm);
49
+
50
+	inprm->mad.mad_hdr.method = IB_MGMT_METHOD_GET;
51
+	inprm->mad.mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
52
+	inprm->mad.mad_hdr.class_version = 1;
53
+	inprm->mad.mad_hdr.base_version = IB_MGMT_BASE_VERSION;
54
+	inprm->mad.mad_hdr.attr_id = IB_SMP_ATTR_PORT_INFO;
55
+	inprm->mad.mad_hdr.attr_mod = port;
56
+
57
+	rc = cmd_mad_ifc(inprm, (struct ib_mad_st *)outprm, port);
58
+	if (!rc) {
59
+		memcpy(buf, &outprm->mad.port_info,
60
+		       sizeof(outprm->mad.port_info));
61
+		*status = inprm->mad.mad_hdr.status;
62
+		if (!(*status)) {
63
+			ib_data.sm_lid = outprm->mad.port_info.mastersm_lid;
64
+			memcpy(&ib_data.port_gid.raw[0],
65
+			       outprm->mad.port_info.gid_prefix, 8);
66
+			cpu_to_be_buf(&ib_data.port_gid.raw[0], 8);
67
+		}
68
+	}
69
+	return rc;
70
+}
71
+
72
+/*
73
+ *  get_guid_info
74
+ *
75
+ *	query the local device for the guidinfo attribute
76
+ *
77
+ *  buf(out) buffer to hold the result
78
+ */
79
+static int get_guid_info(__u16 * status)
80
+{
81
+	union guid_info_mad_u *inprm;
82
+	union guid_info_mad_u *outprm;
83
+	int rc;
84
+
85
+	inprm = get_inprm_buf();
86
+	outprm = get_outprm_buf();
87
+	memset(inprm, 0, sizeof *inprm);
88
+
89
+	inprm->mad.mad_hdr.method = IB_MGMT_METHOD_GET;
90
+	inprm->mad.mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
91
+	inprm->mad.mad_hdr.class_version = 1;
92
+	inprm->mad.mad_hdr.base_version = IB_MGMT_BASE_VERSION;
93
+	inprm->mad.mad_hdr.attr_id = IB_SMP_ATTR_GUID_INFO;
94
+	inprm->mad.mad_hdr.attr_mod = 0;
95
+
96
+	rc = cmd_mad_ifc(inprm, (struct ib_mad_st *)outprm, ib_data.port);
97
+	if (!rc) {
98
+		*status = inprm->mad.mad_hdr.status;
99
+		if (!(*status)) {
100
+			memcpy(&ib_data.port_gid.raw[8],
101
+			       &outprm->mad.guid_info.gid_tbl[0], 8);
102
+			cpu_to_be_buf(&ib_data.port_gid.raw[8], 8);
103
+		}
104
+	}
105
+	return rc;
106
+}
107
+
108
+static int get_pkey_tbl(struct pkey_tbl_st *pkey_tbl, __u16 * status)
109
+{
110
+	union pkey_tbl_mad_u *inprm;
111
+	union pkey_tbl_mad_u *outprm;
112
+	int rc;
113
+
114
+	inprm = get_inprm_buf();
115
+	outprm = get_outprm_buf();
116
+	memset(inprm, 0, sizeof *inprm);
117
+	memset(outprm, 0, sizeof *outprm);
118
+
119
+	inprm->mad.mad_hdr.method = IB_MGMT_METHOD_GET;
120
+	inprm->mad.mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
121
+	inprm->mad.mad_hdr.class_version = 1;
122
+	inprm->mad.mad_hdr.base_version = IB_MGMT_BASE_VERSION;
123
+	inprm->mad.mad_hdr.attr_id = IB_SMP_ATTR_PKEY_TABLE;
124
+	inprm->mad.mad_hdr.attr_mod = 0;
125
+
126
+	rc = cmd_mad_ifc(inprm, (struct ib_mad_st *)outprm, 1);
127
+	if (!rc) {
128
+		if (pkey_tbl)
129
+			memcpy(pkey_tbl, &outprm->mad.pkey_tbl, 2);
130
+		*status = inprm->mad.mad_hdr.status;
131
+		if (!(*status)) {
132
+			ib_data.pkey = outprm->mad.pkey_tbl.pkey_tbl[0][1];
133
+			ib_data.bcast_gid.raw[4] =
134
+			    outprm->mad.pkey_tbl.pkey_tbl[0][1] >> 8;
135
+			ib_data.bcast_gid.raw[5] =
136
+			    outprm->mad.pkey_tbl.pkey_tbl[0][1] & 0xff;
137
+		}
138
+	}
139
+	return rc;
140
+}
141
+
142
+static int join_mc_group(__u32 * qkey_p, __u16 * mlid_p, __u8 join)
143
+{
144
+	struct mc_member_mad_st *mad, *rcv_mad;
145
+	void *snd_wqe;
146
+	void *tmp_wqe;
147
+	udqp_t qp;
148
+	void *av;
149
+	int rc;
150
+	u32 tid;
151
+	void *rcv_wqe;
152
+	int is_good;
153
+
154
+	qp = ib_data.mads_qp;
155
+
156
+	snd_wqe = alloc_send_wqe(qp);
157
+	if (!snd_wqe) {
158
+		eprintf("");
159
+		return -1;
160
+	}
161
+	tprintf("allocated snd_wqe=0x%lx", snd_wqe);
162
+
163
+	mad = get_send_wqe_buf(snd_wqe, 0);
164
+	memset(mad, 0, 256);
165
+
166
+	av = alloc_ud_av();
167
+	if (!av) {
168
+		eprintf("");
169
+		free_wqe(snd_wqe);
170
+		return -1;
171
+	}
172
+	modify_av_params(av, ib_data.sm_lid, 0, 0, 0, NULL, SA_QPN);
173
+
174
+	prep_send_wqe_buf(qp, av, snd_wqe, NULL, 0, 256, 0);
175
+
176
+	mad->mad_hdr.method = join ? IB_MGMT_METHOD_SET : IB_MGMT_METHOD_DELETE;
177
+	mad->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
178
+	mad->mad_hdr.class_version = 2;
179
+	mad->mad_hdr.base_version = IB_MGMT_BASE_VERSION;
180
+	mad->mad_hdr.attr_id = IB_SA_ATTR_MC_MEMBER_REC;
181
+	tid = next_tid;
182
+	next_tid += TID_INC;
183
+	mad->mad_hdr.tid[1] = tid;
184
+
185
+	mad->sa_hdr.comp_mask[1] = IB_SA_MCMEMBER_REC_MGID |
186
+	    IB_SA_MCMEMBER_REC_PORT_GID | IB_SA_MCMEMBER_REC_JOIN_STATE;
187
+
188
+	mad->mc_member.combined4 |= (1 << 24);	/*mad->mc_member.join_state = 1; */
189
+
190
+	be_to_cpu_buf(mad, sizeof *mad);
191
+	memcpy(mad->mc_member.mgid, ib_data.bcast_gid.raw, 16);
192
+	memcpy(mad->mc_member.port_gid, ib_data.port_gid.raw, 16);
193
+
194
+	rc = post_send_req(qp, snd_wqe, 1);
195
+	if (rc) {
196
+		eprintf("");
197
+		free_ud_av(av);
198
+		free_wqe(snd_wqe);
199
+		return -1;
200
+	}
201
+
202
+	tprintf("");
203
+	/* poll the CQ to get the completions
204
+	   on the send and the expected receive */
205
+
206
+	/* send completion */
207
+	rc = poll_cqe_tout(ib_data.mads_snd_cq, SEND_CQE_POLL_TOUT, &tmp_wqe,
208
+			   &is_good);
209
+	if (rc) {
210
+		eprintf("");
211
+		return -1;
212
+	}
213
+
214
+	if (tmp_wqe != snd_wqe) {
215
+		eprintf("");
216
+		return -1;
217
+	}
218
+
219
+	if (free_wqe(snd_wqe)) {
220
+		eprintf("");
221
+		return -1;
222
+	}
223
+	free_ud_av(av);
224
+
225
+	if (!is_good) {
226
+		eprintf("");
227
+		return -1;
228
+	}
229
+
230
+	/* receive completion */
231
+	rc = poll_cqe_tout(ib_data.mads_rcv_cq, SA_RESP_POLL_TOUT, &rcv_wqe,
232
+			   &is_good);
233
+	if (rc) {
234
+		eprintf("");
235
+		return -1;
236
+	}
237
+
238
+	if (is_good) {
239
+		rcv_mad = get_rcv_wqe_buf(rcv_wqe, 1);
240
+		be_to_cpu_buf(rcv_mad, sizeof *rcv_mad);
241
+		if (rcv_mad->mad_hdr.tid[1] == tid) {
242
+			/* that's our response */
243
+			if (mad->mad_hdr.status == 0) {
244
+				/* good response - save results */
245
+				*qkey_p = rcv_mad->mc_member.q_key;
246
+				*mlid_p = rcv_mad->mc_member.combined1 >> 16;	// rcv_mad->mc_member.mlid;
247
+			} else {
248
+				/* join failed */
249
+				eprintf("");
250
+				return -1;
251
+			}
252
+		} else {
253
+			/* not our response */
254
+			eprintf("");
255
+			return -1;
256
+		}
257
+	}
258
+
259
+	if (free_wqe(rcv_wqe)) {
260
+		eprintf("");
261
+		return -1;
262
+	}
263
+
264
+	return is_good ? 0 : -1;
265
+}
266
+
267
+static int get_path_record(union ib_gid_u *dgid, __u16 * dlid_p, u8 * sl_p,
268
+			   u8 * rate_p)
269
+{
270
+	struct path_record_mad_st *mad, *rcv_mad;
271
+	void *snd_wqe;
272
+	udqp_t qp;
273
+	ud_av_t av;
274
+	void *tmp_wqe;
275
+	void *rcv_wqe;
276
+	u32 tid;
277
+	int rc;
278
+	int is_good;
279
+
280
+	tprintf("gid=%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:"
281
+		"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
282
+		dgid->raw[0], dgid->raw[1], dgid->raw[2], dgid->raw[3],
283
+		dgid->raw[4], dgid->raw[5], dgid->raw[6], dgid->raw[7],
284
+		dgid->raw[8], dgid->raw[9], dgid->raw[10], dgid->raw[11],
285
+		dgid->raw[12], dgid->raw[13], dgid->raw[14], dgid->raw[15]);
286
+	qp = ib_data.mads_qp;
287
+
288
+	snd_wqe = alloc_send_wqe(qp);
289
+	if (!snd_wqe) {
290
+		eprintf("");
291
+		return -1;
292
+	}
293
+
294
+	mad = get_send_wqe_buf(snd_wqe, 0);
295
+	memset(mad, 0, 256);
296
+
297
+	av = alloc_ud_av();
298
+	if (!av) {
299
+		eprintf("");
300
+		free_wqe(snd_wqe);
301
+		return -1;
302
+	}
303
+	modify_av_params(av, ib_data.sm_lid, 0, 0, 0, NULL, SA_QPN);
304
+
305
+	prep_send_wqe_buf(qp, av, snd_wqe, NULL, 0, 256, 0);
306
+
307
+	mad->mad_hdr.method = IB_MGMT_METHOD_GET;
308
+	mad->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
309
+	mad->mad_hdr.class_version = 2;
310
+	mad->mad_hdr.base_version = IB_MGMT_BASE_VERSION;
311
+	mad->mad_hdr.attr_id = IB_SA_ATTR_PATH_REC;
312
+	tid = next_tid;
313
+	next_tid += TID_INC;
314
+	mad->mad_hdr.tid[1] = tid;
315
+
316
+	memcpy(mad->path_record.dgid.raw, dgid->raw, 16);
317
+	cpu_to_be_buf(mad->path_record.dgid.raw, 16);
318
+
319
+	mad->sa_hdr.comp_mask[1] = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID;
320
+
321
+	cpu_to_be_buf(mad, sizeof *mad);
322
+	memcpy(mad->path_record.sgid.raw, ib_data.port_gid.raw, 16);
323
+
324
+	rc = post_send_req(qp, snd_wqe, 1);
325
+	if (rc) {
326
+		eprintf("");
327
+		free_ud_av(av);
328
+		free_wqe(snd_wqe);
329
+		return rc;
330
+	}
331
+
332
+	/* poll the CQ to get the completions
333
+	   on the send and the expected receive */
334
+
335
+	/* send completion */
336
+	rc = poll_cqe_tout(ib_data.mads_snd_cq, SEND_CQE_POLL_TOUT, &tmp_wqe,
337
+			   &is_good);
338
+	if (rc) {
339
+		eprintf("");
340
+		return -1;
341
+	}
342
+
343
+	if (tmp_wqe != snd_wqe) {
344
+		eprintf("");
345
+		return -1;
346
+	}
347
+
348
+	if (free_wqe(snd_wqe)) {
349
+		eprintf("");
350
+		return -1;
351
+	}
352
+	free_ud_av(av);
353
+
354
+	if (!is_good) {
355
+		eprintf("");
356
+		return -1;
357
+	}
358
+
359
+	/* receive completion */
360
+	rc = poll_cqe_tout(ib_data.mads_rcv_cq, SA_RESP_POLL_TOUT, &rcv_wqe,
361
+			   &is_good);
362
+	if (rc) {
363
+		eprintf("");
364
+		return -1;
365
+	}
366
+
367
+	if (is_good) {
368
+		rcv_mad = get_rcv_wqe_buf(rcv_wqe, 1);
369
+		be_to_cpu_buf(rcv_mad, sizeof *rcv_mad);
370
+		if (rcv_mad->mad_hdr.tid[1] == tid) {
371
+			/* that's our response */
372
+			if (mad->mad_hdr.status == 0) {
373
+				/* good response - save results */
374
+				*dlid_p = rcv_mad->path_record.dlid;
375
+				*sl_p = (rcv_mad->path_record.combined3 >> 16) & 0xf;	//  rcv_mad->path_record.sl;
376
+				*rate_p = rcv_mad->path_record.combined3 & 0x3f;	//rcv_mad->path_record.rate;
377
+			} else {
378
+				/* join failed */
379
+				eprintf("");
380
+				return -1;
381
+			}
382
+		} else {
383
+			/* not our response */
384
+			eprintf("");
385
+			return -1;
386
+		}
387
+	}
388
+
389
+	if (free_wqe(rcv_wqe)) {
390
+		eprintf("");
391
+		return -1;
392
+	}
393
+
394
+	tprintf("");
395
+	return is_good ? 0 : -1;
396
+}

+ 110
- 0
src/drivers/net/mlx_ipoib/ib_mad.h Datei anzeigen

@@ -0,0 +1,110 @@
1
+/*
2
+  This software is available to you under a choice of one of two
3
+  licenses.  You may choose to be licensed under the terms of the GNU
4
+  General Public License (GPL) Version 2, available at
5
+  <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6
+  license, available in the LICENSE.TXT file accompanying this
7
+  software.  These details are also available at
8
+  <http://openib.org/license.html>.
9
+
10
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
+  SOFTWARE.
18
+
19
+  Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
20
+*/
21
+
22
+#ifndef __ib_mad_h__
23
+#define __ib_mad_h__
24
+
25
+#include "ib_driver.h"
26
+
27
+/* Management base version */
28
+#define IB_MGMT_BASE_VERSION			1
29
+
30
+/* Management classes */
31
+#define IB_MGMT_CLASS_SUBN_LID_ROUTED		0x01
32
+#define IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE	0x81
33
+#define IB_MGMT_CLASS_SUBN_ADM			0x03
34
+#define IB_MGMT_CLASS_PERF_MGMT			0x04
35
+#define IB_MGMT_CLASS_BM			0x05
36
+#define IB_MGMT_CLASS_DEVICE_MGMT		0x06
37
+#define IB_MGMT_CLASS_CM			0x07
38
+#define IB_MGMT_CLASS_SNMP			0x08
39
+#define IB_MGMT_CLASS_VENDOR_RANGE2_START	0x30
40
+#define IB_MGMT_CLASS_VENDOR_RANGE2_END		0x4F
41
+
42
+/* Management methods */
43
+#define IB_MGMT_METHOD_GET			0x01
44
+#define IB_MGMT_METHOD_SET			0x02
45
+#define IB_MGMT_METHOD_GET_RESP			0x81
46
+#define IB_MGMT_METHOD_SEND			0x03
47
+#define IB_MGMT_METHOD_TRAP			0x05
48
+#define IB_MGMT_METHOD_REPORT			0x06
49
+#define IB_MGMT_METHOD_REPORT_RESP		0x86
50
+#define IB_MGMT_METHOD_TRAP_REPRESS		0x07
51
+#define IB_MGMT_METHOD_DELETE			0x15
52
+
53
+#define IB_MGMT_METHOD_RESP			0x80
54
+
55
+/* Subnet management attributes */
56
+#define IB_SMP_ATTR_NOTICE					0x0002
57
+#define IB_SMP_ATTR_NODE_DESC				0x0010
58
+#define IB_SMP_ATTR_NODE_INFO				0x0011
59
+#define IB_SMP_ATTR_SWITCH_INFO				0x0012
60
+#define IB_SMP_ATTR_GUID_INFO				0x0014
61
+#define IB_SMP_ATTR_PORT_INFO				0x0015
62
+#define IB_SMP_ATTR_PKEY_TABLE				0x0016
63
+#define IB_SMP_ATTR_SL_TO_VL_TABLE			0x0017
64
+#define IB_SMP_ATTR_VL_ARB_TABLE			0x0018
65
+#define IB_SMP_ATTR_LINEAR_FORWARD_TABLE	0x0019
66
+#define IB_SMP_ATTR_RANDOM_FORWARD_TABLE	0x001A
67
+#define IB_SMP_ATTR_MCAST_FORWARD_TABLE		0x001B
68
+#define IB_SMP_ATTR_SM_INFO					0x0020
69
+#define IB_SMP_ATTR_VENDOR_DIAG				0x0030
70
+#define IB_SMP_ATTR_LED_INFO				0x0031
71
+#define IB_SMP_ATTR_VENDOR_MASK				0xFF00
72
+
73
+struct ib_mad_hdr_st {
74
+	__u8 method;
75
+	__u8 class_version;
76
+	__u8 mgmt_class;
77
+	__u8 base_version;
78
+	__u16 class_specific;
79
+	__u16 status;
80
+	__u32 tid[2];
81
+	__u16 resv;
82
+	__u16 attr_id;
83
+	__u32 attr_mod;
84
+} __attribute__ ((packed));
85
+
86
+struct rmpp_hdr_st {
87
+	__u32 raw[3];
88
+} __attribute__ ((packed));
89
+
90
+struct sa_header_st {
91
+	__u32 sm_key[2];
92
+	__u16 attrib_offset;
93
+	__u16 r0;
94
+	__u32 comp_mask[2];
95
+} __attribute__ ((packed));
96
+
97
+struct ib_mad_st {
98
+	struct ib_mad_hdr_st mad_hdr;
99
+	__u8 data[232];
100
+} __attribute__ ((packed));
101
+
102
+union mad_u {
103
+	__u8 raw[256];
104
+	struct ib_mad_st mad;
105
+} __attribute__ ((packed));
106
+
107
+static int get_path_record(union ib_gid_u *dgid, __u16 * dlid_p, __u8 * sl_p,
108
+			   __u8 * rate_p);
109
+
110
+#endif				/* __ib_mad_h__ */

+ 1701
- 0
src/drivers/net/mlx_ipoib/ib_mt23108.c
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 1929
- 0
src/drivers/net/mlx_ipoib/ib_mt25218.c
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 1027
- 0
src/drivers/net/mlx_ipoib/ipoib.c
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 297
- 0
src/drivers/net/mlx_ipoib/ipoib.h Datei anzeigen

@@ -0,0 +1,297 @@
1
+/*
2
+  This software is available to you under a choice of one of two
3
+  licenses.  You may choose to be licensed under the terms of the GNU
4
+  General Public License (GPL) Version 2, available at
5
+  <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6
+  license, available in the LICENSE.TXT file accompanying this
7
+  software.  These details are also available at
8
+  <http://openib.org/license.html>.
9
+
10
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
+  SOFTWARE.
18
+
19
+  Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
20
+*/
21
+
22
+#ifndef __ipoib_h__
23
+#define __ipoib_h__
24
+
25
+#define ARP_PROT_TYPE 0x806
26
+#define IPV4_PROT_TYPE 0x800
27
+
28
+#define IPOIB_HW_TYPE 0x20
29
+#define ETH_HW_TYPE 1
30
+
31
+#define ARP_OP_REQUESET 1
32
+#define ARP_OP_REPLY    2
33
+
34
+#define MLX_ETH_3BYTE_PREFIX 0x2c9	/* 00,02,c9 */
35
+#define MLX_ETH_BYTE0 0
36
+#define MLX_ETH_BYTE1 2
37
+#define MLX_ETH_BYTE2 0xC9
38
+
39
+#define IP_PROT_UDP 17
40
+#define DHCP_TYPE_REQUEST 1
41
+#define DHCP_TYPE_RESPONSE 2
42
+#define DHCP_TYPE_ACK 5
43
+
44
+struct ipoib_mac_st {
45
+	__u32 qpn:24;
46
+	__u32 r0:8;
47
+	__u8 gid[16];
48
+} __attribute__ ((packed));
49
+
50
+struct arp_packet_st {
51
+	__u16 arp_prot_type;
52
+	__u16 hw_type;
53
+	__u16 opcode;
54
+	__u8 prot_size;
55
+	__u8 hw_len;
56
+	struct ipoib_mac_st sender_mac;
57
+	__u32 sender_ip;
58
+	struct ipoib_mac_st target_mac;
59
+	__u32 target_ip;
60
+} __attribute__ ((packed));
61
+
62
+/* this struct is used to translate between ipoib and
63
+   ethernet mac addresses */
64
+struct mac_xlation_st {
65
+	__u8 valid;		/* 1=entry valid 0=entry free */
66
+	__u32 youth;		/* youth of this entry the lowest the
67
+				   number the older in age */
68
+	__u8 eth_mac_lsb[3];	/* three bytes Ethernet MAC
69
+				   LS bytes are constants */
70
+	union ib_gid_u gid;
71
+	__u32 qpn;
72
+	ud_av_t av;		/* address vector representing neighbour */
73
+};
74
+
75
+static inline __u16 get_prot_type(void *data)
76
+{
77
+	__u8 *ptr = data;
78
+
79
+	return be16_to_cpu(*((__u16 *) ptr));
80
+}
81
+
82
+static inline __u8 get_hw_len(void *data)
83
+{
84
+	return ((__u8 *) data)[8];
85
+}
86
+
87
+static inline __u8 get_prot_size(void *data)
88
+{
89
+	return ((__u8 *) data)[9];
90
+}
91
+
92
+static inline __u16 get_opcode(const void *data)
93
+{
94
+	return be16_to_cpu(*((__u16 *) (&(((__u8 *) data)[10]))));
95
+}
96
+
97
+static inline __u32 get_sender_qpn(void *data)
98
+{
99
+	__u8 *ptr = data;
100
+
101
+	return (ptr[13] << 16) | (ptr[14] << 8) | ptr[15];
102
+}
103
+
104
+static inline const __u8 *get_sender_gid(void *data)
105
+{
106
+	return &(((__u8 *) data)[16]);
107
+}
108
+
109
+static inline void *arp_mac6_get_sender_ip(const void *data)
110
+{
111
+	return (__u8 *) data + 14;
112
+}
113
+
114
+static inline const void *arp_mac6_get_target_ip(const void *data)
115
+{
116
+	return data + 24;
117
+}
118
+
119
+static inline void arp_mac20_set_sender_ip(const void *ip, void *data)
120
+{
121
+	memcpy(((__u8 *) data) + 28, ip, 4);
122
+}
123
+
124
+static inline void arp_mac20_set_target_ip(const void *ip, void *data)
125
+{
126
+	memcpy(((__u8 *) data) + 52, ip, 4);
127
+}
128
+
129
+static inline void arp_mac20_set_sender_mac(const void *qpn, const void *gid,
130
+					    void *data)
131
+{
132
+	memcpy(((__u8 *) data) + 9, qpn, 3);
133
+	memcpy(((__u8 *) data) + 12, gid, 16);
134
+}
135
+
136
+static inline void arp_mac20_set_target_mac(void *qpn, void *gid, void *data)
137
+{
138
+	memcpy(((__u8 *) data) + 33, qpn, 3);
139
+	memcpy(((__u8 *) data) + 36, gid, 16);
140
+}
141
+
142
+static inline const void *arp_mac6_get_opcode(const void *data)
143
+{
144
+	return data + 6;
145
+}
146
+
147
+static inline void arp_mac20_set_opcode(const void *opcode, void *data)
148
+{
149
+	memcpy(data + 6, opcode, 2);
150
+}
151
+
152
+static inline const void *arp_mac6_get_target_mac(const void *data)
153
+{
154
+	return data + 18;
155
+}
156
+
157
+static inline const void *arp_mac20_get_sender_qpn(void *data)
158
+{
159
+	return ((__u8 *) data) + 13;
160
+}
161
+
162
+static inline const void *arp_mac20_get_sender_gid(void *data)
163
+{
164
+	return ((__u8 *) data) + 16;
165
+}
166
+
167
+static inline const void *arp_mac20_get_target_qpn(void *data)
168
+{
169
+	return ((__u8 *) data) + 37;
170
+}
171
+
172
+static inline const void *arp_mac20_get_target_gid(void *data)
173
+{
174
+	return ((__u8 *) data) + 40;
175
+}
176
+
177
+static inline const void *get_lptr_by_off(const void *packet, __u16 offset)
178
+{
179
+	return packet + offset;
180
+}
181
+
182
+static inline __u8 get_ip_protocl_type(const void *packet)
183
+{
184
+	const void *ptr;
185
+	__u8 prot;
186
+
187
+	ptr = get_lptr_by_off(packet, 9);
188
+
189
+	memcpy(&prot, ptr, 1);
190
+	return prot;
191
+}
192
+
193
+static inline __u16 get_udp_dest_port(const void *packet)
194
+{
195
+	const void *ptr;
196
+	__u16 port;
197
+
198
+	ptr = get_lptr_by_off(packet, 22);
199
+
200
+	memcpy(&port, ptr, 2);
201
+	return port;
202
+}
203
+
204
+static inline __u8 get_dhcp_message_type(const void *packet)
205
+{
206
+	const void *ptr;
207
+	__u8 type;
208
+
209
+	ptr = get_lptr_by_off(packet, 28);
210
+
211
+	memcpy(&type, ptr, 1);
212
+	return type;
213
+}
214
+
215
+static inline void set_hw_type(__u8 * packet)
216
+{
217
+	packet[29] = IPOIB_HW_TYPE;
218
+}
219
+
220
+static inline void zero_hw_len(__u8 * packet)
221
+{
222
+	packet[30] = 0;
223
+}
224
+
225
+static inline void set_udp_csum(__u8 * packet, __u16 val)
226
+{
227
+	__u16 *csum_ptr;
228
+
229
+	csum_ptr = (__u16 *) (packet + 26);
230
+
231
+	*csum_ptr = htons(val);
232
+}
233
+
234
+static inline void zero_chaddr(__u8 * packet)
235
+{
236
+	memset(packet + 56, 0, 16);
237
+}
238
+
239
+static inline void set_bcast_flag(__u8 * packet)
240
+{
241
+	packet[38] = 0x80;
242
+}
243
+
244
+static inline __u8 get_ip_protocl(void *buf)
245
+{
246
+	return ((__u8 *) buf)[9];
247
+}
248
+
249
+static inline __u16 get_udp_dst_port(void *buf)
250
+{
251
+	return be16_to_cpu(*((__u16 *) (((__u8 *) buf) + 0x16)));
252
+}
253
+
254
+static inline __u8 get_dhcp_msg_type(void *buf)
255
+{
256
+	return ((__u8 *) buf)[0x1c];
257
+}
258
+
259
+static inline void set_eth_hwtype(void *buf)
260
+{
261
+	((__u8 *) buf)[0x1d] = ETH_HW_TYPE;
262
+}
263
+
264
+static inline void set_eth_hwlen(void *buf)
265
+{
266
+	((__u8 *) buf)[0x1e] = 6;
267
+}
268
+
269
+static inline void add_udp_len(void *buf, __u16 size_add)
270
+{
271
+	__u16 old_len, *len_ptr;
272
+
273
+	len_ptr = (__u16 *) (((__u8 *) buf) + 24);
274
+	old_len = ntohs(*len_ptr);
275
+	*len_ptr = htons(old_len + size_add);
276
+}
277
+
278
+static inline void set_own_mac(void *buf)
279
+{
280
+	((__u8 *) buf)[0x38] = 0xff;	//MLX_ETH_BYTE0;
281
+	((__u8 *) buf)[0x39] = 0xff;	//MLX_ETH_BYTE1;
282
+	((__u8 *) buf)[0x3a] = 0xff;	//MLX_ETH_BYTE2;
283
+	((__u8 *) buf)[0x3b] = 0xff;	//0;
284
+	((__u8 *) buf)[0x3c] = 0xff;	//0;
285
+	((__u8 *) buf)[0x3d] = 0xff;	//0;
286
+}
287
+
288
+static int ipoib_handle_rcv(void *buf, void **out_buf_p,
289
+			    unsigned int *new_size_p, int *bcast_p);
290
+static int ipoib_send_packet(const __u8 * mac, __u16 protocol, const void *data,
291
+			     unsigned int size);
292
+static int ipoib_init(struct pci_device *pci);
293
+static u8 *get_port_gid(void);
294
+static int ipoib_read_packet(__u16 * prot_p, void *data, unsigned int *size_p,
295
+			     int *is_bcast_p);
296
+
297
+#endif				/* __ipoib_h__ */

+ 244
- 0
src/drivers/net/mlx_ipoib/mad_attrib.h Datei anzeigen

@@ -0,0 +1,244 @@
1
+/*
2
+  This software is available to you under a choice of one of two
3
+  licenses.  You may choose to be licensed under the terms of the GNU
4
+  General Public License (GPL) Version 2, available at
5
+  <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6
+  license, available in the LICENSE.TXT file accompanying this
7
+  software.  These details are also available at
8
+  <http://openib.org/license.html>.
9
+
10
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
+  SOFTWARE.
18
+
19
+  Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
20
+*/
21
+
22
+#ifndef __mad_attrib_h_
23
+#define __mad_attrib_h_
24
+
25
+#include "ib_mad.h"
26
+
27
+#define IB_SA_ATTR_MC_MEMBER_REC 0x38
28
+#define IB_SA_ATTR_PATH_REC 0x35
29
+
30
+#define IB_SA_MCMEMBER_REC_MGID						(1<<0)
31
+#define IB_SA_MCMEMBER_REC_PORT_GID					(1<<1)
32
+#define IB_SA_MCMEMBER_REC_QKEY						(1<<2)
33
+#define IB_SA_MCMEMBER_REC_MLID						(1<<3)
34
+#define IB_SA_MCMEMBER_REC_MTU_SELECTOR				(1<<4)
35
+#define IB_SA_MCMEMBER_REC_MTU						(1<<5)
36
+#define IB_SA_MCMEMBER_REC_TRAFFIC_CLASS			(1<<6)
37
+#define IB_SA_MCMEMBER_REC_PKEY						(1<<7)
38
+#define IB_SA_MCMEMBER_REC_RATE_SELECTOR			(1<<8)
39
+#define IB_SA_MCMEMBER_REC_RATE						(1<<9)
40
+#define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME_SELECTOR	(1<<10)
41
+#define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME			(1<<11)
42
+#define IB_SA_MCMEMBER_REC_SL						(1<<12)
43
+#define IB_SA_MCMEMBER_REC_FLOW_LABEL				(1<<13)
44
+#define IB_SA_MCMEMBER_REC_HOP_LIMIT				(1<<14)
45
+#define IB_SA_MCMEMBER_REC_SCOPE					(1<<15)
46
+#define IB_SA_MCMEMBER_REC_JOIN_STATE				(1<<16)
47
+#define IB_SA_MCMEMBER_REC_PROXY_JOIN				(1<<17)
48
+
49
+#define IB_SA_PATH_REC_DGID		(1<<2)
50
+#define IB_SA_PATH_REC_SGID		(1<<3)
51
+
52
+struct port_info_st {
53
+	__u32 mkey[2];
54
+	__u32 gid_prefix[2];
55
+	__u16 mastersm_lid;
56
+	__u16 lid;
57
+	__u32 cap_mask;
58
+	__u32 combined2;
59
+			/*__u32 mkey_lease_period:16;
60
+			__u32 diag_code:16;*/
61
+	__u32 combined3;
62
+			/*__u32 link_width_active:8;
63
+			__u32 link_width_supported:8;
64
+			__u32 link_width_enabled:8;
65
+			__u32 local_port_num:8;*/
66
+	__u32 combined4;
67
+			/*__u32 link_speed_enabled:4;
68
+			__u32 link_speed_active:4;
69
+			__u32 lmc:3;
70
+			__u32 r1:3;
71
+			__u32 mkey_prot_bits:2;
72
+			__u32 link_down_def_state:4;
73
+			__u32 port_phys_state:4;
74
+			__u32 port_state:4;
75
+			__u32 link_speed_supported:4;*/
76
+	__u32 combined5;
77
+			/*__u32 vl_arb_hi_cap:8;
78
+			__u32 vl_hi_limit:8;
79
+			__u32 init_type:4;
80
+			__u32 vl_cap:4;
81
+			__u32 master_smsl:4;
82
+			__u32 neigh_mtu:4;*/
83
+	__u32 combined6;
84
+			/*__u32 filt_raw_oub:1;
85
+			__u32 filt_raw_inb:1;
86
+			__u32 part_enf_oub:1;
87
+			__u32 part_enf_inb:1;
88
+			__u32 op_vls:4;
89
+			__u32 hoq_life:5;
90
+			__u32 vl_stall_count:3;
91
+			__u32 mtu_cap:4;
92
+			__u32 init_type_reply:4;
93
+			__u32 vl_arb_lo_cap:8;*/
94
+	__u32 combined7;
95
+			/*__u32 pkey_viol:16;
96
+			__u32 mkey_viol:16;*/
97
+	__u32 combined8;
98
+			/*__u32 subn_tout:5;
99
+			__u32 r2:2;
100
+			__u32 client_rereg:1;
101
+			__u32 guid_cap:8;
102
+			__u32 qkey_viol:16;*/
103
+	__u32 combined9;
104
+			/*__u32 max_cred_hint:16;
105
+			__u32 overrun_err:4;
106
+			__u32 local_phy_err:4;
107
+			__u32 resp_t_val:5;
108
+			__u32 r3:3;*/
109
+	__u32 combined10;
110
+			/*__u32 r4:8;
111
+			__u32 link_rtrip_lat:24;*/
112
+} __attribute__ ((packed));
113
+
114
+struct port_info_mad_st {
115
+	struct ib_mad_hdr_st mad_hdr;
116
+	__u32 mkey[2];
117
+	__u32 r1[8];
118
+	struct port_info_st port_info;
119
+} __attribute__ ((packed));
120
+
121
+union port_info_mad_u {
122
+	__u8 raw[256];
123
+	struct port_info_mad_st mad;
124
+} __attribute__ ((packed));
125
+
126
+struct guid_info_st {
127
+	union ib_gid_u gid_tbl[8];
128
+} __attribute__ ((packed));
129
+
130
+struct guid_info_mad_st {
131
+	struct ib_mad_hdr_st mad_hdr;
132
+	__u32 mkey[2];
133
+	__u32 r1[8];
134
+	struct guid_info_st guid_info;
135
+} __attribute__ ((packed));
136
+
137
+union guid_info_mad_u {
138
+	__u8 raw[256];
139
+	struct guid_info_mad_st mad;
140
+} __attribute__ ((packed));
141
+
142
+struct mc_member_st {
143
+	__u8 mgid[16];
144
+	__u8 port_gid[16];
145
+	__u32 q_key;
146
+	__u32 combined1;
147
+			/*__u32	tclass:8;
148
+			__u32 mtu:6;
149
+			__u32 mtu_selector:2;
150
+			__u32 mlid:16;*/
151
+	__u32 combined2;
152
+			/*__u32 packet_liftime:6;
153
+			__u32 packet_liftime_selector:2;
154
+			__u32 rate:6;
155
+			__u32 rate_selector:2;
156
+			__u32 pkey:16;*/
157
+	__u32 combined3;
158
+			/*__u32 hop_limit:8;
159
+			__u32 flow_label:20;
160
+			__u32 sl:4;*/
161
+	__u32 combined4;
162
+			/*__u32 r0:23;
163
+			__u32 proxy_join:1;
164
+			__u32 join_state:4;
165
+			__u32 scope:4;*/
166
+} __attribute__ ((packed));
167
+
168
+struct mc_member_mad_st {
169
+	struct ib_mad_hdr_st mad_hdr;
170
+	struct rmpp_hdr_st rmpp_hdr;
171
+	struct sa_header_st sa_hdr;
172
+	struct mc_member_st mc_member;
173
+} __attribute__ ((packed));
174
+
175
+union mc_member_mad_u {
176
+	struct mc_member_mad_st mc_member;
177
+	__u8 raw[256];
178
+} __attribute__ ((packed));
179
+
180
+struct pkey_tbl_st {
181
+	__u16 pkey_tbl[16][2];
182
+} __attribute__ ((packed));
183
+
184
+struct pkey_tbl_mad_st {
185
+	struct ib_mad_hdr_st mad_hdr;
186
+	__u32 mkey[2];
187
+	__u32 r1[8];
188
+	struct pkey_tbl_st pkey_tbl;
189
+} __attribute__ ((packed));
190
+
191
+union pkey_tbl_mad_u {
192
+	struct pkey_tbl_mad_st mad;
193
+	__u8 raw[256];
194
+} __attribute__ ((packed));
195
+
196
+struct path_record_st {
197
+	__u32 r0[2];
198
+	union ib_gid_u dgid;
199
+	union ib_gid_u sgid;
200
+	__u16 slid;
201
+	__u16 dlid;
202
+	__u32 combined1;
203
+			/*__u32	hop_limit:8;
204
+			__u32 flow_label:20;
205
+			__u32 r1:3;
206
+			__u32 raw_traffic:1;*/
207
+	__u32 combined2;
208
+			/*__u32 pkey:16;
209
+			__u32 numb_path:7;
210
+			__u32 reversible:1;
211
+			__u32 tclass:8;*/
212
+	__u32 combined3;
213
+			/*__u32 rate:6;
214
+			__u32 rate_selector:2;
215
+			__u32 mtu:6;
216
+			__u32 mtu_selector:2;
217
+			__u32 sl:4;
218
+			__u32 reserved:12;*/
219
+	__u32 combined4;
220
+			/*__u32 r2:16;
221
+			__u32 preference:8;
222
+			__u32 packet_lifetime:6;
223
+			__u32 packet_lifetime_selector:2;*/
224
+	__u32 r3;
225
+} __attribute__ ((packed));
226
+
227
+struct path_record_mad_st {
228
+	struct ib_mad_hdr_st mad_hdr;
229
+	struct rmpp_hdr_st rmpp_hdr;
230
+	struct sa_header_st sa_hdr;
231
+	struct path_record_st path_record;
232
+} __attribute__ ((packed));
233
+
234
+union path_record_mad_u {
235
+	struct path_record_mad_st mad;
236
+	__u8 raw[256];
237
+} __attribute__ ((packed));
238
+
239
+static int get_port_info(__u8 port, struct port_info_st *buf, __u16 * status);
240
+static int get_guid_info(__u16 * status);
241
+static int get_pkey_tbl(struct pkey_tbl_st *pkey_tbl, __u16 * status);
242
+static int join_mc_group(__u32 * qkey_p, __u16 * mlid_p, __u8 join);
243
+
244
+#endif				/* __mad_attrib_h_ */

+ 245
- 0
src/drivers/net/mlx_ipoib/mt23108.c Datei anzeigen

@@ -0,0 +1,245 @@
1
+/**************************************************************************
2
+Etherboot -  BOOTP/TFTP Bootstrap Program
3
+Skeleton NIC driver for Etherboot
4
+***************************************************************************/
5
+
6
+/*
7
+ * This program is free software; you can redistribute it and/or
8
+ * modify it under the terms of the GNU General Public License as
9
+ * published by the Free Software Foundation; either version 2, or (at
10
+ * your option) any later version.
11
+ */
12
+
13
+/* to get some global routines like printf */
14
+#include "etherboot.h"
15
+/* to get the interface to the body of the program */
16
+#include "nic.h"
17
+/* to get the PCI support functions, if this is a PCI NIC */
18
+#include "pci.h"
19
+/* to get the ISA support functions, if this is an ISA NIC */
20
+#include "isa.h"
21
+
22
+#include "mt_version.c"
23
+#include "mt23108_imp.c"
24
+
25
+/* NIC specific static variables go here */
26
+
27
+int prompt_key(int secs, unsigned char *ch_p)
28
+{
29
+	unsigned long tmo;
30
+	unsigned char ch;
31
+
32
+	for (tmo = currticks() + secs * TICKS_PER_SEC; currticks() < tmo;) {
33
+		if (iskey()) {
34
+			ch = getchar();
35
+			/* toupper does not work ... */
36
+			if (ch == 'v')
37
+				ch = 'V';
38
+			if (ch == 'i')
39
+				ch = 'I';
40
+			if ((ch=='V') || (ch=='I')) {
41
+				*ch_p = ch;
42
+				return 1;
43
+			}
44
+		}
45
+	}
46
+
47
+	return 0;
48
+}
49
+
50
+/**************************************************************************
51
+IRQ - handle interrupts
52
+***************************************************************************/
53
+static void tavor_irq(struct nic *nic, irq_action_t action)
54
+{
55
+	/* This routine is somewhat optional.  Etherboot itself
56
+	 * doesn't use interrupts, but they are required under some
57
+	 * circumstances when we're acting as a PXE stack.
58
+	 *
59
+	 * If you don't implement this routine, the only effect will
60
+	 * be that your driver cannot be used via Etherboot's UNDI
61
+	 * API.  This won't affect programs that use only the UDP
62
+	 * portion of the PXE API, such as pxelinux.
63
+	 */
64
+
65
+	if (0) {
66
+		nic = NULL;
67
+	}
68
+	switch (action) {
69
+	case DISABLE:
70
+	case ENABLE:
71
+		/* Set receive interrupt enabled/disabled state */
72
+		/*
73
+		   outb ( action == ENABLE ? IntrMaskEnabled : IntrMaskDisabled,
74
+		   nic->ioaddr + IntrMaskRegister );
75
+		 */
76
+		break;
77
+	case FORCE:
78
+		/* Force NIC to generate a receive interrupt */
79
+		/*
80
+		   outb ( ForceInterrupt, nic->ioaddr + IntrForceRegister );
81
+		 */
82
+		break;
83
+	}
84
+}
85
+
86
+/**************************************************************************
87
+POLL - Wait for a frame
88
+***************************************************************************/
89
+static int tavor_poll(struct nic *nic, int retrieve)
90
+{
91
+	/* Work out whether or not there's an ethernet packet ready to
92
+	 * read.  Return 0 if not.
93
+	 */
94
+	/* 
95
+	   if ( ! <packet_ready> ) return 0;
96
+	 */
97
+
98
+	/* retrieve==0 indicates that we are just checking for the
99
+	 * presence of a packet but don't want to read it just yet.
100
+	 */
101
+	/*
102
+	   if ( ! retrieve ) return 1;
103
+	 */
104
+
105
+	/* Copy data to nic->packet.  Data should include the
106
+	 * link-layer header (dest MAC, source MAC, type).
107
+	 * Store length of data in nic->packetlen.
108
+	 * Return true to indicate a packet has been read.
109
+	 */
110
+	/* 
111
+	   nic->packetlen = <packet_length>;
112
+	   memcpy ( nic->packet, <packet_data>, <packet_length> );
113
+	   return 1;
114
+	 */
115
+	unsigned int size;
116
+	int rc;
117
+	rc = poll_imp(nic, retrieve, &size);
118
+	if (rc) {
119
+		return 0;
120
+	}
121
+
122
+	if (size == 0) {
123
+		return 0;
124
+	}
125
+
126
+	nic->packetlen = size;
127
+
128
+	return 1;
129
+}
130
+
131
+/**************************************************************************
132
+TRANSMIT - Transmit a frame
133
+***************************************************************************/
134
+static void tavor_transmit(struct nic *nic, const char *dest,	/* Destination */
135
+			   unsigned int type,	/* Type */
136
+			   unsigned int size,	/* size */
137
+			   const char *packet)
138
+{				/* Packet */
139
+	int rc;
140
+
141
+	/* Transmit packet to dest MAC address.  You will need to
142
+	 * construct the link-layer header (dest MAC, source MAC,
143
+	 * type).
144
+	 */
145
+	if (nic) {
146
+		rc = transmit_imp(dest, type, packet, size);
147
+		if (rc)
148
+			eprintf("tranmit error");
149
+	}
150
+}
151
+
152
+/**************************************************************************
153
+DISABLE - Turn off ethernet interface
154
+***************************************************************************/
155
+static void tavor_disable(struct dev *dev)
156
+{
157
+	/* put the card in its initial state */
158
+	/* This function serves 3 purposes.
159
+	 * This disables DMA and interrupts so we don't receive
160
+	 *  unexpected packets or interrupts from the card after
161
+	 *  etherboot has finished. 
162
+	 * This frees resources so etherboot may use
163
+	 *  this driver on another interface
164
+	 * This allows etherboot to reinitialize the interface
165
+	 *  if something is something goes wrong.
166
+	 */
167
+	if (dev || 1) {		// ????
168
+		disable_imp();
169
+	}
170
+}
171
+
172
+/**************************************************************************
173
+PROBE - Look for an adapter, this routine's visible to the outside
174
+***************************************************************************/
175
+
176
+static int tavor_probe(struct dev *dev, struct pci_device *pci)
177
+{
178
+	struct nic *nic = (struct nic *)dev;
179
+	int rc;
180
+	unsigned char user_request;
181
+
182
+	if (pci->vendor != MELLANOX_VENDOR_ID) {
183
+		eprintf("");
184
+		return 0;
185
+	}
186
+
187
+	printf("\n");
188
+	printf("Mellanox Technologies LTD - Boot over IB implementaion\n");
189
+	printf("Build version = %s\n\n", build_revision);
190
+
191
+	verbose_messages = 0;
192
+        print_info = 0;
193
+	printf("Press within 3 seconds:\n");
194
+	printf("V - to increase verbosity\n");
195
+	printf("I - to print information\n");
196
+	if (prompt_key(3, &user_request)) {
197
+		if (user_request == 'V') {
198
+			printf("User selected verbose messages\n");
199
+			verbose_messages = 1;
200
+		}
201
+		else if (user_request == 'I') {
202
+			printf("User selected to print information\n");
203
+			print_info = 1;
204
+		}
205
+	}
206
+	printf("\n");
207
+
208
+	adjust_pci_device(pci);
209
+
210
+	nic->priv_data = NULL;
211
+	rc = probe_imp(pci, nic);
212
+
213
+	/* give the user a chance to look at the info */
214
+	if (print_info)
215
+		sleep(5);
216
+
217
+	if (!rc) {
218
+		/* store NIC parameters */
219
+		nic->ioaddr = pci->ioaddr & ~3;
220
+		nic->irqno = pci->irq;
221
+		/* point to NIC specific routines */
222
+		dev->disable = tavor_disable;
223
+		nic->poll = tavor_poll;
224
+		nic->transmit = tavor_transmit;
225
+		nic->irq = tavor_irq;
226
+
227
+		return 1;
228
+	}
229
+	/* else */
230
+	return 0;
231
+}
232
+
233
+static struct pci_id tavor_nics[] = {
234
+	PCI_ROM(0x15b3, 0x5a44, "MT23108", "MT23108 HCA driver"),
235
+	PCI_ROM(0x15b3, 0x6278, "MT25208", "MT25208 HCA driver"),
236
+};
237
+
238
+static struct pci_driver tavor_driver __pci_driver = {
239
+	.type = NIC_DRIVER,
240
+	.name = "MT23108/MT25208",
241
+	.probe = tavor_probe,
242
+	.ids = tavor_nics,
243
+	.id_count = sizeof(tavor_nics) / sizeof(tavor_nics[0]),
244
+	.class = 0,
245
+};

+ 543
- 0
src/drivers/net/mlx_ipoib/mt23108.h Datei anzeigen

@@ -0,0 +1,543 @@
1
+#ifndef __mt23108_h__
2
+#define __mt23108_h__
3
+
4
+#include "MT23108_PRM.h"
5
+#include "ib_mad.h"
6
+
7
+#define TAVOR_DEVICE_ID		0x5a44
8
+#define TAVOR_BRIDGE_DEVICE_ID 0x5a46
9
+#define ARTAVOR_DEVICE_ID	0x6278
10
+
11
+#define TAVOR_RESET_OFFSET 0xF0010
12
+
13
+/*
14
+ * Tavor specific command
15
+ *	Only coomands that are specific to Tavor
16
+ *  and used by the driver are listed here
17
+ */
18
+#define TAVOR_CMD_SYS_EN	0x1
19
+#define TAVOR_CMD_SYS_DIS	0x2
20
+
21
+#define TAVOR_CMD_WRITE_MGM		0x26
22
+#define TAVOR_CMD_MOD_STAT_CFG	0x34
23
+#define TAVOR_CMD_QUERY_DEV_LIM   0x003
24
+#define TAVOR_CMD_QUERY_FW		0x004
25
+
26
+/*
27
+ * Tavor specific event types
28
+ *	Only event types that are specific to Tavor
29
+ *  and are used by the driver are listed here
30
+ */
31
+#define TAVOR_IF_EV_TYPE_OVERRUN	0x0F
32
+
33
+/*
34
+ * EQ doorbel commands
35
+ */
36
+#define EQ_DBELL_CMD_INC_CONS_IDX 1	/* increment Consumer_indx by one */
37
+#define EQ_DBELL_CMD_ARM_EQ       2	/* Request notifcation for next event (Arm EQ) */
38
+#define EQ_DBELL_CMD_DISARM_CQ    3	/* Disarm CQ (CQ number is specified in EQ_param) */
39
+#define EQ_DBELL_CMD_SET_CONS_IDX 4	/* set Consumer_indx to value of EQ_param */
40
+#define EQ_DBELL_CMD_ALWAYS_ARM   5	/* move EQ to Always Armed state */
41
+
42
+/*
43
+ * CQ doorbel commands
44
+ */
45
+#define CQ_DBELL_CMD_INC_CONS_IDX 1
46
+#define CQ_DBELL_CMD_REQ_NOTIF_SOL_UNSOL 2
47
+#define CQ_DBELL_CMD_REQ_NOTIF_SOL 3
48
+#define CQ_DBELL_CMD_SET_CONS_IDX 4
49
+#define CQ_DBELL_CMD_REQ_NOTIF_MULT 5
50
+
51
+#define INPRM_BUF_SZ 0x200
52
+#define INPRM_BUF_ALIGN 16
53
+#define OUTPRM_BUF_SZ 0x200
54
+#define OUTPRM_BUF_ALIGN 16
55
+
56
+/*
57
+ *  sizes of parameter blocks used in certain
58
+ *	commands.
59
+ *  TODO: replace them with sizeof
60
+ *  operators of the appropriate structs
61
+ */
62
+#define SW2HW_MPT_IBUF_SZ	 MT_STRUCT_SIZE(tavorprm_mpt_st)
63
+#define SW2HW_EQ_IBUF_SZ	 MT_STRUCT_SIZE(tavorprm_eqc_st)
64
+#define INIT_IB_IBUF_SZ		 0x100
65
+#define SW2HW_CQ_IBUF_SZ	 0x40
66
+#define QPCTX_IBUF_SZ		 0x200
67
+
68
+#define EQN 0
69
+#define UAR_IDX 1
70
+
71
+#define QPC_OFFSET 0
72
+#define CQC_OFFSET (QPC_OFFSET + 0x100000)
73
+#define EQPC_OFFSET (CQC_OFFSET + 0x100000)
74
+#define EQC_OFFSET (EQPC_OFFSET + 0x100000)
75
+#define MC_BASE_OFFSET (EQC_OFFSET + 0x100000)
76
+#define MPT_BASE_OFFSET (MC_BASE_OFFSET + 0x100000)
77
+#define MTT_BASE_OFFSET (MPT_BASE_OFFSET + 0x100000)
78
+
79
+#define LOG2_QPS 7
80
+#define LOG2_CQS 8
81
+#define LOG2_EQS 6
82
+#define LOG2_MC_ENTRY 6		/* 8 QPs per group */
83
+#define LOG2_MC_GROUPS 3	/* 8 groups */
84
+#define LOG2_MPT_ENTRIES 5
85
+
86
+#define LOG2_EQ_SZ 5
87
+#define LOG2_CQ_SZ 5
88
+
89
+#define NUM_PORTS 2
90
+
91
+#define EQE_OWNER_SW 0
92
+#define EQE_OWNER_HW 1
93
+
94
+#define OWNER_HW 1
95
+#define OWNER_SW 0
96
+
97
+#define POST_RCV_OFFSET 0x18
98
+#define POST_SND_OFFSET 0x10
99
+#define CQ_DBELL_OFFSET 0x20
100
+#define EQ_DBELL_OFFSET 0x28
101
+
102
+#define CQE_ERROR_OPCODE 0xfe
103
+
104
+#define MAX_GATHER 1		/* max gather entries used in send */
105
+#define MAX_SCATTER 2
106
+
107
+#define LOG2_MADS_SND_CQ_SZ LOG2_CQ_SZ
108
+#define LOG2_MADS_RCV_CQ_SZ LOG2_CQ_SZ
109
+#define LOG2_IPOIB_SND_CQ_SZ LOG2_CQ_SZ
110
+#define LOG2_IPOIB_RCV_CQ_SZ LOG2_CQ_SZ
111
+
112
+#define NUM_MADS_SND_CQES (1<<LOG2_MADS_SND_CQ_SZ)
113
+#define NUM_MADS_RCV_CQES (1<<LOG2_MADS_RCV_CQ_SZ)
114
+#define NUM_IPOIB_SND_CQES (1<<LOG2_IPOIB_SND_CQ_SZ)
115
+#define NUM_IPOIB_RCV_CQES (1<<LOG2_IPOIB_RCV_CQ_SZ)
116
+
117
+#define NUM_MADS_RCV_WQES 3
118
+#define NUM_IPOIB_RCV_WQES 8
119
+
120
+#if NUM_MADS_RCV_WQES > NUM_IPOIB_RCV_WQES
121
+#define MAX_RCV_WQES NUM_MADS_RCV_WQES
122
+#else
123
+#define MAX_RCV_WQES NUM_IPOIB_RCV_WQES
124
+#endif
125
+
126
+#define NUM_MADS_SND_WQES 2
127
+#define NUM_IPOIB_SND_WQES 2
128
+
129
+#if NUM_MADS_SND_WQES > NUM_IPOIB_SND_WQES
130
+#define MAX_SND_WQES NUM_MADS_SND_WQES
131
+#else
132
+#define MAX_SND_WQES NUM_IPOIB_SND_WQES
133
+#endif
134
+
135
+struct ib_buffers_st {
136
+	__u8 send_mad_buf[NUM_MADS_SND_WQES][MAD_BUF_SZ];
137
+	__u8 rcv_mad_buf[NUM_MADS_RCV_WQES][MAD_BUF_SZ + GRH_SIZE];
138
+	__u8 ipoib_rcv_buf[NUM_IPOIB_RCV_WQES][IPOIB_RCV_BUF_SZ + GRH_SIZE];
139
+	__u8 ipoib_rcv_grh_buf[NUM_IPOIB_RCV_WQES][IPOIB_RCV_BUF_SZ];
140
+	__u8 send_ipoib_buf[NUM_IPOIB_SND_WQES][IPOIB_SND_BUF_SZ];
141
+};
142
+
143
+struct pcidev {
144
+	unsigned long bar[6];
145
+	__u32 dev_config_space[64];
146
+	struct pci_device *dev;
147
+	__u8 bus;
148
+	__u8 devfn;
149
+};
150
+
151
+struct dev_pci_struct {
152
+	struct pcidev dev;
153
+	struct pcidev br;
154
+	void *cr_space;
155
+	void *uar;
156
+};
157
+
158
+struct eq_st {
159
+	__u8 eqn;
160
+	__u32 cons_idx;
161
+	__u32 eq_size;
162
+	struct eqe_t *eq_buf;
163
+};
164
+
165
+struct udav_st {
166
+	union ud_av_u *av_array;
167
+	__u8 udav_next_free;
168
+};
169
+
170
+#if 0
171
+struct udavtable_memory_parameters_st {
172
+	__u32 lkey;
173
+	__u32 pd:24;
174
+	__u32 r0:5;
175
+	__u32 xlation_en:1;
176
+	__u32 r1:2;
177
+} __attribute__ ((packed));
178
+
179
+struct multicast_parameters_st {
180
+	__u32 mc_base_addr_h;
181
+	__u32 mc_base_addr_l;
182
+	__u32 r0[2];
183
+	__u32 log_mc_table_entry_sz:16;
184
+	__u32 r1:16;
185
+	__u32 mc_table_hash_sz:17;
186
+	__u32 r2:15;
187
+	__u32 log_mc_table_sz:5;
188
+	__u32 r3:19;
189
+	__u32 mc_hash_fn:3;
190
+	__u32 r4:5;
191
+	__u32 r5;
192
+} __attribute__ ((packed));
193
+
194
+struct tpt_parameters_st {
195
+	__u32 mpt_base_addr_h;
196
+	__u32 mpt_base_addr_l;
197
+
198
+	__u32 log_mpt_sz:6;
199
+	__u32 r0:2;
200
+	__u32 pfto:5;
201
+	__u32 r1:3;
202
+	__u32 mtt_segment_size:3;
203
+	__u32 r2:13;
204
+
205
+	__u32 mtt_version:8;
206
+	__u32 r3:24;
207
+
208
+	__u32 mtt_base_addr_h;
209
+	__u32 mtt_base_addr_l;
210
+	__u32 r4[2];
211
+} __attribute__ ((packed));
212
+
213
+struct uar_parameters_st {
214
+	__u32 uar_base_addr_h;
215
+	__u32 uar_base_addr_l;	/* 12 lsbs must be zero */
216
+	__u32 uar_page_sz:8;
217
+	__u32 r1:24;
218
+	__u32 r2;
219
+	__u32 uar_scratch_base_addr_h;
220
+	__u32 uar_scratch_base_addr_l;
221
+	__u32 r3[3];
222
+} __attribute__ ((packed));
223
+
224
+struct comp_event_data_st {
225
+	__u32 cqn:24;
226
+	__u32 r1:8;
227
+	__u32 r2[5];
228
+} __attribute__ ((packed));
229
+
230
+struct qp_event_data_st {
231
+	__u32 qpn_een:24;
232
+	__u32 r1:8;
233
+	__u32 r2;
234
+	__u32 r3:28;
235
+	__u32 e_q:1;
236
+	__u32 r4:3;
237
+	__u32 r5[3];
238
+} __attribute__ ((packed));
239
+
240
+struct port_state_change_event_data_st {
241
+	__u32 r0[2];
242
+	__u32 r1:28;
243
+	__u32 port:2;
244
+	__u32 r2:2;
245
+	__u32 r3[3];
246
+} __attribute__ ((packed));
247
+#endif
248
+
249
+struct eqe_t {
250
+	__u8 raw[MT_STRUCT_SIZE(tavorprm_event_queue_entry_st)];
251
+} __attribute__ ((packed));
252
+
253
+enum qp_state_e {
254
+	QP_STATE_RST = 0,
255
+	QP_STATE_INIT = 1,
256
+	QP_STATE_RTR = 2,
257
+	QP_STATE_RTS = 3,
258
+	QP_STATE_SQEr = 4,
259
+	QP_STATE_SQD = 5,
260
+	QP_STATE_ERR = 6,
261
+	QP_STATE_SQDING = 7,
262
+	QP_STATE_SUSPEND = 9
263
+};
264
+
265
+struct memory_pointer_st {
266
+	__u32 byte_count;
267
+	__u32 lkey;
268
+	__u32 local_addr_h;
269
+	__u32 local_addr_l;
270
+} __attribute__ ((packed));
271
+
272
+/* receive wqe descriptor */
273
+struct recv_wqe_st {
274
+	/* part referenced by hardware */
275
+	__u8 next[MT_STRUCT_SIZE(wqe_segment_next_st)];
276
+	__u8 control[MT_STRUCT_SIZE(wqe_segment_ctrl_recv_st)];
277
+	struct memory_pointer_st mpointer[MAX_SCATTER];
278
+} __attribute__ ((packed));
279
+
280
+struct recv_wqe_cont_st {
281
+	struct recv_wqe_st wqe;
282
+
283
+	struct udqp_st *qp;	/* qp this wqe is used with */
284
+} __attribute__ ((packed));
285
+
286
+#define RECV_WQE_U_ALIGN 64
287
+union recv_wqe_u {
288
+	__u8 align[(sizeof(struct recv_wqe_cont_st) + RECV_WQE_U_ALIGN - 1) & (~(RECV_WQE_U_ALIGN - 1))];	/* this ensures proper alignment */
289
+	struct recv_wqe_st wqe;
290
+	struct recv_wqe_cont_st wqe_cont;
291
+} __attribute__ ((packed));
292
+
293
+struct recv_doorbell_st {
294
+	__u8 raw[MT_STRUCT_SIZE(tavorprm_receive_doorbell_st)];
295
+} __attribute__ ((packed));
296
+
297
+struct send_doorbell_st {
298
+	__u8 raw[MT_STRUCT_SIZE(tavorprm_send_doorbell_st)];
299
+} __attribute__ ((packed));
300
+
301
+struct next_control_seg_st {
302
+	__u8 next[MT_STRUCT_SIZE(wqe_segment_next_st)];
303
+	__u8 control[MT_STRUCT_SIZE(wqe_segment_ctrl_send_st)];
304
+} __attribute__ ((packed));
305
+
306
+struct ud_seg_st {
307
+	__u32 r1;
308
+	__u32 lkey;
309
+	__u32 av_add_h;
310
+	__u32 av_add_l;
311
+	__u32 r2[4];
312
+	__u32 dest_qp;
313
+	__u32 qkey;
314
+	__u32 r3[2];
315
+} __attribute__ ((packed));
316
+
317
+struct ud_send_wqe_st {
318
+	struct next_control_seg_st next;
319
+	struct ud_seg_st udseg;
320
+	struct memory_pointer_st mpointer[MAX_GATHER];
321
+} __attribute__ ((packed));
322
+
323
+struct ude_send_wqe_cont_st {
324
+	struct ud_send_wqe_st wqe;
325
+
326
+	struct udqp_st *qp;	/* qp this wqe is used with */
327
+} __attribute__ ((packed));
328
+
329
+#define UD_SEND_WQE_U_ALIGN 64
330
+union ud_send_wqe_u {
331
+	__u8 align[(sizeof(struct ude_send_wqe_cont_st) + UD_SEND_WQE_U_ALIGN -
332
+		    1) & (~(UD_SEND_WQE_U_ALIGN - 1))];
333
+	struct ude_send_wqe_cont_st wqe_cont;
334
+	struct ud_send_wqe_st wqe;
335
+} __attribute__ ((packed));
336
+
337
+#define ADDRESS_VECTOR_ST_ALIGN 64
338
+struct address_vector_st {
339
+	__u8 raw[MT_STRUCT_SIZE(tavorprm_ud_address_vector_st)];
340
+} __attribute__ ((packed));
341
+
342
+struct ud_av_st {
343
+	struct address_vector_st av;
344
+	__u32 dest_qp;		/* destination qpn */
345
+	__u8 next_free;
346
+} __attribute__ ((packed));
347
+
348
+union ud_av_u {
349
+	__u8 raw[(sizeof(struct ud_av_st) + ADDRESS_VECTOR_ST_ALIGN -
350
+		  1) & (~(ADDRESS_VECTOR_ST_ALIGN - 1))];
351
+	struct ud_av_st ud_av;
352
+} __attribute__ ((packed));
353
+
354
+union cqe_st {
355
+	__u8 good_cqe[MT_STRUCT_SIZE(tavorprm_completion_queue_entry_st)];
356
+	__u8 error_cqe[MT_STRUCT_SIZE(tavorprm_completion_with_error_st)];
357
+} __attribute__ ((packed));
358
+
359
+struct address_path_st {
360
+	__u8 raw[MT_STRUCT_SIZE(tavorprm_address_path_st)];
361
+};
362
+
363
+struct qp_ee_ctx_t {
364
+	__u8 raw[MT_STRUCT_SIZE(tavorprm_queue_pair_ee_context_entry_st)];
365
+} __attribute__ ((packed));
366
+
367
+struct qp_ee_state_tarnisition_st {
368
+	__u32 opt_param_mask;
369
+	__u32 r1;
370
+	struct qp_ee_ctx_t ctx;
371
+	__u32 r2[62];
372
+} __attribute__ ((packed));
373
+
374
+struct eq_dbell_st {
375
+	__u8 raw[MT_STRUCT_SIZE(tavorprm_eq_cmd_doorbell_st)];
376
+} __attribute__ ((packed));
377
+
378
+struct cq_dbell_st {
379
+	__u8 raw[MT_STRUCT_SIZE(tavorprm_cq_cmd_doorbell_st)];
380
+} __attribute__ ((packed));
381
+
382
+struct mad_ifc_inprm_st {
383
+	union mad_u mad;
384
+} __attribute__ ((packed));
385
+
386
+struct wqe_buf_st {
387
+	struct ud_send_wqe_st *sndq;
388
+	struct recv_wqe_st *rcvq;
389
+};
390
+
391
+struct mad_buffer_st {
392
+	void *buf;		/* pointer to a 256 byte buffer */
393
+	__u8 owner;		/* sw or hw ownership BUF_OWNER_SW or BUF_OWNER_HW */
394
+};
395
+
396
+struct rcv_buf_st {
397
+	void *buf;
398
+	__u8 busy;
399
+};
400
+
401
+struct ib_eqe_st {
402
+	__u8 event_type;
403
+	__u32 cqn;
404
+};
405
+
406
+struct cq_st {
407
+	__u32 cqn;
408
+	union cqe_st *cq_buf;
409
+	__u32 cons_idx;
410
+	__u8 num_cqes;
411
+};
412
+
413
+struct udqp_st {
414
+	/* cq used by this QP */
415
+	struct cq_st snd_cq;
416
+	struct cq_st rcv_cq;
417
+
418
+	/* QP related data */
419
+	__u32 qpn;		/* QP number */
420
+
421
+	__u32 qkey;
422
+
423
+	__u8 recv_wqe_cur_free;
424
+	__u8 recv_wqe_alloc_idx;
425
+	__u8 max_recv_wqes;
426
+	void *rcv_bufs[MAX_RCV_WQES];
427
+	union recv_wqe_u *rcv_wq;	/* receive work queue */
428
+	struct recv_wqe_st *last_posted_rcv_wqe;
429
+
430
+	__u8 snd_wqe_cur_free;
431
+	__u8 snd_wqe_alloc_idx;
432
+	__u8 max_snd_wqes;
433
+	void *snd_bufs[MAX_SND_WQES];
434
+	__u16 send_buf_sz;
435
+	__u16 rcv_buf_sz;
436
+	union ud_send_wqe_u *snd_wq;	/* send work queue */
437
+	struct ud_send_wqe_st *last_posted_snd_wqe;
438
+};
439
+
440
+struct device_ib_data_st {
441
+	__u32 mkey;
442
+	__u32 pd;
443
+	__u8 port;
444
+	__u32 qkey;
445
+	struct eq_st eq;
446
+	struct udav_st udav;
447
+	struct udqp_st mads_qp;
448
+	struct udqp_st ipoib_qp;
449
+	void *error_buf_addr;
450
+	__u32 error_buf_size;
451
+};
452
+
453
+
454
+
455
+struct query_fw_st {
456
+	__u16 fw_rev_major;
457
+	__u16 fw_rev_minor;
458
+	__u16 fw_rev_subminor;
459
+	__u32 error_buf_start_h;
460
+	__u32 error_buf_start_l;
461
+	__u32 error_buf_size;
462
+};
463
+
464
+
465
+struct dev_lim_st {
466
+	__u8 log2_rsvd_qps;
467
+	__u16 qpc_entry_sz;
468
+
469
+	__u8 log2_rsvd_srqs;
470
+	__u16 srq_entry_sz;
471
+
472
+	__u8 log2_rsvd_ees;
473
+	__u16 eec_entry_sz;
474
+
475
+	__u8 log2_rsvd_cqs;
476
+	__u16 cqc_entry_sz;
477
+
478
+	__u8 log2_rsvd_mtts;
479
+	__u16 mtt_entry_sz;
480
+
481
+	__u8 log2_rsvd_mrws;
482
+	__u16 mpt_entry_sz;
483
+
484
+	__u16 eqc_entry_sz;
485
+};
486
+
487
+struct init_hca_st {
488
+	__u32 qpc_base_addr_h;
489
+	__u32 qpc_base_addr_l;
490
+	__u8 log_num_of_qp;
491
+
492
+	__u32 eec_base_addr_h;
493
+	__u32 eec_base_addr_l;
494
+	__u8 log_num_of_ee;
495
+
496
+	__u32 srqc_base_addr_h;
497
+	__u32 srqc_base_addr_l;
498
+	__u8 log_num_of_srq;
499
+
500
+	__u32 cqc_base_addr_h;
501
+	__u32 cqc_base_addr_l;
502
+	__u8 log_num_of_cq;
503
+
504
+	__u32 eqpc_base_addr_h;
505
+	__u32 eqpc_base_addr_l;
506
+
507
+	__u32 eeec_base_addr_h;
508
+	__u32 eeec_base_addr_l;
509
+
510
+	__u32 eqc_base_addr_h;
511
+	__u32 eqc_base_addr_l;
512
+	__u8 log_num_of_eq;
513
+
514
+	__u32 rdb_base_addr_h;
515
+	__u32 rdb_base_addr_l;
516
+
517
+	__u32 mc_base_addr_h;
518
+	__u32 mc_base_addr_l;
519
+	__u16 log_mc_table_entry_sz;
520
+	__u32 mc_table_hash_sz;
521
+	__u8 log_mc_table_sz;
522
+
523
+	__u32 mpt_base_addr_h;
524
+	__u32 mpt_base_addr_l;
525
+	__u8 log_mpt_sz;
526
+	__u32 mtt_base_addr_h;
527
+	__u32 mtt_base_addr_l;
528
+	__u8 log_max_uars;
529
+};
530
+
531
+static int create_udqp(struct udqp_st *qp);
532
+static int destroy_udqp(struct udqp_st *qp);
533
+static void *get_send_wqe_buf(void *wqe, __u8 index);
534
+static void *get_rcv_wqe_buf(void *wqe, __u8 index);
535
+
536
+static struct recv_wqe_st *alloc_rcv_wqe(struct udqp_st *qp);
537
+static int free_wqe(void *wqe);
538
+static int poll_cq(void *cqh, union cqe_st *cqe_p, __u8 * num_cqes);
539
+static int poll_eq(struct ib_eqe_st *ib_eqe_p, __u8 * num_eqes);
540
+static int post_rcv_buf(struct udqp_st *qp, struct recv_wqe_st *rcv_wqe);
541
+static __u32 dev_get_qpn(void *qph);
542
+
543
+#endif				/* __mt23108_h__ */

+ 230
- 0
src/drivers/net/mlx_ipoib/mt23108_imp.c Datei anzeigen

@@ -0,0 +1,230 @@
1
+typedef uint32_t __u32;
2
+typedef uint16_t __u16;
3
+typedef uint8_t __u8;
4
+
5
+static int verbose_messages=0;
6
+static int print_info=0;
7
+static int fatal_condition=0;
8
+static int fw_fatal;
9
+
10
+#define tprintf(fmt, a...) \
11
+		 do {    \
12
+			if ( verbose_messages ) { \
13
+				printf("%s:%d: " fmt "\n", __func__, __LINE__,  ##a); \
14
+			} \
15
+		 } \
16
+		 while(0)
17
+
18
+#define eprintf(fmt, a...) \
19
+		 printf("%s:%d: " fmt "\n", __func__, __LINE__,  ##a)
20
+
21
+static void cpu_to_be_buf(void *buf, int size)
22
+{
23
+	int dw_sz = size >> 2, i;
24
+
25
+	for (i = 0; i < dw_sz; ++i) {
26
+		((__u32 *) buf)[i] = cpu_to_be32(((__u32 *) buf)[i]);
27
+	}
28
+}
29
+
30
+static void be_to_cpu_buf(void *buf, int size)
31
+{
32
+	int dw_sz = size >> 2, i;
33
+	u32 *p = buf;
34
+
35
+	for (i = 0; i < dw_sz; ++i) {
36
+		p[i] = be32_to_cpu(p[i]);
37
+	}
38
+}
39
+
40
+#include "timer.h"
41
+#include "cmdif_mt23108.c"
42
+#include "cmdif_comm.c"
43
+#include "ib_mt23108.c"
44
+#include "ib_mad.c"
45
+#include "ib_driver.c"
46
+#include "ipoib.c"
47
+
48
+static int probe_imp(struct pci_device *pci, struct nic *nic)
49
+{
50
+	int rc;
51
+
52
+	if (0 && nic) {		/* just to supress warning */
53
+		return 0;
54
+	}
55
+
56
+	fatal_condition= 0;
57
+	fw_fatal= 0;
58
+
59
+	tprintf("");
60
+	rc = ipoib_init(pci);
61
+	if (rc)
62
+		return rc;
63
+
64
+	tprintf("");
65
+
66
+	return rc;
67
+}
68
+
69
+static int disable_imp(void)
70
+{
71
+	int rc;
72
+
73
+	rc = ipoib_close(fw_fatal);
74
+
75
+	return rc;
76
+}
77
+
78
+static int transmit_imp(const char *dest,	/* Destination */
79
+			unsigned int type,	/* Type */
80
+			const char *packet,	/* Packet */
81
+			unsigned int size)
82
+{				/* size */
83
+	int rc;
84
+
85
+	if (fatal_condition) {
86
+		/* since the transmit function does not return a value
87
+		   we return success but do nothing to suppress error messages */
88
+		return 0;
89
+	}
90
+
91
+	rc = ipoib_send_packet(dest, type, packet, size);
92
+	if (rc) {
93
+		printf("*** ERROR IN SEND FLOW ***\n");
94
+		printf("restarting Etherboot\n");
95
+		sleep(1);
96
+		longjmp(restart_etherboot, -1);
97
+		/* we should not be here ... */
98
+		return -1; 
99
+	}
100
+
101
+	return rc;
102
+}
103
+
104
+static void hd(void *where, int n)
105
+{
106
+	int i;
107
+
108
+	while (n > 0) {
109
+		printf("%X ", where);
110
+		for (i = 0; i < ((n > 16) ? 16 : n); i++)
111
+			printf(" %hhX", ((char *)where)[i]);
112
+		printf("\n");
113
+		n -= 16;
114
+		where += 16;
115
+	}
116
+}
117
+
118
+static int poll_imp(struct nic *nic, int retrieve, unsigned int *size_p)
119
+{
120
+	static char packet[2048];
121
+	static char *last_packet_p = NULL;
122
+	static unsigned long last_packet_size;
123
+	char *packet_p;
124
+	const int eth_header_len = 14;
125
+	unsigned int packet_len;
126
+	int is_bcast = 0;
127
+	__u16 prot, *ptr;
128
+	int rc;
129
+
130
+	if (0 && nic) {		/* just to supress warning */
131
+		return -1;
132
+	}
133
+
134
+	if (fatal_condition) {
135
+		*size_p = 0;
136
+		return 0;
137
+	}
138
+
139
+	if (poll_error_buf()) {
140
+		fatal_condition= 1;
141
+		fw_fatal= 1;
142
+		printf("\n *** DEVICE FATAL ERROR ***\n");
143
+		goto fatal_handling;
144
+	}
145
+	else if (drain_eq()) {
146
+		fatal_condition= 1;
147
+		printf("\n *** FATAL ERROR ***\n");
148
+		goto fatal_handling;
149
+	}
150
+
151
+
152
+	if (retrieve) {
153
+		/* we actually want to read the packet */
154
+		if (last_packet_p) {
155
+			eprintf("");
156
+			/* there is already a packet that was previously read */
157
+			memcpy(nic->packet, last_packet_p, last_packet_size);
158
+			*size_p = last_packet_size;
159
+			last_packet_p = NULL;
160
+			return 0;
161
+		}
162
+		packet_p = nic->packet;
163
+	} else {
164
+		/* we don't want to read the packet,
165
+		   just know if there is one. so we
166
+		   read the packet to a local buffer and
167
+		   we will return that buffer when the ip layer wants
168
+		   another packet */
169
+		if (last_packet_p) {
170
+			/* there is already a packet that
171
+			   was not consumend */
172
+			eprintf("overflow receive packets");
173
+			return -1;
174
+		}
175
+		packet_p = packet;
176
+	}
177
+
178
+	rc = ipoib_read_packet(&prot, packet_p + eth_header_len, &packet_len,
179
+			       &is_bcast);
180
+	if (rc) {
181
+		printf("*** FATAL IN RECEIVE FLOW ****\n");
182
+		goto fatal_handling;
183
+	}
184
+
185
+	if (packet_len == 0) {
186
+		*size_p = 0;
187
+		return 0;
188
+	}
189
+
190
+	if (is_bcast) {
191
+		int i;
192
+		for (i = 0; i < 6; ++i) {
193
+			packet_p[i] = 0xff;
194
+		}
195
+	} else {
196
+		packet_p[0] = MLX_ETH_BYTE0;
197
+		packet_p[1] = MLX_ETH_BYTE1;
198
+		packet_p[2] = MLX_ETH_BYTE2;
199
+		packet_p[3] = 0;
200
+		packet_p[4] = 0;
201
+		packet_p[5] = 0;
202
+	}
203
+
204
+	memset(packet_p + 6, 0, 6);
205
+
206
+	ptr = (__u16 *) (packet_p + 12);
207
+	*ptr = htons(prot);
208
+
209
+	if (!retrieve) {
210
+		last_packet_p = packet;
211
+		last_packet_size = packet_len + eth_header_len;
212
+		*size_p = 0;
213
+	}
214
+
215
+	*size_p = packet_len + eth_header_len;
216
+	tprintf("packet size=%d, prot=%x\n", *size_p, prot);
217
+	if (0) {
218
+		hd(nic->packet, 42);
219
+	}
220
+
221
+	return 0;
222
+
223
+fatal_handling:
224
+	printf("restarting Etherboot\n");
225
+	sleep(1);
226
+	longjmp(restart_etherboot, -1);
227
+	/* we should not be here ... */
228
+	return -1; 
229
+	
230
+}

+ 245
- 0
src/drivers/net/mlx_ipoib/mt25218.c Datei anzeigen

@@ -0,0 +1,245 @@
1
+/**************************************************************************
2
+Etherboot -  BOOTP/TFTP Bootstrap Program
3
+Skeleton NIC driver for Etherboot
4
+***************************************************************************/
5
+
6
+/*
7
+ * This program is free software; you can redistribute it and/or
8
+ * modify it under the terms of the GNU General Public License as
9
+ * published by the Free Software Foundation; either version 2, or (at
10
+ * your option) any later version.
11
+ */
12
+
13
+/* to get some global routines like printf */
14
+#include "etherboot.h"
15
+/* to get the interface to the body of the program */
16
+#include "nic.h"
17
+/* to get the PCI support functions, if this is a PCI NIC */
18
+#include "pci.h"
19
+/* to get the ISA support functions, if this is an ISA NIC */
20
+#include "isa.h"
21
+
22
+#include "mt_version.c"
23
+#include "mt25218_imp.c"
24
+
25
+/* NIC specific static variables go here */
26
+
27
+int prompt_key(int secs, unsigned char *ch_p)
28
+{
29
+	unsigned long tmo;
30
+	unsigned char ch;
31
+
32
+	for (tmo = currticks() + secs * TICKS_PER_SEC; currticks() < tmo;) {
33
+		if (iskey()) {
34
+			ch = getchar();
35
+			/* toupper does not work ... */
36
+			if (ch == 'v')
37
+				ch = 'V';
38
+			if (ch == 'i')
39
+				ch = 'I';
40
+			if ((ch=='V') || (ch=='I')) {
41
+				*ch_p = ch;
42
+				return 1;
43
+			}
44
+		}
45
+	}
46
+
47
+	return 0;
48
+}
49
+
50
+/**************************************************************************
51
+IRQ - handle interrupts
52
+***************************************************************************/
53
+static void mt25218_irq(struct nic *nic, irq_action_t action)
54
+{
55
+	/* This routine is somewhat optional.  Etherboot itself
56
+	 * doesn't use interrupts, but they are required under some
57
+	 * circumstances when we're acting as a PXE stack.
58
+	 *
59
+	 * If you don't implement this routine, the only effect will
60
+	 * be that your driver cannot be used via Etherboot's UNDI
61
+	 * API.  This won't affect programs that use only the UDP
62
+	 * portion of the PXE API, such as pxelinux.
63
+	 */
64
+
65
+	if (0) {
66
+		nic = NULL;
67
+	}
68
+	switch (action) {
69
+	case DISABLE:
70
+	case ENABLE:
71
+		/* Set receive interrupt enabled/disabled state */
72
+		/*
73
+		   outb ( action == ENABLE ? IntrMaskEnabled : IntrMaskDisabled,
74
+		   nic->ioaddr + IntrMaskRegister );
75
+		 */
76
+		break;
77
+	case FORCE:
78
+		/* Force NIC to generate a receive interrupt */
79
+		/*
80
+		   outb ( ForceInterrupt, nic->ioaddr + IntrForceRegister );
81
+		 */
82
+		break;
83
+	}
84
+}
85
+
86
+/**************************************************************************
87
+POLL - Wait for a frame
88
+***************************************************************************/
89
+static int mt25218_poll(struct nic *nic, int retrieve)
90
+{
91
+	/* Work out whether or not there's an ethernet packet ready to
92
+	 * read.  Return 0 if not.
93
+	 */
94
+	/* 
95
+	   if ( ! <packet_ready> ) return 0;
96
+	 */
97
+
98
+	/* retrieve==0 indicates that we are just checking for the
99
+	 * presence of a packet but don't want to read it just yet.
100
+	 */
101
+	/*
102
+	   if ( ! retrieve ) return 1;
103
+	 */
104
+
105
+	/* Copy data to nic->packet.  Data should include the
106
+	 * link-layer header (dest MAC, source MAC, type).
107
+	 * Store length of data in nic->packetlen.
108
+	 * Return true to indicate a packet has been read.
109
+	 */
110
+	/* 
111
+	   nic->packetlen = <packet_length>;
112
+	   memcpy ( nic->packet, <packet_data>, <packet_length> );
113
+	   return 1;
114
+	 */
115
+	unsigned int size;
116
+	int rc;
117
+	rc = poll_imp(nic, retrieve, &size);
118
+	if (rc) {
119
+		return 0;
120
+	}
121
+
122
+	if (size == 0) {
123
+		return 0;
124
+	}
125
+
126
+	nic->packetlen = size;
127
+
128
+	return 1;
129
+}
130
+
131
+/**************************************************************************
132
+TRANSMIT - Transmit a frame
133
+***************************************************************************/
134
+static void mt25218_transmit(struct nic *nic, const char *dest,	/* Destination */
135
+			     unsigned int type,	/* Type */
136
+			     unsigned int size,	/* size */
137
+			     const char *packet)
138
+{				/* Packet */
139
+	int rc;
140
+
141
+	/* Transmit packet to dest MAC address.  You will need to
142
+	 * construct the link-layer header (dest MAC, source MAC,
143
+	 * type).
144
+	 */
145
+	if (nic) {
146
+		rc = transmit_imp(dest, type, packet, size);
147
+		if (rc)
148
+			eprintf("tranmit error");
149
+	}
150
+}
151
+
152
+/**************************************************************************
153
+DISABLE - Turn off ethernet interface
154
+***************************************************************************/
155
+static void mt25218_disable(struct dev *dev)
156
+{
157
+	/* put the card in its initial state */
158
+	/* This function serves 3 purposes.
159
+	 * This disables DMA and interrupts so we don't receive
160
+	 *  unexpected packets or interrupts from the card after
161
+	 *  etherboot has finished. 
162
+	 * This frees resources so etherboot may use
163
+	 *  this driver on another interface
164
+	 * This allows etherboot to reinitialize the interface
165
+	 *  if something is something goes wrong.
166
+	 */
167
+	if (dev || 1) {		// ????
168
+		disable_imp();
169
+	}
170
+}
171
+
172
+/**************************************************************************
173
+PROBE - Look for an adapter, this routine's visible to the outside
174
+***************************************************************************/
175
+
176
+static int mt25218_probe(struct dev *dev, struct pci_device *pci)
177
+{
178
+	struct nic *nic = (struct nic *)dev;
179
+	int rc;
180
+	unsigned char user_request;
181
+
182
+	if (pci->vendor != MELLANOX_VENDOR_ID) {
183
+		eprintf("");
184
+		return 0;
185
+	}
186
+
187
+	printf("\n");
188
+	printf("Mellanox Technologies LTD - Boot over IB implementaion\n");
189
+	printf("Build version = %s\n\n", build_revision);
190
+
191
+	verbose_messages = 0;
192
+        print_info = 0;
193
+	printf("Press within 3 seconds:\n");
194
+	printf("V - to increase verbosity\n");
195
+	printf("I - to print information\n");
196
+	if (prompt_key(3, &user_request)) {
197
+		if (user_request == 'V') {
198
+			printf("User selected verbose messages\n");
199
+			verbose_messages = 1;
200
+		}
201
+		else if (user_request == 'I') {
202
+			printf("User selected to print information\n");
203
+			print_info = 1;
204
+		}
205
+	}
206
+	printf("\n");
207
+
208
+	adjust_pci_device(pci);
209
+
210
+	nic->priv_data = NULL;
211
+	rc = probe_imp(pci, nic);
212
+
213
+	/* give the user a chance to look at the info */
214
+	if (print_info)
215
+		sleep(5);
216
+
217
+	if (!rc) {
218
+		/* store NIC parameters */
219
+		nic->ioaddr = pci->ioaddr & ~3;
220
+		nic->irqno = pci->irq;
221
+		/* point to NIC specific routines */
222
+		dev->disable = mt25218_disable;
223
+		nic->poll = mt25218_poll;
224
+		nic->transmit = mt25218_transmit;
225
+		nic->irq = mt25218_irq;
226
+
227
+		return 1;
228
+	}
229
+	/* else */
230
+	return 0;
231
+}
232
+
233
+static struct pci_id mt25218_nics[] = {
234
+	PCI_ROM(0x15b3, 0x6282, "MT25218", "MT25218 HCA driver"),
235
+	PCI_ROM(0x15b3, 0x6274, "MT25204", "MT25204 HCA driver"),
236
+};
237
+
238
+static struct pci_driver mt25218_driver __pci_driver = {
239
+	.type = NIC_DRIVER,
240
+	.name = "MT25218",
241
+	.probe = mt25218_probe,
242
+	.ids = mt25218_nics,
243
+	.id_count = sizeof(mt25218_nics) / sizeof(mt25218_nics[0]),
244
+	.class = 0,
245
+};

+ 546
- 0
src/drivers/net/mlx_ipoib/mt25218.h Datei anzeigen

@@ -0,0 +1,546 @@
1
+#ifndef __mt25218_h__
2
+#define __mt25218_h__
3
+
4
+#include "MT25218_PRM.h"
5
+#include "ib_mad.h"
6
+
7
+#define TAVOR_DEVICE_ID		0x5a44
8
+#define TAVOR_BRIDGE_DEVICE_ID 0x5a46
9
+#define ARTAVOR_DEVICE_ID	0x6278
10
+
11
+#define MEMFREE_RESET_OFFSET 0xF0010
12
+
13
+#define INVALID_WQE_LKEY 0x00000100
14
+
15
+/*
16
+ * memfree specific command
17
+ *	
18
+ */
19
+#define MEMFREE_CMD_QUERY_ADAPTER	0x006
20
+#define MEMFREE_CMD_WRITE_MGM		0x026
21
+#define MEMFREE_CMD_MOD_STAT_CFG	0x034
22
+#define MEMFREE_CMD_QUERY_FW		0x004
23
+#define MEMFREE_CMD_ENABLE_LAM		0xff8
24
+#define MEMFREE_CMD_MAP_FA			0xfff
25
+#define MEMFREE_CMD_UNMAP_FA		0xffe
26
+#define MEMFREE_CMD_RUN_FW			0xff6
27
+#define MEMFREE_CMD_SET_ICM_SIZE	0xffd
28
+#define MEMFREE_CMD_MAP_ICM_AUX		0xffc
29
+#define MEMFREE_CMD_MAP_ICM			0xffa
30
+#define MEMFREE_CMD_QUERY_DEV_LIM   0x003
31
+
32
+/*
33
+ * Tavor specific event types
34
+ *	Only event types that are specific to Tavor
35
+ *  and are used by the driver are listed here
36
+ */
37
+#define TAVOR_IF_EV_TYPE_OVERRUN	0x0F
38
+
39
+/*
40
+ * EQ doorbel commands
41
+ */
42
+#define EQ_DBELL_CMD_INC_CONS_IDX 1	/* increment Consumer_indx by one */
43
+#define EQ_DBELL_CMD_ARM_EQ       2	/* Request notifcation for next event (Arm EQ) */
44
+#define EQ_DBELL_CMD_DISARM_CQ    3	/* Disarm CQ (CQ number is specified in EQ_param) */
45
+#define EQ_DBELL_CMD_SET_CONS_IDX 4	/* set Consumer_indx to value of EQ_param */
46
+#define EQ_DBELL_CMD_ALWAYS_ARM   5	/* move EQ to Always Armed state */
47
+
48
+/*
49
+ * CQ doorbel commands
50
+ */
51
+#define CQ_DBELL_CMD_INC_CONS_IDX 1
52
+#define CQ_DBELL_CMD_REQ_NOTIF_SOL_UNSOL 2
53
+#define CQ_DBELL_CMD_REQ_NOTIF_SOL 3
54
+#define CQ_DBELL_CMD_SET_CONS_IDX 4
55
+#define CQ_DBELL_CMD_REQ_NOTIF_MULT 5
56
+
57
+#define INPRM_BUF_SZ 4096
58
+#define INPRM_BUF_ALIGN 4096
59
+#define OUTPRM_BUF_SZ 4096
60
+#define OUTPRM_BUF_ALIGN 4096
61
+
62
+/*
63
+ *  sizes of parameter blocks used in certain
64
+ *	commands.
65
+ *  TODO: replace them with sizeof
66
+ *  operators of the appropriate structs
67
+ */
68
+#define SW2HW_MPT_IBUF_SZ	 MT_STRUCT_SIZE(arbelprm_mpt_st)
69
+#define SW2HW_EQ_IBUF_SZ	 MT_STRUCT_SIZE(arbelprm_eqc_st)
70
+#define INIT_IB_IBUF_SZ		 MT_STRUCT_SIZE(arbelprm_init_ib_st)
71
+#define SW2HW_CQ_IBUF_SZ	 MT_STRUCT_SIZE(arbelprm_completion_queue_context_st)
72
+#define QPCTX_IBUF_SZ		 MT_STRUCT_SIZE(arbelprm_queue_pair_ee_context_entry_st)
73
+
74
+#define EQN 0
75
+#define UAR_IDX 1
76
+
77
+#define QPC_OFFSET 0
78
+#define CQC_OFFSET (QPC_OFFSET + 0x100000)
79
+#define EQPC_OFFSET (CQC_OFFSET + 0x100000)
80
+#define EQC_OFFSET (EQPC_OFFSET + 0x100000)
81
+#define MC_BASE_OFFSET (EQC_OFFSET + 0x100000)
82
+#define MPT_BASE_OFFSET (MC_BASE_OFFSET + 0x100000)
83
+#define MTT_BASE_OFFSET (MPT_BASE_OFFSET + 0x100000)
84
+
85
+#define LOG2_QPS 7
86
+#define LOG2_CQS 8
87
+#define LOG2_EQS 6
88
+#define LOG2_MC_ENTRY 6		/* 8 QPs per group */
89
+#define LOG2_MC_GROUPS 3	/* 8 groups */
90
+#define LOG2_MPT_ENTRIES 5
91
+
92
+#define LOG2_EQ_SZ 5
93
+#define LOG2_CQ_SZ 5
94
+
95
+#define NUM_PORTS 2
96
+
97
+#define EQE_OWNER_OFFSET 31
98
+#define EQE_OWNER_VAL_HW 0x80
99
+
100
+#define CQE_OWNER_OFFSET 31
101
+#define CQE_OWNER_VAL_HW 0x80
102
+
103
+#define POST_RCV_OFFSET 0x18
104
+#define POST_SND_OFFSET 0x10
105
+#define CQ_DBELL_OFFSET 0x20
106
+#define EQ_DBELL_OFFSET 0x28
107
+
108
+#define CQE_ERROR_OPCODE 0xfe
109
+
110
+#define OWNER_HW 1
111
+#define OWNER_SW 0
112
+
113
+#define MAX_GATHER 1		/* max gather entries used in send */
114
+#define MAX_SCATTER 2
115
+
116
+#define LOG2_MADS_SND_CQ_SZ LOG2_CQ_SZ
117
+#define LOG2_MADS_RCV_CQ_SZ LOG2_CQ_SZ
118
+#define LOG2_IPOIB_SND_CQ_SZ LOG2_CQ_SZ
119
+#define LOG2_IPOIB_RCV_CQ_SZ LOG2_CQ_SZ
120
+
121
+#define NUM_MADS_SND_CQES (1<<LOG2_MADS_SND_CQ_SZ)
122
+#define NUM_MADS_RCV_CQES (1<<LOG2_MADS_RCV_CQ_SZ)
123
+#define NUM_IPOIB_SND_CQES (1<<LOG2_IPOIB_SND_CQ_SZ)
124
+#define NUM_IPOIB_RCV_CQES (1<<LOG2_IPOIB_RCV_CQ_SZ)
125
+
126
+/* work queues must be 2^n size with n=0.. */
127
+#define NUM_MADS_RCV_WQES (1<<1)
128
+#define NUM_IPOIB_RCV_WQES (1<<1)
129
+
130
+#if NUM_MADS_RCV_WQES > NUM_IPOIB_RCV_WQES
131
+#define MAX_RCV_WQES NUM_MADS_RCV_WQES
132
+#else
133
+#define MAX_RCV_WQES NUM_IPOIB_RCV_WQES
134
+#endif
135
+
136
+#define NUM_MADS_SND_WQES (1<<1)
137
+#define NUM_IPOIB_SND_WQES (1<<1)
138
+
139
+#if NUM_MADS_SND_WQES > NUM_IPOIB_SND_WQES
140
+#define MAX_SND_WQES NUM_MADS_SND_WQES
141
+#else
142
+#define MAX_SND_WQES NUM_IPOIB_SND_WQES
143
+#endif
144
+
145
+/* uar context indexes */
146
+enum {
147
+	MADS_RCV_CQ_ARM_DB_IDX,
148
+	MADS_SND_CQ_ARM_DB_IDX,
149
+	IPOIB_RCV_CQ_ARM_DB_IDX,
150
+	IPOIB_SND_CQ_ARM_DB_IDX,
151
+	MADS_SND_QP_DB_IDX,
152
+	IPOIB_SND_QP_DB_IDX,
153
+	GROUP_SEP_IDX,
154
+	START_UNMAPPED_DB_IDX,
155
+	/* --------------------------
156
+	   unmapped doorbell records
157
+	   -------------------------- */
158
+	END_UNMAPPED_DB_IDX = 505,
159
+	MADS_RCV_QP_DB_IDX = 506,
160
+	IPOIB_RCV_QP_DB_IDX = 507,
161
+	MADS_RCV_CQ_CI_DB_IDX = 508,
162
+	MADS_SND_CQ_CI_DB_IDX = 509,
163
+	IPOIB_RCV_CQ_CI_DB_IDX = 510,
164
+	IPOIB_SND_CQ_CI_DB_IDX = 511
165
+};
166
+
167
+/* uar resources types */
168
+enum {
169
+	UAR_RES_INVALID = 0x0,	/* Invalid (not allocated) DoorBell record */
170
+	UAR_RES_CQ_SET_CI = 0x1,	/* CQ SET_CI DoorBell record */
171
+	UAR_RES_CQ_ARM = 0x2,	/* CQ ARM DoorBell record */
172
+	UAR_RES_SQ_DBELL = 0x3,	/* Send Queue DoorBell record */
173
+	UAR_RES_RQ_DBELL = 0x4,	/* Receive Queue DoorBell record */
174
+	UAR_RES_SRQ_DBELL = 0x5,	/* Shared Receive Queue DoorBell record */
175
+	UAR_RES_GROUP_SEP = 0x7	/* Group Separator record */
176
+};
177
+
178
+enum {
179
+	TS_RC,
180
+	TS_UC,
181
+	TS_RD,
182
+	TS_UD,
183
+	TS_MLX
184
+};
185
+
186
+enum {
187
+	PM_STATE_ARMED = 0,
188
+	PM_STATE_REARM = 1,
189
+	PM_STATE_MIGRATED = 3
190
+};
191
+
192
+enum {
193
+	DOORBEL_RES_SQ = 3,
194
+	DOORBEL_RES_RQ = 4,
195
+	DOORBEL_RES_SRQ = 5
196
+};
197
+
198
+struct ib_buffers_st {
199
+	__u8 send_mad_buf[NUM_MADS_SND_WQES][MAD_BUF_SZ];
200
+	__u8 rcv_mad_buf[NUM_MADS_RCV_WQES][MAD_BUF_SZ + GRH_SIZE];
201
+	__u8 ipoib_rcv_buf[NUM_IPOIB_RCV_WQES][IPOIB_RCV_BUF_SZ + GRH_SIZE];
202
+	__u8 ipoib_rcv_grh_buf[NUM_IPOIB_RCV_WQES][IPOIB_RCV_BUF_SZ];
203
+	__u8 send_ipoib_buf[NUM_IPOIB_SND_WQES][IPOIB_SND_BUF_SZ];
204
+};
205
+
206
+struct pcidev {
207
+	unsigned long bar[6];
208
+	__u32 dev_config_space[64];
209
+	struct pci_device *dev;
210
+	__u8 bus;
211
+	__u8 devfn;
212
+};
213
+
214
+struct dev_pci_struct {
215
+	struct pcidev dev;
216
+	struct pcidev br;
217
+	void *cr_space;
218
+	void *uar;
219
+};
220
+
221
+struct eq_st {
222
+	__u8 eqn;
223
+	__u32 cons_counter;
224
+	__u32 eq_size;
225
+	void *ci_base_base_addr;
226
+	struct eqe_t *eq_buf;
227
+};
228
+
229
+struct eqe_t {
230
+	__u8 raw[MT_STRUCT_SIZE(arbelprm_event_queue_entry_st)];
231
+} __attribute__ ((packed));
232
+
233
+enum qp_state_e {
234
+	QP_STATE_RST = 0,
235
+	QP_STATE_INIT = 1,
236
+	QP_STATE_RTR = 2,
237
+	QP_STATE_RTS = 3,
238
+	QP_STATE_SQEr = 4,
239
+	QP_STATE_SQD = 5,
240
+	QP_STATE_ERR = 6,
241
+	QP_STATE_SQDING = 7,
242
+	QP_STATE_SUSPEND = 9
243
+};
244
+
245
+struct memory_pointer_st {
246
+	__u32 byte_count;
247
+	__u32 lkey;
248
+	__u32 local_addr_h;
249
+	__u32 local_addr_l;
250
+} __attribute__ ((packed));
251
+
252
+/* receive wqe descriptor */
253
+struct recv_wqe_st {
254
+	/* part referenced by hardware */
255
+	__u8 control[MT_STRUCT_SIZE(arbelprm_wqe_segment_ctrl_recv_st)];
256
+	struct memory_pointer_st mpointer[MAX_SCATTER];
257
+} __attribute__ ((packed));
258
+
259
+struct recv_wqe_cont_st {
260
+	struct recv_wqe_st wqe;
261
+
262
+	struct udqp_st *qp;	/* qp this wqe is used with */
263
+} __attribute__ ((packed));
264
+
265
+#define RECV_WQE_U_ALIGN 64
266
+union recv_wqe_u {
267
+	__u8 align[RECV_WQE_U_ALIGN];	/* this ensures proper alignment */
268
+	struct recv_wqe_st wqe;
269
+	struct recv_wqe_cont_st wqe_cont;
270
+} __attribute__ ((packed));
271
+
272
+struct send_doorbell_st {
273
+	__u8 raw[MT_STRUCT_SIZE(arbelprm_send_doorbell_st)];
274
+} __attribute__ ((packed));
275
+
276
+struct next_control_seg_st {
277
+	__u8 next[MT_STRUCT_SIZE(arbelprm_wqe_segment_next_st)];
278
+	__u8 control[MT_STRUCT_SIZE(arbelprm_wqe_segment_ctrl_send_st)];
279
+} __attribute__ ((packed));
280
+
281
+struct ud_seg_st {
282
+	__u8 av[MT_STRUCT_SIZE(arbelprm_wqe_segment_ud_st)];
283
+} __attribute__ ((packed));
284
+
285
+struct ud_send_wqe_st {
286
+	struct next_control_seg_st next;	/* 16 bytes */
287
+	struct ud_seg_st udseg;	/* 48 bytes */
288
+	struct memory_pointer_st mpointer[MAX_GATHER];	/* 16 * MAX_GATHER bytes */
289
+} __attribute__ ((packed));
290
+
291
+struct ude_send_wqe_cont_st {
292
+	struct ud_send_wqe_st wqe;
293
+
294
+	struct udqp_st *qp;	/* qp this wqe is used with */
295
+} __attribute__ ((packed));
296
+
297
+#define UD_SEND_WQE_U_ALIGN 128
298
+union ud_send_wqe_u {
299
+	__u8 align[UD_SEND_WQE_U_ALIGN];
300
+	struct ude_send_wqe_cont_st wqe_cont;
301
+} __attribute__ ((packed));
302
+
303
+struct address_vector_st {
304
+	__u8 raw[MT_STRUCT_SIZE(arbelprm_ud_address_vector_st)];
305
+} __attribute__ ((packed));
306
+
307
+struct ud_av_st {
308
+	struct address_vector_st av;
309
+	__u32 dest_qp;		/* destination qpn */
310
+	__u32 qkey;
311
+	__u8 next_free;
312
+} __attribute__ ((packed));
313
+
314
+union ud_av_u {
315
+	struct ud_av_st ud_av;
316
+} __attribute__ ((packed));
317
+
318
+struct udav_st {
319
+	union ud_av_u av_array[NUM_AVS];
320
+	__u8 udav_next_free;
321
+};
322
+
323
+union cqe_st {
324
+	__u8 good_cqe[MT_STRUCT_SIZE(arbelprm_completion_queue_entry_st)];
325
+	__u8 error_cqe[MT_STRUCT_SIZE(arbelprm_completion_with_error_st)];
326
+} __attribute__ ((packed));
327
+
328
+struct qp_ee_ctx_t {
329
+	__u8 raw[MT_STRUCT_SIZE(arbelprm_queue_pair_ee_context_entry_st)];
330
+} __attribute__ ((packed));
331
+
332
+struct qp_ee_state_tarnisition_st {
333
+	__u32 opt_param_mask;
334
+	__u32 r1;
335
+	struct qp_ee_ctx_t ctx;
336
+	__u32 r2[62];
337
+} __attribute__ ((packed));
338
+
339
+struct cq_dbell_st {
340
+	__u8 raw[MT_STRUCT_SIZE(arbelprm_cq_cmd_doorbell_st)];
341
+} __attribute__ ((packed));
342
+
343
+struct mad_ifc_inprm_st {
344
+	union mad_u mad;
345
+} __attribute__ ((packed));
346
+
347
+struct wqe_buf_st {
348
+	struct ud_send_wqe_st *sndq;
349
+	struct recv_wqe_st *rcvq;
350
+};
351
+
352
+struct mad_buffer_st {
353
+	void *buf;		/* pointer to a 256 byte buffer */
354
+	__u8 owner;		/* sw or hw ownership BUF_OWNER_SW or BUF_OWNER_HW */
355
+};
356
+
357
+struct rcv_buf_st {
358
+	void *buf;
359
+	__u8 busy;
360
+};
361
+
362
+struct ib_eqe_st {
363
+	__u8 event_type;
364
+	__u32 cqn;
365
+};
366
+
367
+struct cq_st {
368
+	__u32 cqn;
369
+	union cqe_st *cq_buf;
370
+	__u32 cons_counter;	/* consuner counter */
371
+	__u8 num_cqes;
372
+	__u32 arm_db_ctx_idx;
373
+	void *arm_db_ctx_pointer;
374
+	__u32 ci_db_ctx_idx;
375
+	void *ci_db_ctx_pointer;
376
+};
377
+
378
+struct udqp_st {
379
+	/* cq used by this QP */
380
+	struct cq_st snd_cq;
381
+	struct cq_st rcv_cq;
382
+
383
+	/* QP related data */
384
+	__u32 qpn;		/* QP number */
385
+
386
+	__u32 qkey;
387
+
388
+	__u8 recv_wqe_cur_free;
389
+	__u8 recv_wqe_alloc_idx;
390
+	__u8 max_recv_wqes;
391
+	void *rcv_bufs[MAX_RCV_WQES];
392
+	union recv_wqe_u *rcv_wq;	/* receive work queue */
393
+	struct recv_wqe_st *last_posted_rcv_wqe;
394
+
395
+	__u8 snd_wqe_cur_free;
396
+	__u8 snd_wqe_alloc_idx;
397
+	__u8 max_snd_wqes;
398
+	void *snd_bufs[MAX_SND_WQES];
399
+	__u16 send_buf_sz;
400
+	__u16 rcv_buf_sz;
401
+	union ud_send_wqe_u *snd_wq;	/* send work queue */
402
+	struct ud_send_wqe_st *last_posted_snd_wqe;
403
+	/* pointers to uar context entries */
404
+	void *send_uar_context;
405
+	__u16 post_send_counter;
406
+	void *rcv_uar_context;
407
+	__u16 post_rcv_counter;
408
+	__u32 snd_db_record_index;
409
+	__u32 rcv_db_record_index;
410
+};
411
+
412
+struct device_ib_data_st {
413
+	__u32 mkey;
414
+	__u32 pd;
415
+	__u8 port;
416
+	__u32 qkey;
417
+	struct eq_st eq;
418
+	struct udav_st udav;
419
+	struct udqp_st mads_qp;
420
+	struct udqp_st ipoib_qp;
421
+	void *clr_int_addr;
422
+	__u32 clr_int_data;
423
+	__u32 uar_idx;
424
+	void *uar_context_base;
425
+	void *error_buf_addr;
426
+	__u32 error_buf_size;
427
+};
428
+
429
+struct query_fw_st {
430
+	__u16 fw_rev_major;
431
+	__u16 fw_rev_minor;
432
+	__u16 fw_rev_subminor;
433
+	__u32 error_buf_start_h;
434
+	__u32 error_buf_start_l;
435
+	__u32 error_buf_size;
436
+	__u32 fw_pages;
437
+	struct addr_64_st eq_ci_table;
438
+	struct addr_64_st clear_int_addr;
439
+};
440
+
441
+struct query_adapter_st {
442
+	__u8 intapin;
443
+};
444
+
445
+struct vpm_entry_st {
446
+	__u32 va_h;
447
+	__u32 va_l;
448
+	__u32 pa_h;
449
+	__u32 pa_l;
450
+	__u8 log2_size;
451
+};
452
+
453
+#define MAX_VPM_PER_CALL 1
454
+
455
+struct map_icm_st {
456
+	__u32 num_vpm;
457
+	struct vpm_entry_st vpm_arr[MAX_VPM_PER_CALL];
458
+};
459
+
460
+struct init_hca_st {
461
+	__u32 qpc_base_addr_h;
462
+	__u32 qpc_base_addr_l;
463
+	__u8 log_num_of_qp;
464
+
465
+	__u32 eec_base_addr_h;
466
+	__u32 eec_base_addr_l;
467
+	__u8 log_num_of_ee;
468
+
469
+	__u32 srqc_base_addr_h;
470
+	__u32 srqc_base_addr_l;
471
+	__u8 log_num_of_srq;
472
+
473
+	__u32 cqc_base_addr_h;
474
+	__u32 cqc_base_addr_l;
475
+	__u8 log_num_of_cq;
476
+
477
+	__u32 eqpc_base_addr_h;
478
+	__u32 eqpc_base_addr_l;
479
+
480
+	__u32 eeec_base_addr_h;
481
+	__u32 eeec_base_addr_l;
482
+
483
+	__u32 eqc_base_addr_h;
484
+	__u32 eqc_base_addr_l;
485
+	__u8 log_num_of_eq;
486
+
487
+	__u32 rdb_base_addr_h;
488
+	__u32 rdb_base_addr_l;
489
+
490
+	__u32 mc_base_addr_h;
491
+	__u32 mc_base_addr_l;
492
+	__u16 log_mc_table_entry_sz;
493
+	__u32 mc_table_hash_sz;
494
+	__u8 log_mc_table_sz;
495
+
496
+	__u32 mpt_base_addr_h;
497
+	__u32 mpt_base_addr_l;
498
+	__u8 log_mpt_sz;
499
+	__u32 mtt_base_addr_h;
500
+	__u32 mtt_base_addr_l;
501
+	__u8 log_max_uars;
502
+};
503
+
504
+struct dev_lim_st {
505
+	__u8 log2_rsvd_qps;
506
+	__u16 qpc_entry_sz;
507
+
508
+	__u8 log2_rsvd_srqs;
509
+	__u16 srq_entry_sz;
510
+
511
+	__u8 log2_rsvd_ees;
512
+	__u16 eec_entry_sz;
513
+
514
+	__u8 log2_rsvd_cqs;
515
+	__u16 cqc_entry_sz;
516
+
517
+	__u8 log2_rsvd_mtts;
518
+	__u16 mtt_entry_sz;
519
+
520
+	__u8 log2_rsvd_mrws;
521
+	__u16 mpt_entry_sz;
522
+
523
+	__u8 log2_rsvd_rdbs;
524
+
525
+	__u16 eqc_entry_sz;
526
+
527
+	__u32 max_icm_size_l;
528
+	__u32 max_icm_size_h;
529
+
530
+	__u8 uar_sz;
531
+	__u8 num_rsvd_uars;
532
+};
533
+
534
+static int create_udqp(struct udqp_st *qp);
535
+static int destroy_udqp(struct udqp_st *qp);
536
+static void *get_send_wqe_buf(void *wqe, __u8 index);
537
+static void *get_rcv_wqe_buf(void *wqe, __u8 index);
538
+
539
+static struct recv_wqe_st *alloc_rcv_wqe(struct udqp_st *qp);
540
+static int free_wqe(void *wqe);
541
+static int poll_cq(void *cqh, union cqe_st *cqe_p, __u8 * num_cqes);
542
+static int poll_eq(struct ib_eqe_st *ib_eqe_p, __u8 * num_eqes);
543
+static int post_rcv_buf(struct udqp_st *qp, struct recv_wqe_st *rcv_wqe);
544
+static __u32 dev_get_qpn(void *qph);
545
+
546
+#endif				/* __mt25218_h__ */

+ 230
- 0
src/drivers/net/mlx_ipoib/mt25218_imp.c Datei anzeigen

@@ -0,0 +1,230 @@
1
+typedef uint32_t __u32;
2
+typedef uint16_t __u16;
3
+typedef uint8_t __u8;
4
+
5
+static int verbose_messages=0;
6
+static int print_info=0;
7
+static int fatal_condition=0;
8
+static int fw_fatal;
9
+
10
+#define tprintf(fmt, a...) \
11
+		 do {    \
12
+			if ( verbose_messages ) { \
13
+				printf("%s:%d: " fmt "\n", __func__, __LINE__,  ##a); \
14
+			} \
15
+		 } \
16
+		 while(0)
17
+
18
+#define eprintf(fmt, a...) \
19
+		 printf("%s:%d: " fmt "\n", __func__, __LINE__,  ##a)
20
+
21
+static void cpu_to_be_buf(void *buf, int size)
22
+{
23
+	int dw_sz = size >> 2, i;
24
+
25
+	for (i = 0; i < dw_sz; ++i) {
26
+		((__u32 *) buf)[i] = cpu_to_be32(((__u32 *) buf)[i]);
27
+	}
28
+}
29
+
30
+static void be_to_cpu_buf(void *buf, int size)
31
+{
32
+	int dw_sz = size >> 2, i;
33
+	u32 *p = buf;
34
+
35
+	for (i = 0; i < dw_sz; ++i) {
36
+		p[i] = be32_to_cpu(p[i]);
37
+	}
38
+}
39
+
40
+#include "timer.h"
41
+#include "cmdif_mt25218.c"
42
+#include "cmdif_comm.c"
43
+#include "ib_mt25218.c"
44
+#include "ib_mad.c"
45
+#include "ib_driver.c"
46
+#include "ipoib.c"
47
+
48
+static int probe_imp(struct pci_device *pci, struct nic *nic)
49
+{
50
+	int rc;
51
+
52
+	if (0 && nic) {		/* just to supress warning */
53
+		return 0;
54
+	}
55
+
56
+	fatal_condition= 0;
57
+	fw_fatal= 0;
58
+
59
+	tprintf("");
60
+	rc = ipoib_init(pci);
61
+	if (rc)
62
+		return rc;
63
+
64
+	tprintf("");
65
+
66
+	return rc;
67
+}
68
+
69
+static int disable_imp(void)
70
+{
71
+	int rc;
72
+
73
+	rc = ipoib_close(fw_fatal);
74
+
75
+	return rc;
76
+}
77
+
78
+static int transmit_imp(const char *dest,	/* Destination */
79
+			unsigned int type,	/* Type */
80
+			const char *packet,	/* Packet */
81
+			unsigned int size)
82
+{				/* size */
83
+	int rc;
84
+
85
+	if (fatal_condition) {
86
+		/* since the transmit function does not return a value
87
+		   we return success but do nothing to suppress error messages */
88
+		return 0;
89
+	}
90
+
91
+	rc = ipoib_send_packet(dest, type, packet, size);
92
+	if (rc) {
93
+		printf("*** ERROR IN SEND FLOW ***\n");
94
+		printf("restarting Etherboot\n");
95
+		sleep(1);
96
+		longjmp(restart_etherboot, -1);
97
+		/* we should not be here ... */
98
+		return -1; 
99
+	}
100
+
101
+	return rc;
102
+}
103
+
104
+static void hd(void *where, int n)
105
+{
106
+	int i;
107
+
108
+	while (n > 0) {
109
+		printf("%X ", where);
110
+		for (i = 0; i < ((n > 16) ? 16 : n); i++)
111
+			printf(" %hhX", ((char *)where)[i]);
112
+		printf("\n");
113
+		n -= 16;
114
+		where += 16;
115
+	}
116
+}
117
+
118
+static int poll_imp(struct nic *nic, int retrieve, unsigned int *size_p)
119
+{
120
+	static char packet[2048];
121
+	static char *last_packet_p = NULL;
122
+	static unsigned long last_packet_size;
123
+	char *packet_p;
124
+	const int eth_header_len = 14;
125
+	unsigned int packet_len;
126
+	int is_bcast = 0;
127
+	__u16 prot, *ptr;
128
+	int rc;
129
+
130
+	if (0 && nic) {		/* just to supress warning */
131
+		return -1;
132
+	}
133
+
134
+	if (fatal_condition) {
135
+		*size_p = 0;
136
+		return 0;
137
+	}
138
+
139
+	if (poll_error_buf()) {
140
+		fatal_condition= 1;
141
+		fw_fatal= 1;
142
+		printf("\n *** DEVICE FATAL ERROR ***\n");
143
+		goto fatal_handling;
144
+	}
145
+	else if (drain_eq()) {
146
+		fatal_condition= 1;
147
+		printf("\n *** FATAL ERROR ***\n");
148
+		goto fatal_handling;
149
+	}
150
+
151
+
152
+	if (retrieve) {
153
+		/* we actually want to read the packet */
154
+		if (last_packet_p) {
155
+			eprintf("");
156
+			/* there is already a packet that was previously read */
157
+			memcpy(nic->packet, last_packet_p, last_packet_size);
158
+			*size_p = last_packet_size;
159
+			last_packet_p = NULL;
160
+			return 0;
161
+		}
162
+		packet_p = nic->packet;
163
+	} else {
164
+		/* we don't want to read the packet,
165
+		   just know if there is one. so we
166
+		   read the packet to a local buffer and
167
+		   we will return that buffer when the ip layer wants
168
+		   another packet */
169
+		if (last_packet_p) {
170
+			/* there is already a packet that
171
+			   was not consumend */
172
+			eprintf("overflow receive packets");
173
+			return -1;
174
+		}
175
+		packet_p = packet;
176
+	}
177
+
178
+	rc = ipoib_read_packet(&prot, packet_p + eth_header_len, &packet_len,
179
+			       &is_bcast);
180
+	if (rc) {
181
+		printf("*** FATAL IN RECEIVE FLOW ****\n");
182
+		goto fatal_handling;
183
+	}
184
+
185
+	if (packet_len == 0) {
186
+		*size_p = 0;
187
+		return 0;
188
+	}
189
+
190
+	if (is_bcast) {
191
+		int i;
192
+		for (i = 0; i < 6; ++i) {
193
+			packet_p[i] = 0xff;
194
+		}
195
+	} else {
196
+		packet_p[0] = MLX_ETH_BYTE0;
197
+		packet_p[1] = MLX_ETH_BYTE1;
198
+		packet_p[2] = MLX_ETH_BYTE2;
199
+		packet_p[3] = 0;
200
+		packet_p[4] = 0;
201
+		packet_p[5] = 0;
202
+	}
203
+
204
+	memset(packet_p + 6, 0, 6);
205
+
206
+	ptr = (__u16 *) (packet_p + 12);
207
+	*ptr = htons(prot);
208
+
209
+	if (!retrieve) {
210
+		last_packet_p = packet;
211
+		last_packet_size = packet_len + eth_header_len;
212
+		*size_p = 0;
213
+	}
214
+
215
+	*size_p = packet_len + eth_header_len;
216
+	tprintf("packet size=%d, prot=%x\n", *size_p, prot);
217
+	if (0) {
218
+		hd(nic->packet, 42);
219
+	}
220
+
221
+	return 0;
222
+
223
+fatal_handling:
224
+	printf("restarting Etherboot\n");
225
+	sleep(1);
226
+	longjmp(restart_etherboot, -1);
227
+	/* we should not be here ... */
228
+	return -1; 
229
+	
230
+}

+ 23
- 0
src/drivers/net/mlx_ipoib/mt_version.c Datei anzeigen

@@ -0,0 +1,23 @@
1
+/*
2
+  This software is available to you under a choice of one of two
3
+  licenses.  You may choose to be licensed under the terms of the GNU
4
+  General Public License (GPL) Version 2, available at
5
+  <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6
+  license, available in the LICENSE.TXT file accompanying this
7
+  software.  These details are also available at
8
+  <http://openib.org/license.html>.
9
+
10
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
+  SOFTWARE.
18
+
19
+  Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
20
+*/
21
+
22
+/* definition of the build version goes here */
23
+const char *build_revision= "113";

Laden…
Abbrechen
Speichern