]>
Commit | Line | Data |
---|---|---|
1 | Index: vl.c | |
2 | =================================================================== | |
3 | RCS file: /sources/qemu/qemu/vl.c,v | |
4 | retrieving revision 1.157 | |
5 | diff -u -p -r1.157 vl.c | |
6 | --- vl.c 18 Dec 2005 20:34:32 -0000 1.157 | |
7 | +++ vl.c 20 Dec 2005 21:11:37 -0000 | |
8 | @@ -1768,13 +1768,16 @@ VLANState *qemu_find_vlan(int id) | |
9 | } | |
10 | ||
11 | VLANClientState *qemu_new_vlan_client(VLANState *vlan, | |
12 | - IOReadHandler *fd_read, void *opaque) | |
13 | + IOReadHandler *fd_read, | |
14 | + IOCanRWHandler *fd_can_read, | |
15 | + void *opaque) | |
16 | { | |
17 | VLANClientState *vc, **pvc; | |
18 | vc = qemu_mallocz(sizeof(VLANClientState)); | |
19 | if (!vc) | |
20 | return NULL; | |
21 | vc->fd_read = fd_read; | |
22 | + vc->fd_can_read = fd_can_read; | |
23 | vc->opaque = opaque; | |
24 | vc->vlan = vlan; | |
25 | ||
26 | @@ -1786,6 +1789,20 @@ VLANClientState *qemu_new_vlan_client(VL | |
27 | return vc; | |
28 | } | |
29 | ||
30 | +int qemu_can_send_packet(VLANClientState *vc1) | |
31 | +{ | |
32 | + VLANState *vlan = vc1->vlan; | |
33 | + VLANClientState *vc; | |
34 | + | |
35 | + for(vc = vlan->first_client; vc != NULL; vc = vc->next) { | |
36 | + if (vc != vc1) { | |
37 | + if (vc->fd_can_read && !vc->fd_can_read(vc->opaque)) | |
38 | + return 0; | |
39 | + } | |
40 | + } | |
41 | + return 1; | |
42 | +} | |
43 | + | |
44 | void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size) | |
45 | { | |
46 | VLANState *vlan = vc1->vlan; | |
47 | @@ -1811,7 +1828,7 @@ static VLANClientState *slirp_vc; | |
48 | ||
49 | int slirp_can_output(void) | |
50 | { | |
51 | - return 1; | |
52 | + return qemu_can_send_packet(slirp_vc); | |
53 | } | |
54 | ||
55 | void slirp_output(const uint8_t *pkt, int pkt_len) | |
56 | @@ -1839,7 +1856,7 @@ static int net_slirp_init(VLANState *vla | |
57 | slirp_init(); | |
58 | } | |
59 | slirp_vc = qemu_new_vlan_client(vlan, | |
60 | - slirp_receive, NULL); | |
61 | + slirp_receive, NULL, NULL); | |
62 | snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector"); | |
63 | return 0; | |
64 | } | |
65 | @@ -2024,7 +2041,7 @@ static TAPState *net_tap_fd_init(VLANSta | |
66 | if (!s) | |
67 | return NULL; | |
68 | s->fd = fd; | |
69 | - s->vc = qemu_new_vlan_client(vlan, tap_receive, s); | |
70 | + s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s); | |
71 | qemu_set_fd_handler(s->fd, tap_send, NULL, s); | |
72 | snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd); | |
73 | return s; | |
74 | @@ -2327,7 +2344,7 @@ static NetSocketState *net_socket_fd_ini | |
75 | return NULL; | |
76 | s->fd = fd; | |
77 | ||
78 | - s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, s); | |
79 | + s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, NULL, s); | |
80 | qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s); | |
81 | ||
82 | /* mcast: save bound address as dst */ | |
83 | @@ -2355,7 +2372,7 @@ static NetSocketState *net_socket_fd_ini | |
84 | return NULL; | |
85 | s->fd = fd; | |
86 | s->vc = qemu_new_vlan_client(vlan, | |
87 | - net_socket_receive, s); | |
88 | + net_socket_receive, NULL, s); | |
89 | snprintf(s->vc->info_str, sizeof(s->vc->info_str), | |
90 | "socket: fd=%d", fd); | |
91 | if (is_connected) { | |
92 | Index: vl.h | |
93 | =================================================================== | |
94 | RCS file: /sources/qemu/qemu/vl.h,v | |
95 | retrieving revision 1.99 | |
96 | diff -u -p -r1.99 vl.h | |
97 | --- vl.h 18 Dec 2005 20:34:32 -0000 1.99 | |
98 | +++ vl.h 20 Dec 2005 21:11:38 -0000 | |
99 | @@ -279,6 +279,9 @@ typedef struct VLANClientState VLANClien | |
100 | ||
101 | struct VLANClientState { | |
102 | IOReadHandler *fd_read; | |
103 | + /* Packets may still be sent if this returns zero. It's used to | |
104 | + rate-limit the slirp code. */ | |
105 | + IOCanRWHandler *fd_can_read; | |
106 | void *opaque; | |
107 | struct VLANClientState *next; | |
108 | struct VLANState *vlan; | |
109 | @@ -293,8 +296,12 @@ typedef struct VLANState { | |
110 | ||
111 | VLANState *qemu_find_vlan(int id); | |
112 | VLANClientState *qemu_new_vlan_client(VLANState *vlan, | |
113 | - IOReadHandler *fd_read, void *opaque); | |
114 | + IOReadHandler *fd_read, | |
115 | + IOCanRWHandler *fd_can_read, | |
116 | + void *opaque); | |
117 | +int qemu_can_send_packet(VLANClientState *vc); | |
118 | void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size); | |
119 | +void qemu_handler_true(void *opaque); | |
120 | ||
121 | void do_info_network(void); | |
122 | ||
123 | Index: hw/lance.c | |
124 | =================================================================== | |
125 | RCS file: /sources/qemu/qemu/hw/lance.c,v | |
126 | retrieving revision 1.5 | |
127 | diff -u -p -r1.5 lance.c | |
128 | --- hw/lance.c 15 Nov 2005 22:16:05 -0000 1.5 | |
129 | +++ hw/lance.c 20 Dec 2005 21:11:38 -0000 | |
130 | @@ -283,6 +283,11 @@ static CPUWriteMemoryFunc *lance_mem_wri | |
131 | ||
132 | #define MIN_BUF_SIZE 60 | |
133 | ||
134 | +static void lance_can_receive(void *opaque) | |
135 | +{ | |
136 | + return 1; | |
137 | +} | |
138 | + | |
139 | static void lance_receive(void *opaque, const uint8_t *buf, int size) | |
140 | { | |
141 | LANCEState *s = opaque; | |
142 | @@ -440,7 +445,7 @@ void lance_init(NICInfo *nd, int irq, ui | |
143 | ||
144 | lance_reset(s); | |
145 | ||
146 | - s->vc = qemu_new_vlan_client(nd->vlan, lance_receive, s); | |
147 | + s->vc = qemu_new_vlan_client(nd->vlan, lance_receive, lance_can_receive, s); | |
148 | ||
149 | snprintf(s->vc->info_str, sizeof(s->vc->info_str), | |
150 | "lance macaddr=%02x:%02x:%02x:%02x:%02x:%02x", | |
151 | Index: hw/ne2000.c | |
152 | =================================================================== | |
153 | RCS file: /sources/qemu/qemu/hw/ne2000.c,v | |
154 | retrieving revision 1.17 | |
155 | diff -u -p -r1.17 ne2000.c | |
156 | --- hw/ne2000.c 22 Nov 2005 20:16:13 -0000 1.17 | |
157 | +++ hw/ne2000.c 20 Dec 2005 21:11:38 -0000 | |
158 | @@ -200,14 +200,10 @@ static int compute_mcast_idx(const uint8 | |
159 | return (crc >> 26); | |
160 | } | |
161 | ||
162 | -/* return the max buffer size if the NE2000 can receive more data */ | |
163 | -static int ne2000_can_receive(void *opaque) | |
164 | +static int ne2000_buffer_full(NE2000State *s) | |
165 | { | |
166 | - NE2000State *s = opaque; | |
167 | int avail, index, boundary; | |
168 | - | |
169 | - if (s->cmd & E8390_STOP) | |
170 | - return 0; | |
171 | + | |
172 | index = s->curpag << 8; | |
173 | boundary = s->boundary << 8; | |
174 | if (index < boundary) | |
175 | @@ -215,8 +211,17 @@ static int ne2000_can_receive(void *opaq | |
176 | else | |
177 | avail = (s->stop - s->start) - (index - boundary); | |
178 | if (avail < (MAX_ETH_FRAME_SIZE + 4)) | |
179 | - return 0; | |
180 | - return MAX_ETH_FRAME_SIZE; | |
181 | + return 1; | |
182 | + return 0; | |
183 | +} | |
184 | + | |
185 | +static int ne2000_can_receive(void *opaque) | |
186 | +{ | |
187 | + NE2000State *s = opaque; | |
188 | + | |
189 | + if (s->cmd & E8390_STOP) | |
190 | + return 1; | |
191 | + return !ne2000_buffer_full(s); | |
192 | } | |
193 | ||
194 | #define MIN_BUF_SIZE 60 | |
195 | @@ -234,7 +239,7 @@ static void ne2000_receive(void *opaque, | |
196 | printf("NE2000: received len=%d\n", size); | |
197 | #endif | |
198 | ||
199 | - if (!ne2000_can_receive(s)) | |
200 | + if (s->cmd & E8390_STOP || ne2000_buffer_full(s)) | |
201 | return; | |
202 | ||
203 | /* XXX: check this */ | |
204 | @@ -715,7 +720,8 @@ void isa_ne2000_init(int base, int irq, | |
205 | ||
206 | ne2000_reset(s); | |
207 | ||
208 | - s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive, s); | |
209 | + s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive, | |
210 | + ne2000_can_receive, s); | |
211 | ||
212 | snprintf(s->vc->info_str, sizeof(s->vc->info_str), | |
213 | "ne2000 macaddr=%02x:%02x:%02x:%02x:%02x:%02x", | |
214 | @@ -784,7 +790,8 @@ void pci_ne2000_init(PCIBus *bus, NICInf | |
215 | s->pci_dev = (PCIDevice *)d; | |
216 | memcpy(s->macaddr, nd->macaddr, 6); | |
217 | ne2000_reset(s); | |
218 | - s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive, s); | |
219 | + s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive, | |
220 | + ne2000_can_receive, s); | |
221 | ||
222 | snprintf(s->vc->info_str, sizeof(s->vc->info_str), | |
223 | "ne2000 pci macaddr=%02x:%02x:%02x:%02x:%02x:%02x", | |
224 | Index: hw/smc91c111.c | |
225 | =================================================================== | |
226 | RCS file: /sources/qemu/qemu/hw/smc91c111.c,v | |
227 | retrieving revision 1.2 | |
228 | diff -u -p -r1.2 smc91c111.c | |
229 | --- hw/smc91c111.c 18 Dec 2005 17:39:52 -0000 1.2 | |
230 | +++ hw/smc91c111.c 20 Dec 2005 21:11:38 -0000 | |
231 | @@ -593,6 +593,17 @@ static uint32_t smc91c111_readl(void *op | |
232 | return val; | |
233 | } | |
234 | ||
235 | +static int smc91c111_can_receive(void *opaque) | |
236 | +{ | |
237 | + smc91c111_state *s = (smc91c111_state *)opaque; | |
238 | + | |
239 | + if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST)) | |
240 | + return 1; | |
241 | + if (s->allocated == (1 << NUM_PACKETS) - 1) | |
242 | + return 0; | |
243 | + return 1; | |
244 | +} | |
245 | + | |
246 | static void smc91c111_receive(void *opaque, const uint8_t *buf, int size) | |
247 | { | |
248 | smc91c111_state *s = (smc91c111_state *)opaque; | |
249 | @@ -697,6 +708,7 @@ void smc91c111_init(NICInfo *nd, uint32_ | |
250 | ||
251 | smc91c111_reset(s); | |
252 | ||
253 | - s->vc = qemu_new_vlan_client(nd->vlan, smc91c111_receive, s); | |
254 | + s->vc = qemu_new_vlan_client(nd->vlan, smc91c111_receive, | |
255 | + smc91c111_can_receive, s); | |
256 | /* ??? Save/restore. */ | |
257 | } |