Commit 6ac4b57f authored by Maciej W. Rozycki's avatar Maciej W. Rozycki Committed by David S. Miller

[NET]: Fix fddi_statistics for 64-bit

 There is a problem with "struct fddi_statistics" for 64-bit systems.
The starting members of the struct are expected to correspond to the
respective members of "struct net_device_stats" (drivers for FDDI
devices return "struct fddi_statistics" in the response to the
get_stats() call of "struct net_device").  Unfortunately, due to using
different types (u32 vs ulong) they do not.  "struct net_device_stats"
is a public interface and as a result, bogus results are retrieved,
e.g. for /proc/net/dev.

 Here is my proposal to address the problem.  I think there is no
point in duplicating the layout of "struct net_device_stats" in
"struct fddi_statistics" as the former can simply be included as a
member avoiding this problem and actually any possible discrepancy in
the future.  This also preserves the layout of the structure for
32-bit systems.
Signed-off-by: default avatarMaciej W. Rozycki <macro@linux-mips.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bbafa8ab
...@@ -1814,16 +1814,18 @@ static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev) ...@@ -1814,16 +1814,18 @@ static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev)
/* Fill the bp->stats structure with driver-maintained counters */ /* Fill the bp->stats structure with driver-maintained counters */
bp->stats.rx_packets = bp->rcv_total_frames; bp->stats.gen.rx_packets = bp->rcv_total_frames;
bp->stats.tx_packets = bp->xmt_total_frames; bp->stats.gen.tx_packets = bp->xmt_total_frames;
bp->stats.rx_bytes = bp->rcv_total_bytes; bp->stats.gen.rx_bytes = bp->rcv_total_bytes;
bp->stats.tx_bytes = bp->xmt_total_bytes; bp->stats.gen.tx_bytes = bp->xmt_total_bytes;
bp->stats.rx_errors = (u32)(bp->rcv_crc_errors + bp->rcv_frame_status_errors + bp->rcv_length_errors); bp->stats.gen.rx_errors = bp->rcv_crc_errors +
bp->stats.tx_errors = bp->xmt_length_errors; bp->rcv_frame_status_errors +
bp->stats.rx_dropped = bp->rcv_discards; bp->rcv_length_errors;
bp->stats.tx_dropped = bp->xmt_discards; bp->stats.gen.tx_errors = bp->xmt_length_errors;
bp->stats.multicast = bp->rcv_multicast_frames; bp->stats.gen.rx_dropped = bp->rcv_discards;
bp->stats.transmit_collision = 0; /* always zero (0) for FDDI */ bp->stats.gen.tx_dropped = bp->xmt_discards;
bp->stats.gen.multicast = bp->rcv_multicast_frames;
bp->stats.gen.collisions = 0; /* always zero (0) for FDDI */
/* Get FDDI SMT MIB objects */ /* Get FDDI SMT MIB objects */
......
...@@ -1095,7 +1095,7 @@ static int skfp_send_pkt(struct sk_buff *skb, struct net_device *dev) ...@@ -1095,7 +1095,7 @@ static int skfp_send_pkt(struct sk_buff *skb, struct net_device *dev)
*/ */
if (!(skb->len >= FDDI_K_LLC_ZLEN && skb->len <= FDDI_K_LLC_LEN)) { if (!(skb->len >= FDDI_K_LLC_ZLEN && skb->len <= FDDI_K_LLC_LEN)) {
bp->MacStat.tx_errors++; /* bump error counter */ bp->MacStat.gen.tx_errors++; /* bump error counter */
// dequeue packets from xmt queue and send them // dequeue packets from xmt queue and send them
netif_start_queue(dev); netif_start_queue(dev);
dev_kfree_skb(skb); dev_kfree_skb(skb);
...@@ -1546,8 +1546,8 @@ void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd) ...@@ -1546,8 +1546,8 @@ void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd)
skb->len, PCI_DMA_TODEVICE); skb->len, PCI_DMA_TODEVICE);
txd->txd_os.dma_addr = 0; txd->txd_os.dma_addr = 0;
smc->os.MacStat.tx_packets++; // Count transmitted packets. smc->os.MacStat.gen.tx_packets++; // Count transmitted packets.
smc->os.MacStat.tx_bytes+=skb->len; // Count bytes smc->os.MacStat.gen.tx_bytes+=skb->len; // Count bytes
// free the skb // free the skb
dev_kfree_skb_irq(skb); dev_kfree_skb_irq(skb);
...@@ -1629,7 +1629,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd, ...@@ -1629,7 +1629,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
skb = rxd->rxd_os.skb; skb = rxd->rxd_os.skb;
if (!skb) { if (!skb) {
PRINTK(KERN_INFO "No skb in rxd\n"); PRINTK(KERN_INFO "No skb in rxd\n");
smc->os.MacStat.rx_errors++; smc->os.MacStat.gen.rx_errors++;
goto RequeueRxd; goto RequeueRxd;
} }
virt = skb->data; virt = skb->data;
...@@ -1682,13 +1682,14 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd, ...@@ -1682,13 +1682,14 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
} }
// Count statistics. // Count statistics.
smc->os.MacStat.rx_packets++; // Count indicated receive packets. smc->os.MacStat.gen.rx_packets++; // Count indicated receive
smc->os.MacStat.rx_bytes+=len; // Count bytes // packets.
smc->os.MacStat.gen.rx_bytes+=len; // Count bytes.
// virt points to header again // virt points to header again
if (virt[1] & 0x01) { // Check group (multicast) bit. if (virt[1] & 0x01) { // Check group (multicast) bit.
smc->os.MacStat.multicast++; smc->os.MacStat.gen.multicast++;
} }
// deliver frame to system // deliver frame to system
...@@ -1706,7 +1707,8 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd, ...@@ -1706,7 +1707,8 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
RequeueRxd: RequeueRxd:
PRINTK(KERN_INFO "Rx: re-queue RXD.\n"); PRINTK(KERN_INFO "Rx: re-queue RXD.\n");
mac_drv_requeue_rxd(smc, rxd, frag_count); mac_drv_requeue_rxd(smc, rxd, frag_count);
smc->os.MacStat.rx_errors++; // Count receive packets not indicated. smc->os.MacStat.gen.rx_errors++; // Count receive packets
// not indicated.
} // mac_drv_rx_complete } // mac_drv_rx_complete
...@@ -2081,7 +2083,7 @@ void smt_stat_counter(struct s_smc *smc, int stat) ...@@ -2081,7 +2083,7 @@ void smt_stat_counter(struct s_smc *smc, int stat)
break; break;
case 1: case 1:
PRINTK(KERN_INFO "Receive fifo overflow.\n"); PRINTK(KERN_INFO "Receive fifo overflow.\n");
smc->os.MacStat.rx_errors++; smc->os.MacStat.gen.rx_errors++;
break; break;
default: default:
PRINTK(KERN_INFO "Unknown status (%d).\n", stat); PRINTK(KERN_INFO "Unknown status (%d).\n", stat);
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Global definitions for the ANSI FDDI interface. * Global definitions for the ANSI FDDI interface.
* *
* Version: @(#)if_fddi.h 1.0.1 09/16/96 * Version: @(#)if_fddi.h 1.0.2 Sep 29 2004
* *
* Author: Lawrence V. Stefani, <stefani@lkg.dec.com> * Author: Lawrence V. Stefani, <stefani@lkg.dec.com>
* *
...@@ -103,38 +103,12 @@ struct fddihdr ...@@ -103,38 +103,12 @@ struct fddihdr
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Define FDDI statistics structure */ /* Define FDDI statistics structure */
struct fddi_statistics struct fddi_statistics {
{
__u32 rx_packets; /* total packets received */ /* Generic statistics. */
__u32 tx_packets; /* total packets transmitted */
__u32 rx_bytes; /* total bytes received */
__u32 tx_bytes; /* total bytes transmitted */
__u32 rx_errors; /* bad packets received */
__u32 tx_errors; /* packet transmit problems */
__u32 rx_dropped; /* no space in linux buffers */
__u32 tx_dropped; /* no space available in linux */
__u32 multicast; /* multicast packets received */
__u32 transmit_collision; /* always 0 for FDDI */
/* detailed rx_errors */ struct net_device_stats gen;
__u32 rx_length_errors;
__u32 rx_over_errors; /* receiver ring buff overflow */
__u32 rx_crc_errors; /* recved pkt with crc error */
__u32 rx_frame_errors; /* recv'd frame alignment error */
__u32 rx_fifo_errors; /* recv'r fifo overrun */
__u32 rx_missed_errors; /* receiver missed packet */
/* detailed tx_errors */
__u32 tx_aborted_errors;
__u32 tx_carrier_errors;
__u32 tx_fifo_errors;
__u32 tx_heartbeat_errors;
__u32 tx_window_errors;
/* for cslip etc */
__u32 rx_compressed;
__u32 tx_compressed;
/* Detailed FDDI statistics. Adopted from RFC 1512 */ /* Detailed FDDI statistics. Adopted from RFC 1512 */
__u8 smt_station_id[8]; __u8 smt_station_id[8];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment