3 * linux/drivers/s390/net/qeth_fs.c ($Revision: 1.16 $)
5 * Linux on zSeries OSA Express and HiperSockets support
6 * This file contains code related to procfs.
8 * Copyright 2000,2003 IBM Corporation
10 * Author(s): Thomas Spatzier <tspat@de.ibm.com>
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/proc_fs.h>
16 #include <linux/seq_file.h>
17 #include <linux/list.h>
18 #include <linux/rwsem.h>
24 const char *VERSION_QETH_PROC_C
= "$Revision: 1.16 $";
26 /***** /proc/qeth *****/
27 #define QETH_PROCFILE_NAME "qeth"
28 static struct proc_dir_entry
*qeth_procfile
;
31 qeth_procfile_seq_match(struct device
*dev
, void *data
)
37 qeth_procfile_seq_start(struct seq_file
*s
, loff_t
*offset
)
39 struct device
*dev
= NULL
;
42 down_read(&qeth_ccwgroup_driver
.driver
.bus
->subsys
.rwsem
);
44 return SEQ_START_TOKEN
;
46 dev
= driver_find_device(&qeth_ccwgroup_driver
.driver
, dev
,
47 NULL
, qeth_procfile_seq_match
);
56 qeth_procfile_seq_stop(struct seq_file
*s
, void* it
)
58 up_read(&qeth_ccwgroup_driver
.driver
.bus
->subsys
.rwsem
);
62 qeth_procfile_seq_next(struct seq_file
*s
, void *it
, loff_t
*offset
)
64 struct device
*prev
, *next
;
66 if (it
== SEQ_START_TOKEN
)
69 prev
= (struct device
*) it
;
70 next
= driver_find_device(&qeth_ccwgroup_driver
.driver
,
71 prev
, NULL
, qeth_procfile_seq_match
);
76 static inline const char *
77 qeth_get_router_str(struct qeth_card
*card
, int ipv
)
82 routing_type
= card
->options
.route4
.type
;
84 #ifdef CONFIG_QETH_IPV6
85 routing_type
= card
->options
.route6
.type
;
88 #endif /* CONFIG_QETH_IPV6 */
91 if (routing_type
== PRIMARY_ROUTER
)
93 else if (routing_type
== SECONDARY_ROUTER
)
95 else if (routing_type
== MULTICAST_ROUTER
) {
96 if (card
->info
.broadcast_capable
== QETH_BROADCAST_WITHOUT_ECHO
)
99 } else if (routing_type
== PRIMARY_CONNECTOR
) {
100 if (card
->info
.broadcast_capable
== QETH_BROADCAST_WITHOUT_ECHO
)
103 } else if (routing_type
== SECONDARY_CONNECTOR
) {
104 if (card
->info
.broadcast_capable
== QETH_BROADCAST_WITHOUT_ECHO
)
107 } else if (routing_type
== NO_ROUTER
)
114 qeth_procfile_seq_show(struct seq_file
*s
, void *it
)
116 struct device
*device
;
117 struct qeth_card
*card
;
118 char tmp
[12]; /* for qeth_get_prioq_str */
120 if (it
== SEQ_START_TOKEN
){
121 seq_printf(s
, "devices CHPID interface "
122 "cardtype port chksum prio-q'ing rtr4 "
124 seq_printf(s
, "-------------------------- ----- ---------- "
125 "-------------- ---- ------ ---------- ---- "
126 "---- ----- -----\n");
128 device
= (struct device
*) it
;
129 card
= device
->driver_data
;
130 seq_printf(s
, "%s/%s/%s x%02X %-10s %-14s %-4i ",
135 QETH_CARD_IFNAME(card
),
136 qeth_get_cardname_short(card
),
138 if (card
->lan_online
)
139 seq_printf(s
, "%-6s %-10s %-4s %-4s %-5s %-5i\n",
140 qeth_get_checksum_str(card
),
141 qeth_get_prioq_str(card
, tmp
),
142 qeth_get_router_str(card
, 4),
143 qeth_get_router_str(card
, 6),
144 qeth_get_bufsize_str(card
),
145 card
->qdio
.in_buf_pool
.buf_count
);
147 seq_printf(s
, " +++ LAN OFFLINE +++\n");
153 static struct seq_operations qeth_procfile_seq_ops
= {
154 .start
= qeth_procfile_seq_start
,
155 .stop
= qeth_procfile_seq_stop
,
156 .next
= qeth_procfile_seq_next
,
157 .show
= qeth_procfile_seq_show
,
161 qeth_procfile_open(struct inode
*inode
, struct file
*file
)
163 return seq_open(file
, &qeth_procfile_seq_ops
);
166 static struct file_operations qeth_procfile_fops
= {
167 .owner
= THIS_MODULE
,
168 .open
= qeth_procfile_open
,
171 .release
= seq_release
,
174 /***** /proc/qeth_perf *****/
175 #define QETH_PERF_PROCFILE_NAME "qeth_perf"
176 static struct proc_dir_entry
*qeth_perf_procfile
;
178 #ifdef CONFIG_QETH_PERF_STATS
180 qeth_perf_procfile_seq_show(struct seq_file
*s
, void *it
)
182 struct device
*device
;
183 struct qeth_card
*card
;
186 if (it
== SEQ_START_TOKEN
)
189 device
= (struct device
*) it
;
190 card
= device
->driver_data
;
191 seq_printf(s
, "For card with devnos %s/%s/%s (%s):\n",
195 QETH_CARD_IFNAME(card
)
197 seq_printf(s
, " Skb's/buffers received : %li/%i\n"
198 " Skb's/buffers sent : %li/%i\n\n",
199 card
->stats
.rx_packets
, card
->perf_stats
.bufs_rec
,
200 card
->stats
.tx_packets
, card
->perf_stats
.bufs_sent
202 seq_printf(s
, " Skb's/buffers sent without packing : %li/%i\n"
203 " Skb's/buffers sent with packing : %i/%i\n\n",
204 card
->stats
.tx_packets
- card
->perf_stats
.skbs_sent_pack
,
205 card
->perf_stats
.bufs_sent
- card
->perf_stats
.bufs_sent_pack
,
206 card
->perf_stats
.skbs_sent_pack
,
207 card
->perf_stats
.bufs_sent_pack
209 seq_printf(s
, " Skbs sent in SG mode : %i\n"
210 " Skb fragments sent in SG mode : %i\n\n",
211 card
->perf_stats
.sg_skbs_sent
,
212 card
->perf_stats
.sg_frags_sent
);
213 seq_printf(s
, " large_send tx (in Kbytes) : %i\n"
214 " large_send count : %i\n\n",
215 card
->perf_stats
.large_send_bytes
>> 10,
216 card
->perf_stats
.large_send_cnt
);
217 seq_printf(s
, " Packing state changes no pkg.->packing : %i/%i\n"
218 " Watermarks L/H : %i/%i\n"
219 " Current buffer usage (outbound q's) : "
221 card
->perf_stats
.sc_dp_p
, card
->perf_stats
.sc_p_dp
,
222 QETH_LOW_WATERMARK_PACK
, QETH_HIGH_WATERMARK_PACK
,
223 atomic_read(&card
->qdio
.out_qs
[0]->used_buffers
),
224 (card
->qdio
.no_out_queues
> 1)?
225 atomic_read(&card
->qdio
.out_qs
[1]->used_buffers
)
227 (card
->qdio
.no_out_queues
> 2)?
228 atomic_read(&card
->qdio
.out_qs
[2]->used_buffers
)
230 (card
->qdio
.no_out_queues
> 3)?
231 atomic_read(&card
->qdio
.out_qs
[3]->used_buffers
)
234 seq_printf(s
, " Inbound handler time (in us) : %i\n"
235 " Inbound handler count : %i\n"
236 " Inbound do_QDIO time (in us) : %i\n"
237 " Inbound do_QDIO count : %i\n\n"
238 " Outbound handler time (in us) : %i\n"
239 " Outbound handler count : %i\n\n"
240 " Outbound time (in us, incl QDIO) : %i\n"
241 " Outbound count : %i\n"
242 " Outbound do_QDIO time (in us) : %i\n"
243 " Outbound do_QDIO count : %i\n\n",
244 card
->perf_stats
.inbound_time
,
245 card
->perf_stats
.inbound_cnt
,
246 card
->perf_stats
.inbound_do_qdio_time
,
247 card
->perf_stats
.inbound_do_qdio_cnt
,
248 card
->perf_stats
.outbound_handler_time
,
249 card
->perf_stats
.outbound_handler_cnt
,
250 card
->perf_stats
.outbound_time
,
251 card
->perf_stats
.outbound_cnt
,
252 card
->perf_stats
.outbound_do_qdio_time
,
253 card
->perf_stats
.outbound_do_qdio_cnt
259 static struct seq_operations qeth_perf_procfile_seq_ops
= {
260 .start
= qeth_procfile_seq_start
,
261 .stop
= qeth_procfile_seq_stop
,
262 .next
= qeth_procfile_seq_next
,
263 .show
= qeth_perf_procfile_seq_show
,
267 qeth_perf_procfile_open(struct inode
*inode
, struct file
*file
)
269 return seq_open(file
, &qeth_perf_procfile_seq_ops
);
272 static struct file_operations qeth_perf_procfile_fops
= {
273 .owner
= THIS_MODULE
,
274 .open
= qeth_perf_procfile_open
,
277 .release
= seq_release
,
280 #define qeth_perf_procfile_created qeth_perf_procfile
282 #define qeth_perf_procfile_created 1
283 #endif /* CONFIG_QETH_PERF_STATS */
286 qeth_create_procfs_entries(void)
288 qeth_procfile
= create_proc_entry(QETH_PROCFILE_NAME
,
289 S_IFREG
| 0444, NULL
);
291 qeth_procfile
->proc_fops
= &qeth_procfile_fops
;
293 #ifdef CONFIG_QETH_PERF_STATS
294 qeth_perf_procfile
= create_proc_entry(QETH_PERF_PROCFILE_NAME
,
295 S_IFREG
| 0444, NULL
);
296 if (qeth_perf_procfile
)
297 qeth_perf_procfile
->proc_fops
= &qeth_perf_procfile_fops
;
298 #endif /* CONFIG_QETH_PERF_STATS */
301 qeth_perf_procfile_created
)
308 qeth_remove_procfs_entries(void)
311 remove_proc_entry(QETH_PROCFILE_NAME
, NULL
);
312 if (qeth_perf_procfile
)
313 remove_proc_entry(QETH_PERF_PROCFILE_NAME
, NULL
);