3 * linux/drivers/s390/net/qeth_fs.c
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 /***** /proc/qeth *****/
25 #define QETH_PROCFILE_NAME "qeth"
26 static struct proc_dir_entry
*qeth_procfile
;
29 qeth_procfile_seq_match(struct device
*dev
, void *data
)
35 qeth_procfile_seq_start(struct seq_file
*s
, loff_t
*offset
)
37 struct device
*dev
= NULL
;
41 return SEQ_START_TOKEN
;
43 dev
= driver_find_device(&qeth_ccwgroup_driver
.driver
, dev
,
44 NULL
, qeth_procfile_seq_match
);
53 qeth_procfile_seq_stop(struct seq_file
*s
, void* it
)
58 qeth_procfile_seq_next(struct seq_file
*s
, void *it
, loff_t
*offset
)
60 struct device
*prev
, *next
;
62 if (it
== SEQ_START_TOKEN
)
65 prev
= (struct device
*) it
;
66 next
= driver_find_device(&qeth_ccwgroup_driver
.driver
,
67 prev
, NULL
, qeth_procfile_seq_match
);
72 static inline const char *
73 qeth_get_router_str(struct qeth_card
*card
, int ipv
)
75 enum qeth_routing_types routing_type
= NO_ROUTER
;
78 routing_type
= card
->options
.route4
.type
;
80 #ifdef CONFIG_QETH_IPV6
81 routing_type
= card
->options
.route6
.type
;
84 #endif /* CONFIG_QETH_IPV6 */
87 switch (routing_type
){
90 case SECONDARY_ROUTER
:
92 case MULTICAST_ROUTER
:
93 if (card
->info
.broadcast_capable
== QETH_BROADCAST_WITHOUT_ECHO
)
96 case PRIMARY_CONNECTOR
:
97 if (card
->info
.broadcast_capable
== QETH_BROADCAST_WITHOUT_ECHO
)
100 case SECONDARY_CONNECTOR
:
101 if (card
->info
.broadcast_capable
== QETH_BROADCAST_WITHOUT_ECHO
)
104 default: /* NO_ROUTER */
110 qeth_procfile_seq_show(struct seq_file
*s
, void *it
)
112 struct device
*device
;
113 struct qeth_card
*card
;
114 char tmp
[12]; /* for qeth_get_prioq_str */
116 if (it
== SEQ_START_TOKEN
){
117 seq_printf(s
, "devices CHPID interface "
118 "cardtype port chksum prio-q'ing rtr4 "
120 seq_printf(s
, "-------------------------- ----- ---------- "
121 "-------------- ---- ------ ---------- ---- "
122 "---- ----- -----\n");
124 device
= (struct device
*) it
;
125 card
= device
->driver_data
;
126 seq_printf(s
, "%s/%s/%s x%02X %-10s %-14s %-4i ",
131 QETH_CARD_IFNAME(card
),
132 qeth_get_cardname_short(card
),
134 if (card
->lan_online
)
135 seq_printf(s
, "%-6s %-10s %-4s %-4s %-5s %-5i\n",
136 qeth_get_checksum_str(card
),
137 qeth_get_prioq_str(card
, tmp
),
138 qeth_get_router_str(card
, 4),
139 qeth_get_router_str(card
, 6),
140 qeth_get_bufsize_str(card
),
141 card
->qdio
.in_buf_pool
.buf_count
);
143 seq_printf(s
, " +++ LAN OFFLINE +++\n");
149 static struct seq_operations qeth_procfile_seq_ops
= {
150 .start
= qeth_procfile_seq_start
,
151 .stop
= qeth_procfile_seq_stop
,
152 .next
= qeth_procfile_seq_next
,
153 .show
= qeth_procfile_seq_show
,
157 qeth_procfile_open(struct inode
*inode
, struct file
*file
)
159 return seq_open(file
, &qeth_procfile_seq_ops
);
162 static const struct file_operations qeth_procfile_fops
= {
163 .owner
= THIS_MODULE
,
164 .open
= qeth_procfile_open
,
167 .release
= seq_release
,
170 /***** /proc/qeth_perf *****/
171 #define QETH_PERF_PROCFILE_NAME "qeth_perf"
172 static struct proc_dir_entry
*qeth_perf_procfile
;
175 qeth_perf_procfile_seq_show(struct seq_file
*s
, void *it
)
177 struct device
*device
;
178 struct qeth_card
*card
;
181 if (it
== SEQ_START_TOKEN
)
184 device
= (struct device
*) it
;
185 card
= device
->driver_data
;
186 seq_printf(s
, "For card with devnos %s/%s/%s (%s):\n",
190 QETH_CARD_IFNAME(card
)
192 if (!card
->options
.performance_stats
)
193 seq_printf(s
, "Performance statistics are deactivated.\n");
194 seq_printf(s
, " Skb's/buffers received : %lu/%u\n"
195 " Skb's/buffers sent : %lu/%u\n\n",
196 card
->stats
.rx_packets
-
197 card
->perf_stats
.initial_rx_packets
,
198 card
->perf_stats
.bufs_rec
,
199 card
->stats
.tx_packets
-
200 card
->perf_stats
.initial_tx_packets
,
201 card
->perf_stats
.bufs_sent
203 seq_printf(s
, " Skb's/buffers sent without packing : %lu/%u\n"
204 " Skb's/buffers sent with packing : %u/%u\n\n",
205 card
->stats
.tx_packets
- card
->perf_stats
.initial_tx_packets
206 - card
->perf_stats
.skbs_sent_pack
,
207 card
->perf_stats
.bufs_sent
- card
->perf_stats
.bufs_sent_pack
,
208 card
->perf_stats
.skbs_sent_pack
,
209 card
->perf_stats
.bufs_sent_pack
211 seq_printf(s
, " Skbs sent in SG mode : %u\n"
212 " Skb fragments sent in SG mode : %u\n\n",
213 card
->perf_stats
.sg_skbs_sent
,
214 card
->perf_stats
.sg_frags_sent
);
215 seq_printf(s
, " large_send tx (in Kbytes) : %u\n"
216 " large_send count : %u\n\n",
217 card
->perf_stats
.large_send_bytes
>> 10,
218 card
->perf_stats
.large_send_cnt
);
219 seq_printf(s
, " Packing state changes no pkg.->packing : %u/%u\n"
220 " Watermarks L/H : %i/%i\n"
221 " Current buffer usage (outbound q's) : "
223 card
->perf_stats
.sc_dp_p
, card
->perf_stats
.sc_p_dp
,
224 QETH_LOW_WATERMARK_PACK
, QETH_HIGH_WATERMARK_PACK
,
225 atomic_read(&card
->qdio
.out_qs
[0]->used_buffers
),
226 (card
->qdio
.no_out_queues
> 1)?
227 atomic_read(&card
->qdio
.out_qs
[1]->used_buffers
)
229 (card
->qdio
.no_out_queues
> 2)?
230 atomic_read(&card
->qdio
.out_qs
[2]->used_buffers
)
232 (card
->qdio
.no_out_queues
> 3)?
233 atomic_read(&card
->qdio
.out_qs
[3]->used_buffers
)
236 seq_printf(s
, " Inbound handler time (in us) : %u\n"
237 " Inbound handler count : %u\n"
238 " Inbound do_QDIO time (in us) : %u\n"
239 " Inbound do_QDIO count : %u\n\n"
240 " Outbound handler time (in us) : %u\n"
241 " Outbound handler count : %u\n\n"
242 " Outbound time (in us, incl QDIO) : %u\n"
243 " Outbound count : %u\n"
244 " Outbound do_QDIO time (in us) : %u\n"
245 " Outbound do_QDIO count : %u\n\n",
246 card
->perf_stats
.inbound_time
,
247 card
->perf_stats
.inbound_cnt
,
248 card
->perf_stats
.inbound_do_qdio_time
,
249 card
->perf_stats
.inbound_do_qdio_cnt
,
250 card
->perf_stats
.outbound_handler_time
,
251 card
->perf_stats
.outbound_handler_cnt
,
252 card
->perf_stats
.outbound_time
,
253 card
->perf_stats
.outbound_cnt
,
254 card
->perf_stats
.outbound_do_qdio_time
,
255 card
->perf_stats
.outbound_do_qdio_cnt
261 static struct seq_operations qeth_perf_procfile_seq_ops
= {
262 .start
= qeth_procfile_seq_start
,
263 .stop
= qeth_procfile_seq_stop
,
264 .next
= qeth_procfile_seq_next
,
265 .show
= qeth_perf_procfile_seq_show
,
269 qeth_perf_procfile_open(struct inode
*inode
, struct file
*file
)
271 return seq_open(file
, &qeth_perf_procfile_seq_ops
);
274 static const struct file_operations qeth_perf_procfile_fops
= {
275 .owner
= THIS_MODULE
,
276 .open
= qeth_perf_procfile_open
,
279 .release
= seq_release
,
283 qeth_create_procfs_entries(void)
285 qeth_procfile
= create_proc_entry(QETH_PROCFILE_NAME
,
286 S_IFREG
| 0444, NULL
);
288 qeth_procfile
->proc_fops
= &qeth_procfile_fops
;
290 qeth_perf_procfile
= create_proc_entry(QETH_PERF_PROCFILE_NAME
,
291 S_IFREG
| 0444, NULL
);
292 if (qeth_perf_procfile
)
293 qeth_perf_procfile
->proc_fops
= &qeth_perf_procfile_fops
;
303 qeth_remove_procfs_entries(void)
306 remove_proc_entry(QETH_PROCFILE_NAME
, NULL
);
307 if (qeth_perf_procfile
)
308 remove_proc_entry(QETH_PERF_PROCFILE_NAME
, NULL
);