Browse Source

[ifmgmt] Rewrite iflinkwait() to use monojob_wait()

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 years ago
parent
commit
16d37102ca
4 changed files with 99 additions and 44 deletions
  1. 1
    1
      src/include/usr/ifmgmt.h
  2. 4
    3
      src/usr/dhcpmgmt.c
  3. 92
    36
      src/usr/ifmgmt.c
  4. 2
    4
      src/usr/lotest.c

+ 1
- 1
src/include/usr/ifmgmt.h View File

@@ -14,6 +14,6 @@ struct net_device;
14 14
 extern int ifopen ( struct net_device *netdev );
15 15
 extern void ifclose ( struct net_device *netdev );
16 16
 extern void ifstat ( struct net_device *netdev );
17
-extern int iflinkwait ( struct net_device *netdev, unsigned int max_wait_ms );
17
+extern int iflinkwait ( struct net_device *netdev, unsigned long timeout );
18 18
 
19 19
 #endif /* _USR_IFMGMT_H */

+ 4
- 3
src/usr/dhcpmgmt.c View File

@@ -25,11 +25,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
25 25
 #include <ipxe/netdevice.h>
26 26
 #include <ipxe/dhcp.h>
27 27
 #include <ipxe/monojob.h>
28
-#include <ipxe/process.h>
28
+#include <ipxe/timer.h>
29 29
 #include <usr/ifmgmt.h>
30 30
 #include <usr/dhcpmgmt.h>
31 31
 
32
-#define LINK_WAIT_MS	15000
32
+/** Default time to wait for link-up */
33
+#define LINK_WAIT_TIMEOUT ( 15 * TICKS_PER_SEC )
33 34
 
34 35
 /** @file
35 36
  *
@@ -45,7 +46,7 @@ int dhcp ( struct net_device *netdev ) {
45 46
 		return rc;
46 47
 
47 48
 	/* Wait for link-up */
48
-	if ( ( rc = iflinkwait ( netdev, LINK_WAIT_MS ) ) != 0 )
49
+	if ( ( rc = iflinkwait ( netdev, LINK_WAIT_TIMEOUT ) ) != 0 )
49 50
 		return rc;
50 51
 
51 52
 	/* Perform DHCP */

+ 92
- 36
src/usr/ifmgmt.c View File

@@ -26,8 +26,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
26 26
 #include <ipxe/console.h>
27 27
 #include <ipxe/netdevice.h>
28 28
 #include <ipxe/device.h>
29
-#include <ipxe/process.h>
30
-#include <ipxe/keys.h>
29
+#include <ipxe/job.h>
30
+#include <ipxe/monojob.h>
31
+#include <ipxe/nap.h>
31 32
 #include <usr/ifmgmt.h>
32 33
 
33 34
 /** @file
@@ -104,49 +105,104 @@ void ifstat ( struct net_device *netdev ) {
104 105
 	ifstat_errors ( &netdev->rx_stats, "RXE" );
105 106
 }
106 107
 
108
+/** Network device poller */
109
+struct ifpoller {
110
+	/** Job control interface */
111
+	struct interface job;
112
+	/** Network device */
113
+	struct net_device *netdev;
114
+	/**
115
+	 * Check progress
116
+	 *
117
+	 * @v ifpoller		Network device poller
118
+	 * @ret ongoing_rc	Ongoing job status code (if known)
119
+	 */
120
+	int ( * progress ) ( struct ifpoller *ifpoller );
121
+};
122
+
123
+/**
124
+ * Report network device poller progress
125
+ *
126
+ * @v ifpoller		Network device poller
127
+ * @v progress		Progress report to fill in
128
+ * @ret ongoing_rc	Ongoing job status code (if known)
129
+ */
130
+static int ifpoller_progress ( struct ifpoller *ifpoller,
131
+			       struct job_progress *progress __unused ) {
132
+
133
+	/* Reduce CPU utilisation */
134
+	cpu_nap();
135
+
136
+	/* Hand off to current progress checker */
137
+	return ifpoller->progress ( ifpoller );
138
+}
139
+
140
+/** Network device poller operations */
141
+static struct interface_operation ifpoller_job_op[] = {
142
+	INTF_OP ( job_progress, struct ifpoller *, ifpoller_progress ),
143
+};
144
+
145
+/** Network device poller descriptor */
146
+static struct interface_descriptor ifpoller_job_desc =
147
+	INTF_DESC ( struct ifpoller, job, ifpoller_job_op );
148
+
149
+/**
150
+ * Poll network device until completion
151
+ *
152
+ * @v netdev		Network device
153
+ * @v timeout		Timeout period, in ticks
154
+ * @v progress		Method to check progress
155
+ * @ret rc		Return status code
156
+ */
157
+static int ifpoller_wait ( struct net_device *netdev, unsigned long timeout,
158
+			   int ( * progress ) ( struct ifpoller *ifpoller ) ) {
159
+	static struct ifpoller ifpoller = {
160
+		.job = INTF_INIT ( ifpoller_job_desc ),
161
+	};
162
+
163
+	ifpoller.netdev = netdev;
164
+	ifpoller.progress = progress;
165
+	intf_plug_plug ( &monojob, &ifpoller.job );
166
+	return monojob_wait ( "", timeout );
167
+}
168
+
169
+/**
170
+ * Check link-up progress
171
+ *
172
+ * @v ifpoller		Network device poller
173
+ * @ret ongoing_rc	Ongoing job status code (if known)
174
+ */
175
+static int iflinkwait_progress ( struct ifpoller *ifpoller ) {
176
+	struct net_device *netdev = ifpoller->netdev;
177
+	int ongoing_rc = netdev->link_rc;
178
+
179
+	/* Terminate successfully if link is up */
180
+	if ( ongoing_rc == 0 )
181
+		intf_close ( &ifpoller->job, 0 );
182
+
183
+	/* Otherwise, report link status as ongoing job status */
184
+	return ongoing_rc;
185
+}
186
+
107 187
 /**
108 188
  * Wait for link-up, with status indication
109 189
  *
110 190
  * @v netdev		Network device
111
- * @v max_wait_ms	Maximum time to wait, in ms
191
+ * @v timeout		Timeout period, in ticks
112 192
  */
113
-int iflinkwait ( struct net_device *netdev, unsigned int max_wait_ms ) {
114
-	int key;
193
+int iflinkwait ( struct net_device *netdev, unsigned long timeout ) {
115 194
 	int rc;
116 195
 
117
-	/* Allow link state to be updated */
118
-	netdev_poll ( netdev );
196
+	/* Ensure device is open */
197
+	if ( ( rc = ifopen ( netdev ) ) != 0 )
198
+		return rc;
119 199
 
200
+	/* Return immediately if link is already up */
201
+	netdev_poll ( netdev );
120 202
 	if ( netdev_link_ok ( netdev ) )
121 203
 		return 0;
122 204
 
123
-	printf ( "Waiting for link-up on %s...", netdev->name );
124
-
125
-	while ( 1 ) {
126
-		if ( netdev_link_ok ( netdev ) ) {
127
-			rc = 0;
128
-			break;
129
-		}
130
-		if ( max_wait_ms-- == 0 ) {
131
-			rc = netdev->link_rc;
132
-			break;
133
-		}
134
-		step();
135
-		if ( iskey() ) {
136
-			key = getchar();
137
-			if ( key == CTRL_C ) {
138
-				rc = -ECANCELED;
139
-				break;
140
-			}
141
-		}
142
-		mdelay ( 1 );
143
-	}
144
-
145
-	if ( rc == 0 ) {
146
-		printf ( " ok\n" );
147
-	} else {
148
-		printf ( " failed: %s\n", strerror ( rc ) );
149
-	}
150
-
151
-	return rc;
205
+	/* Wait for link-up */
206
+	printf ( "Waiting for link-up on %s", netdev->name );
207
+	return ifpoller_wait ( netdev, timeout, iflinkwait_progress );
152 208
 }

+ 2
- 4
src/usr/lotest.c View File

@@ -39,8 +39,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
39 39
  *
40 40
  */
41 41
 
42
-#define LINK_WAIT_MS 15000
43
-
44 42
 /**
45 43
  * Process received packet
46 44
  *
@@ -189,9 +187,9 @@ int loopback_test ( struct net_device *sender, struct net_device *receiver,
189 187
 		return rc;
190 188
 
191 189
 	/* Wait for link-up */
192
-	if ( ( rc = iflinkwait ( sender, LINK_WAIT_MS ) ) != 0 )
190
+	if ( ( rc = iflinkwait ( sender, 0 ) ) != 0 )
193 191
 		return rc;
194
-	if ( ( rc = iflinkwait ( receiver, LINK_WAIT_MS ) ) != 0 )
192
+	if ( ( rc = iflinkwait ( receiver, 0 ) ) != 0 )
195 193
 		return rc;
196 194
 
197 195
 	/* Allocate data buffer */

Loading…
Cancel
Save