Browse Source

[intel] Fix operation when physical function has jumbo frames enabled

When jumbo frames are enabled, the Linux ixgbe physical function
driver will disable the virtual function's receive datapath by
default, and will enable it only if the virtual function negotiates
API version 1.1 (or higher) and explicitly selects an MTU.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
99f87b2338
4 changed files with 134 additions and 2 deletions
  1. 39
    2
      src/drivers/net/intelvf.c
  2. 25
    0
      src/drivers/net/intelvf.h
  3. 64
    0
      src/drivers/net/intelxvf.c
  4. 6
    0
      src/drivers/net/intelxvf.h

+ 39
- 2
src/drivers/net/intelvf.c View File

146
  * @v msg		Message buffer
146
  * @v msg		Message buffer
147
  * @ret rc		Return status code
147
  * @ret rc		Return status code
148
  */
148
  */
149
-static int intelvf_mbox_msg ( struct intel_nic *intel,
150
-			      union intelvf_msg *msg ) {
149
+int intelvf_mbox_msg ( struct intel_nic *intel, union intelvf_msg *msg ) {
151
 	struct intel_mailbox *mbox = &intel->mbox;
150
 	struct intel_mailbox *mbox = &intel->mbox;
152
 	uint32_t ctrl;
151
 	uint32_t ctrl;
153
 	uint32_t seen = 0;
152
 	uint32_t seen = 0;
301
 
300
 
302
 	return 0;
301
 	return 0;
303
 }
302
 }
303
+
304
+/**
305
+ * Send set MTU message
306
+ *
307
+ * @v intel		Intel device
308
+ * @v mtu		Maximum packet size
309
+ * @ret rc		Return status code
310
+ */
311
+int intelvf_mbox_set_mtu ( struct intel_nic *intel, size_t mtu ) {
312
+	union intelvf_msg msg;
313
+	int rc;
314
+
315
+	/* Send set MTU message */
316
+	memset ( &msg, 0, sizeof ( msg ) );
317
+	msg.hdr = INTELVF_MSG_TYPE_SET_MTU;
318
+	msg.mtu.mtu = mtu;
319
+	if ( ( rc = intelvf_mbox_msg ( intel, &msg ) ) != 0 ) {
320
+		DBGC ( intel, "INTEL %p set MTU failed: %s\n",
321
+		       intel, strerror ( rc ) );
322
+		return rc;
323
+	}
324
+
325
+	/* Check response */
326
+	if ( ( msg.hdr & INTELVF_MSG_TYPE_MASK ) != INTELVF_MSG_TYPE_SET_MTU ) {
327
+		DBGC ( intel, "INTEL %p set MTU unexpected response:\n",
328
+		       intel );
329
+		DBGC_HDA ( intel, 0, &msg, sizeof ( msg ) );
330
+		return -EPROTO;
331
+	}
332
+
333
+	/* Check that we were allowed to set the MTU */
334
+	if ( ! ( msg.hdr & INTELVF_MSG_ACK ) ) {
335
+		DBGC ( intel, "INTEL %p set MTU refused\n", intel );
336
+		return -EPERM;
337
+	}
338
+
339
+	return 0;
340
+}

+ 25
- 0
src/drivers/net/intelvf.h View File

34
 /** Set MAC address mailbox message */
34
 /** Set MAC address mailbox message */
35
 #define INTELVF_MSG_TYPE_SET_MAC 0x00000002UL
35
 #define INTELVF_MSG_TYPE_SET_MAC 0x00000002UL
36
 
36
 
37
+/** Set MTU mailbox message */
38
+#define INTELVF_MSG_TYPE_SET_MTU 0x00000005UL
39
+
37
 /** Control ("ping") mailbox message */
40
 /** Control ("ping") mailbox message */
38
 #define INTELVF_MSG_TYPE_CONTROL 0x00000100UL
41
 #define INTELVF_MSG_TYPE_CONTROL 0x00000100UL
39
 
42
 
59
 	uint8_t reserved[ (-ETH_ALEN) & 0x3 ];
62
 	uint8_t reserved[ (-ETH_ALEN) & 0x3 ];
60
 } __attribute__ (( packed ));
63
 } __attribute__ (( packed ));
61
 
64
 
65
+/** Version number mailbox message */
66
+struct intelvf_msg_version {
67
+	/** Message header */
68
+	uint32_t hdr;
69
+	/** API version */
70
+	uint32_t version;
71
+} __attribute__ (( packed ));
72
+
73
+/** MTU mailbox message */
74
+struct intelvf_msg_mtu {
75
+	/** Message header */
76
+	uint32_t hdr;
77
+	/** Maximum packet size */
78
+	uint32_t mtu;
79
+} __attribute__ (( packed ));
80
+
62
 /** Mailbox message */
81
 /** Mailbox message */
63
 union intelvf_msg {
82
 union intelvf_msg {
64
 	/** Message header */
83
 	/** Message header */
65
 	uint32_t hdr;
84
 	uint32_t hdr;
66
 	/** MAC address message */
85
 	/** MAC address message */
67
 	struct intelvf_msg_mac mac;
86
 	struct intelvf_msg_mac mac;
87
+	/** Version number message */
88
+	struct intelvf_msg_version version;
89
+	/** MTU message */
90
+	struct intelvf_msg_mtu mtu;
68
 	/** Raw dwords */
91
 	/** Raw dwords */
69
 	uint32_t dword[0];
92
 	uint32_t dword[0];
70
 };
93
 };
75
  */
98
  */
76
 #define INTELVF_MBOX_MAX_WAIT_MS 500
99
 #define INTELVF_MBOX_MAX_WAIT_MS 500
77
 
100
 
101
+extern int intelvf_mbox_msg ( struct intel_nic *intel, union intelvf_msg *msg );
78
 extern int intelvf_mbox_poll ( struct intel_nic *intel );
102
 extern int intelvf_mbox_poll ( struct intel_nic *intel );
79
 extern int intelvf_mbox_wait ( struct intel_nic *intel );
103
 extern int intelvf_mbox_wait ( struct intel_nic *intel );
80
 extern int intelvf_mbox_reset ( struct intel_nic *intel, uint8_t *hw_addr );
104
 extern int intelvf_mbox_reset ( struct intel_nic *intel, uint8_t *hw_addr );
81
 extern int intelvf_mbox_set_mac ( struct intel_nic *intel,
105
 extern int intelvf_mbox_set_mac ( struct intel_nic *intel,
82
 				  const uint8_t *ll_addr );
106
 				  const uint8_t *ll_addr );
107
+extern int intelvf_mbox_set_mtu ( struct intel_nic *intel, size_t mtu );
83
 
108
 
84
 #endif /* _INTELVF_H */
109
 #endif /* _INTELVF_H */

+ 64
- 0
src/drivers/net/intelxvf.c View File

109
 	}
109
 	}
110
 }
110
 }
111
 
111
 
112
+/******************************************************************************
113
+ *
114
+ * Mailbox messages
115
+ *
116
+ ******************************************************************************
117
+ */
118
+
119
+/**
120
+ * Send negotiate API version message
121
+ *
122
+ * @v intel		Intel device
123
+ * @v version		Requested version
124
+ * @ret rc		Return status code
125
+ */
126
+static int intelxvf_mbox_version ( struct intel_nic *intel,
127
+				   unsigned int version ) {
128
+	union intelvf_msg msg;
129
+	int rc;
130
+
131
+	/* Send set MTU message */
132
+	memset ( &msg, 0, sizeof ( msg ) );
133
+	msg.hdr = INTELXVF_MSG_TYPE_VERSION;
134
+	msg.version.version = version;
135
+	if ( ( rc = intelvf_mbox_msg ( intel, &msg ) ) != 0 ) {
136
+		DBGC ( intel, "INTEL %p negotiate API version failed: %s\n",
137
+		       intel, strerror ( rc ) );
138
+		return rc;
139
+	}
140
+
141
+	/* Check response */
142
+	if ( ( msg.hdr & INTELVF_MSG_TYPE_MASK ) != INTELXVF_MSG_TYPE_VERSION ){
143
+		DBGC ( intel, "INTEL %p negotiate API version unexpected "
144
+		       "response:\n", intel );
145
+		DBGC_HDA ( intel, 0, &msg, sizeof ( msg ) );
146
+		return -EPROTO;
147
+	}
148
+
149
+	/* Check that this version is supported */
150
+	if ( ! ( msg.hdr & INTELVF_MSG_ACK ) ) {
151
+		DBGC ( intel, "INTEL %p negotiate API version failed\n",
152
+		       intel );
153
+		return -EPERM;
154
+	}
155
+
156
+	return 0;
157
+}
158
+
112
 /******************************************************************************
159
 /******************************************************************************
113
  *
160
  *
114
  * Network device interface
161
  * Network device interface
138
 		goto err_mbox_reset;
185
 		goto err_mbox_reset;
139
 	}
186
 	}
140
 
187
 
188
+	/* Negotiate API version 1.1.  If we do not negotiate at least
189
+	 * this version, then the RX datapath will remain disabled if
190
+	 * the PF has jumbo frames enabled.
191
+	 *
192
+	 * Ignore failures, since the host may not actually support
193
+	 * v1.1.
194
+	 */
195
+	intelxvf_mbox_version ( intel, INTELXVF_MSG_VERSION_1_1 );
196
+
141
 	/* Set MAC address */
197
 	/* Set MAC address */
142
 	if ( ( rc = intelvf_mbox_set_mac ( intel, netdev->ll_addr ) ) != 0 ) {
198
 	if ( ( rc = intelvf_mbox_set_mac ( intel, netdev->ll_addr ) ) != 0 ) {
143
 		DBGC ( intel, "INTEL %p could not set MAC address: %s\n",
199
 		DBGC ( intel, "INTEL %p could not set MAC address: %s\n",
145
 		goto err_mbox_set_mac;
201
 		goto err_mbox_set_mac;
146
 	}
202
 	}
147
 
203
 
204
+	/* Set MTU */
205
+	if ( ( rc = intelvf_mbox_set_mtu ( intel, netdev->max_pkt_len ) ) != 0){
206
+		DBGC ( intel, "INTEL %p could not set MTU %zd: %s\n",
207
+		       intel, netdev->max_pkt_len, strerror ( rc ) );
208
+		goto err_mbox_set_mtu;
209
+	}
210
+
148
 	/* Create transmit descriptor ring */
211
 	/* Create transmit descriptor ring */
149
 	if ( ( rc = intel_create_ring ( intel, &intel->tx ) ) != 0 )
212
 	if ( ( rc = intel_create_ring ( intel, &intel->tx ) ) != 0 )
150
 		goto err_create_tx;
213
 		goto err_create_tx;
188
  err_create_rx:
251
  err_create_rx:
189
 	intel_destroy_ring ( intel, &intel->tx );
252
 	intel_destroy_ring ( intel, &intel->tx );
190
  err_create_tx:
253
  err_create_tx:
254
+ err_mbox_set_mtu:
191
  err_mbox_set_mac:
255
  err_mbox_set_mac:
192
  err_mbox_reset:
256
  err_mbox_reset:
193
 	intelxvf_reset ( intel );
257
 	intelxvf_reset ( intel );

+ 6
- 0
src/drivers/net/intelxvf.h View File

95
 /** Good Packets Transmitted Count High */
95
 /** Good Packets Transmitted Count High */
96
 #define INTELXVF_GOTCH 0x2024
96
 #define INTELXVF_GOTCH 0x2024
97
 
97
 
98
+/** Negotiate API version mailbox message */
99
+#define INTELXVF_MSG_TYPE_VERSION 0x00000008UL
100
+
101
+/** API version 1.1 */
102
+#define INTELXVF_MSG_VERSION_1_1 0x00000002UL
103
+
98
 #endif /* _INTELXVF_H */
104
 #endif /* _INTELXVF_H */

Loading…
Cancel
Save