aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Kenna <cjk@cs.unc.edu>2012-01-05 21:32:02 -0500
committerChristopher Kenna <cjk@cs.unc.edu>2012-01-05 21:32:02 -0500
commitc8b2f1313326bee25e847bd7f979c0eb2bba2883 (patch)
tree7b910621b6161a5f2bfbfdb0dc97c9b4ecae84a6
parent8a53287722d90631f08590e40c189fa89726eb72 (diff)
Plotting with different level-curves on the graphs.
-rwxr-xr-xplot_rtas12.py127
1 files changed, 69 insertions, 58 deletions
diff --git a/plot_rtas12.py b/plot_rtas12.py
index d5e9ed9..d65534e 100755
--- a/plot_rtas12.py
+++ b/plot_rtas12.py
@@ -50,26 +50,38 @@ def gnuplot_col(col_name):
50 return 1 + COLS[col_name] 50 return 1 + COLS[col_name]
51 51
52def get_sched_title(sched): 52def get_sched_title(sched):
53 SCHEDULERS = {'MC': 'Basic', 53 SCHEDULERS = {'MC': 'Basic:',
54 'MC-MERGE': 'IM + TM', 54 'MC-MERGE': 'IM + TM:',
55 'MC-MERGE-REDIR': 'IM + TM + WR'} 55 'MC-MERGE-REDIR': 'All:'}
56 return SCHEDULERS[sched] 56 return SCHEDULERS[sched]
57 57
58def get_overhead_title(ov): 58def get_overhead_title(ov):
59 OV = {'SCHED': '(A, B, C)', 59 OV = {'LVLA-SCHED': 'A',
60 'LVLA-SCHED': '(A)', 60 'LVLB-SCHED': 'B',
61 'RELEASE': '(A, B, C)', 61 'LVLC-SCHED': 'C',
62 'LVLA-RELEASE': '(A)'} 62 'LVLA-RELEASE': 'A',
63 'LVLB-RELEASE': 'B',
64 'LVLC-RELEASE': 'C',
65}
63 return OV[ov] 66 return OV[ov]
64 67
68def get_line_style(sched, o_type):
69 S = { 'MC' : {'LVLA': 1, 'LVLB': 4, 'LVLC': 7},
70 'MC-MERGE': {'LVLA': 2, 'LVLB': 5, 'LVLC': 8},
71 'MC-MERGE-REDIR': {'LVLA': 3, 'LVLB': 6, 'LVLC': 9}}
72 o = o_type.split('-')[0]
73 return 'linespoints linestyle {0}'.format(S[sched][o])
74
75def get_graph_fname(directory, o_type, levels, ycol_type):
76 return '{0}/overhead={1}-levels={2}-type={3}'.format(directory, o_type,
77 levels, ycol_type)
78
65def set_plot_opts(opts, p): 79def set_plot_opts(opts, p):
66 p.rounded_caps = True 80 p.rounded_caps = True
67 p.font = 'Helvetica' 81 p.font = 'Helvetica'
68 p.default_style = 'linespoints lw 2.5'
69 p.default_style += ' smooth bezier'
70 p.key = 'off' 82 p.key = 'off'
71 p.monochrome = False 83 p.monochrome = False
72 p.dashed_lines = False 84 p.dashed_lines = True
73 p.xrange = (18, 122) 85 p.xrange = (18, 122)
74 p.yrange = (0, '') 86 p.yrange = (0, '')
75 87
@@ -88,27 +100,18 @@ def set_plot_opts(opts, p):
88 p.output = '{0}.{1}'.format(p.output, ext) 100 p.output = '{0}.{1}'.format(p.output, ext)
89 p.format = ext 101 p.format = ext
90 102
91 for i, c in enumerate(p.curves):
92 c.style = "linespoints ls %d" % (i + 1)
93
94 try:
95 # don't use yellow if we have this curve
96 p.curves[5].style = "linespoints ls 7"
97 except IndexError:
98 pass
99
100 p.line_styles = [ 103 p.line_styles = [
101 (1, "lw {0} ps {1}".format(line_width, point_size)), 104 (1, 'lt 1 pt 1 lw {0} ps {1} lc rgbcolor "#ff0000"'.format(line_width, point_size)),
102 (2, "lw {0} ps {1}".format(line_width, point_size)), 105 (2, 'lt 1 pt 4 lw {0} ps {1} lc rgbcolor "#00ff00"'.format(line_width, point_size)),
103 (3, "lw {0} ps {1}".format(line_width, point_size)), 106 (3, 'lt 1 pt 7 lw {0} ps {1} lc rgbcolor "#0000ff"'.format(line_width, point_size)),
104 (4, "lw {0} ps {1}".format(line_width, point_size)), 107 (4, 'lt 2 pt 1 lw {0} ps {1} lc rgbcolor "#ff0000"'.format(line_width, point_size)),
105 (5, 'pt 6 lw {0} ps {1} lc rgbcolor "#ff910d"'.format(line_width, point_size)), 108 (5, 'lt 2 pt 4 lw {0} ps {1} lc rgbcolor "#00ff00"'.format(line_width, point_size)),
106 (6, "pt 7 lw {0} ps {1}".format(line_width, point_size)), 109 (6, 'lt 2 pt 7 lw {0} ps {1} lc rgbcolor "#0000ff"'.format(line_width, point_size)),
107 (7, 'lw {0} ps {1} lc rgbcolor "#000000"'.format(line_width, point_size)), 110 (7, 'lt 3 pt 1 lw {0} ps {1} lc rgbcolor "#ff0000"'.format(line_width, point_size)),
108 (8, "lw {0} ps {1}".format(line_width, point_size)), 111 (8, 'lt 3 pt 4 lw {0} ps {1} lc rgbcolor "#00ff00"'.format(line_width, point_size)),
112 (9, 'lt 3 pt 7 lw {0} ps {1} lc rgbcolor "#0000ff"'.format(line_width, point_size)),
109 ] 113 ]
110 114
111
112def get_data_matrix(fname): 115def get_data_matrix(fname):
113 ret = [] 116 ret = []
114 with open(fname, 'r') as f: 117 with open(fname, 'r') as f:
@@ -162,34 +165,36 @@ def include_level_a_releases(data_dir, o_type, scheduler, ycol):
162 f.file.flush() 165 f.file.flush()
163 return (f.name, f) 166 return (f.name, f)
164 167
168def add_key_to_plot(p):
169 p.key = 'on tmargin center horizontal maxcolumns 3'
170 p.size = ('8.5cm', '6.25cm')
165 171
166def plot_release(opts, data_dir, ycol, title, fname): 172def plot_release(opts, data_dir, ycol_name, title, levels):
167 p = Plot() 173 levels = levels.upper()
168 p.output = '{0}/{1}'.format(data_dir, fname)
169 refs = [] # need to save reference to file handle so it is not deleted 174 refs = [] # need to save reference to file handle so it is not deleted
175 p = Plot()
176 p.output = get_graph_fname(data_dir, 'RELEASE', levels, ycol_name)
170 177
171 for o_type in ['RELEASE', 'LVLA-RELEASE']: 178 for o_type in ['LVL{0}-RELEASE'.format(l) for l in levels]:
172 for sched in SCHEDULERS: 179 for sched in SCHEDULERS:
173 if o_type == 'RELEASE': 180 # if o_type == 'RELEASE':
174 # we have to make the regular release include the level-A 181 # # we have to make the regular release include the level-A
175 # releases 182 # # releases
176 fname, ref = include_level_a_releases(data_dir, o_type, 183 # fname, ref = include_level_a_releases(data_dir, o_type,
177 sched, ycol) 184 # sched, ycol)
178 refs.append(ref) 185 # refs.append(ref)
179 else: 186 # else:
180 fname = '{0}/scheduler={1}_overhead={2}.csv'.format(data_dir, sched, o_type) 187 fname = '{0}/scheduler={1}_overhead={2}.csv'.format(data_dir, sched, o_type)
181 ti = '{0} {1}'.format(get_sched_title(sched), get_overhead_title(o_type)) 188 ti = '{0} {1}'.format(get_sched_title(sched), get_overhead_title(o_type))
182 p.curves += [curve(fname=fname, xcol=gnuplot_col('n_tasks'), 189 c = curve(fname=fname, xcol=gnuplot_col('n_tasks'),
183 ycol=ycol, title=ti)] 190 ycol=gnuplot_col(ycol_name), title=ti,
191 style=get_line_style(sched, o_type))
192 p.curves += [c]
184 p.xlabel = 'number of tasks' 193 p.xlabel = 'number of tasks'
185 p.ylabel = 'overhead (microseconds)' 194 p.ylabel = 'overhead (microseconds)'
186 set_plot_opts(opts, p) 195 set_plot_opts(opts, p)
187 if gnuplot_col('avg') == ycol: 196 if 'avg' == ycol_name and 'ABC' == levels:
188 # make this graph's y-scale match the scale on the average-case 197 add_key_to_plot(p)
189 # scheduling overhead graph because they are next to each other
190 p.yrange = (0, 16)
191 # it gets the key
192 p.key = 'top left'
193 p.gnuplot_exec() 198 p.gnuplot_exec()
194 199
195def plot_release_jim(opts, data_dir, ycol, title, fname): 200def plot_release_jim(opts, data_dir, ycol, title, fname):
@@ -210,19 +215,24 @@ def plot_release_jim(opts, data_dir, ycol, title, fname):
210 p.title = 'level-A worst-case release overhead' 215 p.title = 'level-A worst-case release overhead'
211 p.gnuplot_exec() 216 p.gnuplot_exec()
212 217
213def plot_sched(opts, data_dir, ycol, title, fname): 218def plot_sched(opts, data_dir, ycol_name, title, levels):
219 levels = levels.upper()
214 p = Plot() 220 p = Plot()
215 p.output = '{0}/{1}'.format(data_dir, fname) 221 p.output = get_graph_fname(data_dir, 'SCHED', levels, ycol_name)
216 222
217 for o_type in ['SCHED', 'LVLA-SCHED']: 223 for o_type in ['LVL{0}-SCHED'.format(l) for l in levels]:
218 for sched in SCHEDULERS: 224 for sched in SCHEDULERS:
219 fname = '{0}/scheduler={1}_overhead={2}.csv'.format(data_dir, sched, o_type) 225 fname = '{0}/scheduler={1}_overhead={2}.csv'.format(data_dir, sched, o_type)
220 ti = '{0} {1}'.format(get_sched_title(sched), get_overhead_title(o_type)) 226 ti = '{0} {1}'.format(get_sched_title(sched), get_overhead_title(o_type))
221 p.curves += [curve(fname=fname, xcol=gnuplot_col('n_tasks'), 227 c = curve(fname=fname, xcol=gnuplot_col('n_tasks'),
222 ycol=ycol, title=ti)] 228 ycol=gnuplot_col(ycol_name), title=ti,
229 style=get_line_style(sched, o_type))
230 p.curves += [c]
223 p.xlabel = 'number of tasks' 231 p.xlabel = 'number of tasks'
224 p.ylabel = 'overhead (microseconds)' 232 p.ylabel = 'overhead (microseconds)'
225 set_plot_opts(opts, p) 233 set_plot_opts(opts, p)
234 if 'avg' == ycol_name and 'ABC' == levels:
235 add_key_to_plot(p)
226 p.gnuplot_exec() 236 p.gnuplot_exec()
227 237
228 238
@@ -234,11 +244,12 @@ def main():
234 usage('missing args') 244 usage('missing args')
235 245
236 data_dir = extra[0] 246 data_dir = extra[0]
237 plot_sched(opts, data_dir, gnuplot_col('max'), 'worst-case scheduling overhead', 'overhead=SCHED_type=MAX') 247 for levels in ('ABC', 'AC', 'BC'):
238 plot_release(opts, data_dir, gnuplot_col('max'), 'worst-case release overhead', 'overhead=RELEASE_type=MAX') 248 plot_sched(opts, data_dir, 'max', 'worst-case scheduling overhead', levels)
239 plot_sched(opts, data_dir, gnuplot_col('avg'), 'average-case scheduling overhead', 'overhead=SCHED_type=AVG') 249 plot_release(opts, data_dir, 'max', 'worst-case release overhead', levels)
240 plot_release(opts, data_dir, gnuplot_col('avg'), 'average-case release overhead', 'overhead=RELEASE_type=AVG') 250 plot_sched(opts, data_dir, 'avg', 'average-case scheduling overhead', levels)
241 plot_release_jim(opts, data_dir, gnuplot_col('max'), 'worst-case release overhead', 'overhead=RELEASE_type=MAX_for-jim=1') 251 plot_release(opts, data_dir, 'avg', 'average-case release overhead', levels)
252 #plot_release_jim(opts, data_dir, 'max', 'worst-case release overhead', 'overhead=RELEASE_type=MAX_for-jim=1')
242 253
243if __name__ == '__main__': 254if __name__ == '__main__':
244 main() 255 main()
ass="hl opt">); lance->RAP = CSR89; /* Chip ID */ version |= swapw(lance->RDP)<<16; if ((version & 0x00000fff) != 0x00000003) { printk(KERN_WARNING "ariadne_open: Couldn't find AMD Ethernet Chip\n"); return -EAGAIN; } if ((version & 0x0ffff000) != 0x00003000) { printk(KERN_WARNING "ariadne_open: Couldn't find Am79C960 (Wrong part " "number = %ld)\n", (version & 0x0ffff000)>>12); return -EAGAIN; } #if 0 printk(KERN_DEBUG "ariadne_open: Am79C960 (PCnet-ISA) Revision %ld\n", (version & 0xf0000000)>>28); #endif ariadne_init_ring(dev); /* Miscellaneous Stuff */ lance->RAP = CSR3; /* Interrupt Masks and Deferral Control */ lance->RDP = 0x0000; lance->RAP = CSR4; /* Test and Features Control */ lance->RDP = DPOLL|APAD_XMT|MFCOM|RCVCCOM|TXSTRTM|JABM; /* Set the Multicast Table */ lance->RAP = CSR8; /* Logical Address Filter, LADRF[15:0] */ lance->RDP = 0x0000; lance->RAP = CSR9; /* Logical Address Filter, LADRF[31:16] */ lance->RDP = 0x0000; lance->RAP = CSR10; /* Logical Address Filter, LADRF[47:32] */ lance->RDP = 0x0000; lance->RAP = CSR11; /* Logical Address Filter, LADRF[63:48] */ lance->RDP = 0x0000; /* Set the Ethernet Hardware Address */ lance->RAP = CSR12; /* Physical Address Register, PADR[15:0] */ lance->RDP = ((u_short *)&dev->dev_addr[0])[0]; lance->RAP = CSR13; /* Physical Address Register, PADR[31:16] */ lance->RDP = ((u_short *)&dev->dev_addr[0])[1]; lance->RAP = CSR14; /* Physical Address Register, PADR[47:32] */ lance->RDP = ((u_short *)&dev->dev_addr[0])[2]; /* Set the Init Block Mode */ lance->RAP = CSR15; /* Mode Register */ lance->RDP = 0x0000; /* Set the Transmit Descriptor Ring Pointer */ lance->RAP = CSR30; /* Base Address of Transmit Ring */ lance->RDP = swloww(ARIADNE_RAM+offsetof(struct lancedata, tx_ring)); lance->RAP = CSR31; /* Base Address of transmit Ring */ lance->RDP = swhighw(ARIADNE_RAM+offsetof(struct lancedata, tx_ring)); /* Set the Receive Descriptor Ring Pointer */ lance->RAP = CSR24; /* Base Address of Receive Ring */ lance->RDP = swloww(ARIADNE_RAM+offsetof(struct lancedata, rx_ring)); lance->RAP = CSR25; /* Base Address of Receive Ring */ lance->RDP = swhighw(ARIADNE_RAM+offsetof(struct lancedata, rx_ring)); /* Set the Number of RX and TX Ring Entries */ lance->RAP = CSR76; /* Receive Ring Length */ lance->RDP = swapw(((u_short)-RX_RING_SIZE)); lance->RAP = CSR78; /* Transmit Ring Length */ lance->RDP = swapw(((u_short)-TX_RING_SIZE)); /* Enable Media Interface Port Auto Select (10BASE-2/10BASE-T) */ lance->RAP = ISACSR2; /* Miscellaneous Configuration */ lance->IDP = ASEL; /* LED Control */ lance->RAP = ISACSR5; /* LED1 Status */ lance->IDP = PSE|XMTE; lance->RAP = ISACSR6; /* LED2 Status */ lance->IDP = PSE|COLE; lance->RAP = ISACSR7; /* LED3 Status */ lance->IDP = PSE|RCVE; netif_start_queue(dev); i = request_irq(IRQ_AMIGA_PORTS, ariadne_interrupt, IRQF_SHARED, dev->name, dev); if (i) return i; lance->RAP = CSR0; /* PCnet-ISA Controller Status */ lance->RDP = INEA|STRT; return 0; } static void ariadne_init_ring(struct net_device *dev) { struct ariadne_private *priv = netdev_priv(dev); volatile struct lancedata *lancedata = (struct lancedata *)dev->mem_start; int i; netif_stop_queue(dev); priv->tx_full = 0; priv->cur_rx = priv->cur_tx = 0; priv->dirty_tx = 0; /* Set up TX Ring */ for (i = 0; i < TX_RING_SIZE; i++) { volatile struct TDRE *t = &lancedata->tx_ring[i]; t->TMD0 = swloww(ARIADNE_RAM+offsetof(struct lancedata, tx_buff[i])); t->TMD1 = swhighw(ARIADNE_RAM+offsetof(struct lancedata, tx_buff[i])) | TF_STP | TF_ENP; t->TMD2 = swapw((u_short)-PKT_BUF_SIZE); t->TMD3 = 0; priv->tx_ring[i] = &lancedata->tx_ring[i]; priv->tx_buff[i] = lancedata->tx_buff[i]; #if 0 printk(KERN_DEBUG "TX Entry %2d at %p, Buf at %p\n", i, &lancedata->tx_ring[i], lancedata->tx_buff[i]); #endif } /* Set up RX Ring */ for (i = 0; i < RX_RING_SIZE; i++) { volatile struct RDRE *r = &lancedata->rx_ring[i]; r->RMD0 = swloww(ARIADNE_RAM+offsetof(struct lancedata, rx_buff[i])); r->RMD1 = swhighw(ARIADNE_RAM+offsetof(struct lancedata, rx_buff[i])) | RF_OWN; r->RMD2 = swapw((u_short)-PKT_BUF_SIZE); r->RMD3 = 0x0000; priv->rx_ring[i] = &lancedata->rx_ring[i]; priv->rx_buff[i] = lancedata->rx_buff[i]; #if 0 printk(KERN_DEBUG "RX Entry %2d at %p, Buf at %p\n", i, &lancedata->rx_ring[i], lancedata->rx_buff[i]); #endif } } static int ariadne_close(struct net_device *dev) { struct ariadne_private *priv = netdev_priv(dev); volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; netif_stop_queue(dev); lance->RAP = CSR112; /* Missed Frame Count */ priv->stats.rx_missed_errors = swapw(lance->RDP); lance->RAP = CSR0; /* PCnet-ISA Controller Status */ if (ariadne_debug > 1) { printk(KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n", dev->name, lance->RDP); printk(KERN_DEBUG "%s: %lu packets missed\n", dev->name, priv->stats.rx_missed_errors); } /* We stop the LANCE here -- it occasionally polls memory if we don't. */ lance->RDP = STOP; free_irq(IRQ_AMIGA_PORTS, dev); return 0; } static inline void ariadne_reset(struct net_device *dev) { volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; lance->RAP = CSR0; /* PCnet-ISA Controller Status */ lance->RDP = STOP; ariadne_init_ring(dev); lance->RDP = INEA|STRT; netif_start_queue(dev); } static irqreturn_t ariadne_interrupt(int irq, void *data) { struct net_device *dev = (struct net_device *)data; volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; struct ariadne_private *priv; int csr0, boguscnt; int handled = 0; if (dev == NULL) { printk(KERN_WARNING "ariadne_interrupt(): irq for unknown device.\n"); return IRQ_NONE; } lance->RAP = CSR0; /* PCnet-ISA Controller Status */ if (!(lance->RDP & INTR)) /* Check if any interrupt has been */ return IRQ_NONE; /* generated by the board. */ priv = netdev_priv(dev); boguscnt = 10; while ((csr0 = lance->RDP) & (ERR|RINT|TINT) && --boguscnt >= 0) { /* Acknowledge all of the current interrupt sources ASAP. */ lance->RDP = csr0 & ~(INEA|TDMD|STOP|STRT|INIT); #if 0 if (ariadne_debug > 5) { printk(KERN_DEBUG "%s: interrupt csr0=%#2.2x new csr=%#2.2x.", dev->name, csr0, lance->RDP); printk("["); if (csr0 & INTR) printk(" INTR"); if (csr0 & INEA) printk(" INEA"); if (csr0 & RXON) printk(" RXON"); if (csr0 & TXON) printk(" TXON"); if (csr0 & TDMD) printk(" TDMD"); if (csr0 & STOP) printk(" STOP"); if (csr0 & STRT) printk(" STRT"); if (csr0 & INIT) printk(" INIT"); if (csr0 & ERR) printk(" ERR"); if (csr0 & BABL) printk(" BABL"); if (csr0 & CERR) printk(" CERR"); if (csr0 & MISS) printk(" MISS"); if (csr0 & MERR) printk(" MERR"); if (csr0 & RINT) printk(" RINT"); if (csr0 & TINT) printk(" TINT"); if (csr0 & IDON) printk(" IDON"); printk(" ]\n"); } #endif if (csr0 & RINT) { /* Rx interrupt */ handled = 1; ariadne_rx(dev); } if (csr0 & TINT) { /* Tx-done interrupt */ int dirty_tx = priv->dirty_tx; handled = 1; while (dirty_tx < priv->cur_tx) { int entry = dirty_tx % TX_RING_SIZE; int status = lowb(priv->tx_ring[entry]->TMD1); if (status & TF_OWN) break; /* It still hasn't been Txed */ priv->tx_ring[entry]->TMD1 &= 0xff00; if (status & TF_ERR) { /* There was an major error, log it. */ int err_status = priv->tx_ring[entry]->TMD3; priv->stats.tx_errors++; if (err_status & EF_RTRY) priv->stats.tx_aborted_errors++; if (err_status & EF_LCAR) priv->stats.tx_carrier_errors++; if (err_status & EF_LCOL) priv->stats.tx_window_errors++; if (err_status & EF_UFLO) { /* Ackk! On FIFO errors the Tx unit is turned off! */ priv->stats.tx_fifo_errors++; /* Remove this verbosity later! */ printk(KERN_ERR "%s: Tx FIFO error! Status %4.4x.\n", dev->name, csr0); /* Restart the chip. */ lance->RDP = STRT; } } else { if (status & (TF_MORE|TF_ONE)) priv->stats.collisions++; priv->stats.tx_packets++; } dirty_tx++; } #ifndef final_version if (priv->cur_tx - dirty_tx >= TX_RING_SIZE) { printk(KERN_ERR "out-of-sync dirty pointer, %d vs. %d, " "full=%d.\n", dirty_tx, priv->cur_tx, priv->tx_full); dirty_tx += TX_RING_SIZE; } #endif if (priv->tx_full && netif_queue_stopped(dev) && dirty_tx > priv->cur_tx - TX_RING_SIZE + 2) { /* The ring is no longer full. */ priv->tx_full = 0; netif_wake_queue(dev); } priv->dirty_tx = dirty_tx; } /* Log misc errors. */ if (csr0 & BABL) { handled = 1; priv->stats.tx_errors++; /* Tx babble. */ } if (csr0 & MISS) { handled = 1; priv->stats.rx_errors++; /* Missed a Rx frame. */ } if (csr0 & MERR) { handled = 1; printk(KERN_ERR "%s: Bus master arbitration failure, status " "%4.4x.\n", dev->name, csr0); /* Restart the chip. */ lance->RDP = STRT; } } /* Clear any other interrupt, and set interrupt enable. */ lance->RAP = CSR0; /* PCnet-ISA Controller Status */ lance->RDP = INEA|BABL|CERR|MISS|MERR|IDON; #if 0 if (ariadne_debug > 4) printk(KERN_DEBUG "%s: exiting interrupt, csr%d=%#4.4x.\n", dev->name, lance->RAP, lance->RDP); #endif return IRQ_RETVAL(handled); } static void ariadne_tx_timeout(struct net_device *dev) { volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; printk(KERN_ERR "%s: transmit timed out, status %4.4x, resetting.\n", dev->name, lance->RDP); ariadne_reset(dev); netif_wake_queue(dev); } static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ariadne_private *priv = netdev_priv(dev); volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; int entry; unsigned long flags; int len = skb->len; #if 0 if (ariadne_debug > 3) { lance->RAP = CSR0; /* PCnet-ISA Controller Status */ printk(KERN_DEBUG "%s: ariadne_start_xmit() called, csr0 %4.4x.\n", dev->name, lance->RDP); lance->RDP = 0x0000; } #endif /* FIXME: is the 79C960 new enough to do its own padding right ? */ if (skb->len < ETH_ZLEN) { if (skb_padto(skb, ETH_ZLEN)) return 0; len = ETH_ZLEN; } /* Fill in a Tx ring entry */ #if 0 printk(KERN_DEBUG "TX pkt type 0x%04x from ", ((u_short *)skb->data)[6]); { int i; u_char *ptr = &((u_char *)skb->data)[6]; for (i = 0; i < 6; i++) printk("%02x", ptr[i]); } printk(" to "); { int i; u_char *ptr = (u_char *)skb->data; for (i = 0; i < 6; i++) printk("%02x", ptr[i]); } printk(" data 0x%08x len %d\n", (int)skb->data, (int)skb->len); #endif local_irq_save(flags); entry = priv->cur_tx % TX_RING_SIZE; /* Caution: the write order is important here, set the base address with the "ownership" bits last. */ priv->tx_ring[entry]->TMD2 = swapw((u_short)-skb->len); priv->tx_ring[entry]->TMD3 = 0x0000; memcpyw(priv->tx_buff[entry], (u_short *)skb->data, len); #if 0 { int i, len; len = skb->len > 64 ? 64 : skb->len; len >>= 1; for (i = 0; i < len; i += 8) { int j; printk(KERN_DEBUG "%04x:", i); for (j = 0; (j < 8) && ((i+j) < len); j++) { if (!(j & 1)) printk(" "); printk("%04x", priv->tx_buff[entry][i+j]);