|
@@ -84,6 +84,86 @@ static struct net_protocol lotest_protocol __net_protocol = {
|
84
|
84
|
.net_addr_len = 0,
|
85
|
85
|
};
|
86
|
86
|
|
|
87
|
+/**
|
|
88
|
+ * Wait for packet to be received
|
|
89
|
+ *
|
|
90
|
+ * @v receiver Receiving network device*
|
|
91
|
+ * @v data Expected data
|
|
92
|
+ * @v len Expected data length
|
|
93
|
+ * @ret rc Return status code
|
|
94
|
+ */
|
|
95
|
+static int loopback_wait ( struct net_device *receiver, void *data,
|
|
96
|
+ size_t len ) {
|
|
97
|
+ struct ll_protocol *ll_protocol = receiver->ll_protocol;
|
|
98
|
+ struct io_buffer *iobuf;
|
|
99
|
+ const void *ll_dest;
|
|
100
|
+ const void *ll_source;
|
|
101
|
+ uint16_t net_proto;
|
|
102
|
+ unsigned int flags;
|
|
103
|
+ int rc;
|
|
104
|
+
|
|
105
|
+ /* Poll until packet arrives */
|
|
106
|
+ while ( 1 ) {
|
|
107
|
+
|
|
108
|
+ /* Check for cancellation */
|
|
109
|
+ if ( iskey() && ( getchar() == CTRL_C ) )
|
|
110
|
+ return -ECANCELED;
|
|
111
|
+
|
|
112
|
+ /* Poll network devices */
|
|
113
|
+ net_poll();
|
|
114
|
+
|
|
115
|
+ /* Dequeue packet, if available */
|
|
116
|
+ iobuf = netdev_rx_dequeue ( receiver );
|
|
117
|
+ if ( ! iobuf )
|
|
118
|
+ continue;
|
|
119
|
+
|
|
120
|
+ /* Strip link-layer header */
|
|
121
|
+ if ( ( rc = ll_protocol->pull ( receiver, iobuf, &ll_dest,
|
|
122
|
+ &ll_source, &net_proto,
|
|
123
|
+ &flags ) ) != 0 ) {
|
|
124
|
+ printf ( "\nFailed to strip link-layer header: %s",
|
|
125
|
+ strerror ( rc ) );
|
|
126
|
+ free_iob ( iob_disown ( iobuf ) );
|
|
127
|
+ return rc;
|
|
128
|
+ }
|
|
129
|
+
|
|
130
|
+ /* Ignore non-loopback packets */
|
|
131
|
+ if ( net_proto != lotest_protocol.net_proto ) {
|
|
132
|
+ printf ( "\nReceived spurious packet type %04x\n",
|
|
133
|
+ ntohs ( net_proto ) );
|
|
134
|
+ free_iob ( iob_disown ( iobuf ) );
|
|
135
|
+ continue;
|
|
136
|
+ }
|
|
137
|
+
|
|
138
|
+ /* Check packet length */
|
|
139
|
+ if ( iob_len ( iobuf ) != len ) {
|
|
140
|
+ printf ( "\nLength mismatch: sent %zd, received %zd",
|
|
141
|
+ len, iob_len ( iobuf ) );
|
|
142
|
+ DBG ( "\nSent:\n" );
|
|
143
|
+ DBG_HDA ( 0, data, len );
|
|
144
|
+ DBG ( "Received:\n" );
|
|
145
|
+ DBG_HDA ( 0, iobuf->data, iob_len ( iobuf ) );
|
|
146
|
+ free_iob ( iob_disown ( iobuf ) );
|
|
147
|
+ return -EINVAL;
|
|
148
|
+ }
|
|
149
|
+
|
|
150
|
+ /* Check packet content */
|
|
151
|
+ if ( memcmp ( iobuf->data, data, len ) != 0 ) {
|
|
152
|
+ printf ( "\nContent mismatch" );
|
|
153
|
+ DBG ( "\nSent:\n" );
|
|
154
|
+ DBG_HDA ( 0, data, len );
|
|
155
|
+ DBG ( "Received:\n" );
|
|
156
|
+ DBG_HDA ( 0, iobuf->data, iob_len ( iobuf ) );
|
|
157
|
+ free_iob ( iob_disown ( iobuf ) );
|
|
158
|
+ return -EINVAL;
|
|
159
|
+ }
|
|
160
|
+
|
|
161
|
+ /* Discard packet and return */
|
|
162
|
+ free_iob ( iob_disown ( iobuf ) );
|
|
163
|
+ return 0;
|
|
164
|
+ }
|
|
165
|
+}
|
|
166
|
+
|
87
|
167
|
/**
|
88
|
168
|
* Perform loopback test between two network devices
|
89
|
169
|
*
|
|
@@ -96,10 +176,6 @@ int loopback_test ( struct net_device *sender, struct net_device *receiver,
|
96
|
176
|
size_t mtu ) {
|
97
|
177
|
uint8_t buf[mtu];
|
98
|
178
|
struct io_buffer *iobuf;
|
99
|
|
- const void *ll_dest;
|
100
|
|
- const void *ll_source;
|
101
|
|
- uint16_t net_proto;
|
102
|
|
- unsigned int flags;
|
103
|
179
|
unsigned int i;
|
104
|
180
|
unsigned int successes;
|
105
|
181
|
int rc;
|
|
@@ -140,7 +216,7 @@ int loopback_test ( struct net_device *sender, struct net_device *receiver,
|
140
|
216
|
if ( ! iobuf ) {
|
141
|
217
|
printf ( "\nFailed to allocate I/O buffer" );
|
142
|
218
|
rc = -ENOMEM;
|
143
|
|
- goto done;
|
|
219
|
+ break;
|
144
|
220
|
}
|
145
|
221
|
iob_reserve ( iobuf, MAX_LL_HEADER_LEN );
|
146
|
222
|
memcpy ( iob_put ( iobuf, sizeof ( buf ) ),
|
|
@@ -152,65 +228,17 @@ int loopback_test ( struct net_device *sender, struct net_device *receiver,
|
152
|
228
|
sender->ll_addr ) ) != 0 ) {
|
153
|
229
|
printf ( "\nFailed to transmit packet: %s",
|
154
|
230
|
strerror ( rc ) );
|
155
|
|
- goto done;
|
|
231
|
+ break;
|
156
|
232
|
}
|
157
|
233
|
|
158
|
|
- /* Poll until packet arrives */
|
159
|
|
- do {
|
160
|
|
- /* Check for cancellation */
|
161
|
|
- if ( iskey() && ( getchar() == CTRL_C ) ) {
|
162
|
|
- rc = -ECANCELED;
|
163
|
|
- goto done;
|
164
|
|
- }
|
165
|
|
- /* Poll network devices */
|
166
|
|
- net_poll();
|
167
|
|
- } while ( ( iobuf = netdev_rx_dequeue ( receiver ) ) == NULL );
|
168
|
|
-
|
169
|
|
- /* Check received packet */
|
170
|
|
- if ( ( rc = receiver->ll_protocol->pull ( receiver, iobuf,
|
171
|
|
- &ll_dest, &ll_source,
|
172
|
|
- &net_proto,
|
173
|
|
- &flags ) ) != 0 ) {
|
174
|
|
- printf ( "\nFailed to strip link-layer header: %s",
|
175
|
|
- strerror ( rc ) );
|
176
|
|
- goto done;
|
177
|
|
- }
|
178
|
|
- if ( net_proto == lotest_protocol.net_proto ) {
|
179
|
|
- if ( iob_len ( iobuf ) != sizeof ( buf ) ) {
|
180
|
|
- printf ( "\nLength mismatch: sent %zd, "
|
181
|
|
- "received %zd",
|
182
|
|
- sizeof ( buf ), iob_len ( iobuf ) );
|
183
|
|
- DBG ( "\nSent:\n" );
|
184
|
|
- DBG_HDA ( 0, buf, sizeof ( buf ) );
|
185
|
|
- DBG ( "Received:\n" );
|
186
|
|
- DBG_HDA ( 0, iobuf->data, iob_len ( iobuf ) );
|
187
|
|
- rc = -EINVAL;
|
188
|
|
- goto done;
|
189
|
|
- }
|
190
|
|
- if ( memcmp ( iobuf->data, buf, sizeof ( buf ) ) != 0){
|
191
|
|
- printf ( "\nContent mismatch" );
|
192
|
|
- DBG ( "\nSent:\n" );
|
193
|
|
- DBG_HDA ( 0, buf, sizeof ( buf ) );
|
194
|
|
- DBG ( "Received:\n" );
|
195
|
|
- DBG_HDA ( 0, iobuf->data, iob_len ( iobuf ) );
|
196
|
|
- rc = -EINVAL;
|
197
|
|
- goto done;
|
198
|
|
- }
|
199
|
|
- } else {
|
200
|
|
- printf ( "\nReceived spurious packet type %04x\n",
|
201
|
|
- ntohs ( net_proto ) );
|
202
|
|
- /* Continue; this allows for the fact that
|
203
|
|
- * there may have been packets outstanding on
|
204
|
|
- * the wire when we started the test.
|
205
|
|
- */
|
|
234
|
+ /* Wait for received packet */
|
|
235
|
+ if ( ( rc = loopback_wait ( receiver, buf,
|
|
236
|
+ sizeof ( buf ) ) ) != 0 ) {
|
|
237
|
+ break;
|
206
|
238
|
}
|
207
|
|
-
|
208
|
|
- free_iob ( iob_disown ( iobuf ) );
|
209
|
239
|
}
|
210
|
240
|
|
211
|
|
- done:
|
212
|
241
|
printf ( "\n");
|
213
|
|
- free_iob ( iobuf );
|
214
|
242
|
netdev_rx_unfreeze ( receiver );
|
215
|
243
|
|
216
|
244
|
/* Dump final statistics */
|