linux/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c
<<
>>
Prefs
   1/*---------------------------------------------------------------------------
   2   FT1000 driver for Flarion Flash OFDM NIC Device
   3
   4   Copyright (C) 2006 Patrik Ostrihon, All rights reserved.
   5   Copyright (C) 2006 ProWeb Consulting, a.s, All rights reserved.
   6
   7   This program is free software; you can redistribute it and/or modify it
   8   under the terms of the GNU General Public License as published by the Free
   9   Software Foundation; either version 2 of the License, or (at your option) any
  10   later version. This program is distributed in the hope that it will be useful,
  11   but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  12   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13   more details. You should have received a copy of the GNU General Public
  14   License along with this program; if not, write to the
  15   Free Software Foundation, Inc., 59 Temple Place -
  16   Suite 330, Boston, MA 02111-1307, USA.
  17-----------------------------------------------------------------------------*/
  18
  19#include <linux/module.h>
  20#include <linux/kernel.h>
  21#include <linux/proc_fs.h>
  22#include <linux/string.h>
  23#include <linux/vmalloc.h>
  24#include <linux/netdevice.h>
  25#include <asm/io.h>
  26#include <asm/uaccess.h>
  27#include "ft1000.h"
  28
  29#define FT1000_PROC "ft1000"
  30#define MAX_FILE_LEN 255
  31
  32#define PUTM_TO_PAGE(len,page,args...) \
  33        len += snprintf(page+len, PAGE_SIZE - len, args)
  34
  35#define PUTX_TO_PAGE(len,page,message,size,var) \
  36        len += snprintf(page+len, PAGE_SIZE - len, message); \
  37        for(i = 0; i < (size - 1); i++) \
  38        { \
  39                len += snprintf(page+len, PAGE_SIZE - len, "%02x:", var[i]); \
  40        } \
  41        len += snprintf(page+len, PAGE_SIZE - len, "%02x\n", var[i])
  42
  43#define PUTD_TO_PAGE(len,page,message,size,var) \
  44        len += snprintf(page+len, PAGE_SIZE - len, message); \
  45        for(i = 0; i < (size - 1); i++) \
  46        { \
  47                len += snprintf(page+len, PAGE_SIZE - len, "%d.", var[i]); \
  48        } \
  49        len += snprintf(page+len, PAGE_SIZE - len, "%d\n", var[i])
  50
  51static int ft1000ReadProc(char *page, char **start, off_t off,
  52                          int count, int *eof, void *data)
  53{
  54        struct net_device *dev;
  55        int len;
  56        int i;
  57        struct ft1000_info *info;
  58        char *status[] =
  59                { "Idle (Disconnect)", "Searching", "Active (Connected)",
  60                "Waiting for L2", "Sleep", "No Coverage", "", ""
  61        };
  62        char *signal[] = { "", "*", "**", "***", "****" };
  63        int strength;
  64        int quality;
  65        struct timeval tv;
  66        time_t delta;
  67
  68        dev = (struct net_device *)data;
  69        info = netdev_priv(dev);
  70
  71        if (off > 0) {
  72                *eof = 1;
  73                return 0;
  74        }
  75
  76        /* Wrap-around */
  77
  78        if (info->AsicID == ELECTRABUZZ_ID) {
  79                if (info->ProgConStat != 0xFF) {
  80                        info->LedStat =
  81                                ft1000_read_dpram(dev, FT1000_DSP_LED);
  82                        info->ConStat =
  83                                ft1000_read_dpram(dev,
  84                                                  FT1000_DSP_CON_STATE);
  85                } else {
  86                        info->ConStat = 0xf;
  87                }
  88        } else {
  89                if (info->ProgConStat != 0xFF) {
  90                        info->LedStat =
  91                                ntohs(ft1000_read_dpram_mag_16
  92                                  (dev, FT1000_MAG_DSP_LED,
  93                                   FT1000_MAG_DSP_LED_INDX));
  94                        info->ConStat =
  95                                ntohs(ft1000_read_dpram_mag_16
  96                                  (dev, FT1000_MAG_DSP_CON_STATE,
  97                                   FT1000_MAG_DSP_CON_STATE_INDX));
  98                } else {
  99                        info->ConStat = 0xf;
 100                }
 101        }
 102
 103        i = (info->LedStat) & 0xf;
 104        switch (i) {
 105        case 0x1:
 106                strength = 1;
 107                break;
 108        case 0x3:
 109                strength = 2;
 110                break;
 111        case 0x7:
 112                strength = 3;
 113                break;
 114        case 0xf:
 115                strength = 4;
 116                break;
 117        default:
 118                strength = 0;
 119        }
 120
 121        i = (info->LedStat >> 8) & 0xf;
 122        switch (i) {
 123        case 0x1:
 124                quality = 1;
 125                break;
 126        case 0x3:
 127                quality = 2;
 128                break;
 129        case 0x7:
 130                quality = 3;
 131                break;
 132        case 0xf:
 133                quality = 4;
 134                break;
 135        default:
 136                quality = 0;
 137        }
 138
 139        do_gettimeofday(&tv);
 140        delta = (tv.tv_sec - info->ConTm);
 141        len = 0;
 142        PUTM_TO_PAGE(len, page, "Connection Time: %02ld:%02ld:%02ld\n",
 143                         ((delta / 3600) % 24), ((delta / 60) % 60), (delta % 60));
 144        PUTM_TO_PAGE(len, page, "Connection Time[s]: %ld\n", delta);
 145        PUTM_TO_PAGE(len, page, "Asic ID: %s\n",
 146                         (info->AsicID) ==
 147                         ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC");
 148        PUTX_TO_PAGE(len, page, "SKU: ", SKUSZ, info->Sku);
 149        PUTX_TO_PAGE(len, page, "EUI64: ", EUISZ, info->eui64);
 150        PUTD_TO_PAGE(len, page, "DSP version number: ", DSPVERSZ, info->DspVer);
 151        PUTX_TO_PAGE(len, page, "Hardware Serial Number: ", HWSERNUMSZ,
 152                         info->HwSerNum);
 153        PUTX_TO_PAGE(len, page, "Caliberation Version: ", CALVERSZ,
 154                         info->RfCalVer);
 155        PUTD_TO_PAGE(len, page, "Caliberation Date: ", CALDATESZ,
 156                         info->RfCalDate);
 157        PUTM_TO_PAGE(len, page, "Media State: %s\n",
 158                         (info->mediastate) ? "link" : "no link");
 159        PUTM_TO_PAGE(len, page, "Connection Status: %s\n",
 160                         status[((info->ConStat) & 0x7)]);
 161        PUTM_TO_PAGE(len, page, "RX packets: %ld\n", info->stats.rx_packets);
 162        PUTM_TO_PAGE(len, page, "TX packets: %ld\n", info->stats.tx_packets);
 163        PUTM_TO_PAGE(len, page, "RX bytes: %ld\n", info->stats.rx_bytes);
 164        PUTM_TO_PAGE(len, page, "TX bytes: %ld\n", info->stats.tx_bytes);
 165        PUTM_TO_PAGE(len, page, "Signal Strength: %s\n", signal[strength]);
 166        PUTM_TO_PAGE(len, page, "Signal Quality: %s\n", signal[quality]);
 167        return len;
 168}
 169
 170static int ft1000NotifyProc(struct notifier_block *this, unsigned long event,
 171                                void *ptr)
 172{
 173        struct net_device *dev = ptr;
 174        struct ft1000_info *info;
 175
 176        info = netdev_priv(dev);
 177
 178        switch (event) {
 179        case NETDEV_CHANGENAME:
 180                remove_proc_entry(info->netdevname, info->proc_ft1000);
 181                create_proc_read_entry(dev->name, 0644, info->proc_ft1000,
 182                                           ft1000ReadProc, dev);
 183                snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name);
 184                break;
 185        }
 186        return NOTIFY_DONE;
 187}
 188
 189static struct notifier_block ft1000_netdev_notifier = {
 190        .notifier_call = ft1000NotifyProc
 191};
 192
 193void ft1000InitProc(struct net_device *dev)
 194{
 195        struct ft1000_info *info;
 196
 197        info = netdev_priv(dev);
 198
 199        info->proc_ft1000 = proc_mkdir(FT1000_PROC, init_net.proc_net);
 200        create_proc_read_entry(dev->name, 0644, info->proc_ft1000,
 201                                   ft1000ReadProc, dev);
 202        snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name);
 203        register_netdevice_notifier(&ft1000_netdev_notifier);
 204}
 205
 206void ft1000CleanupProc(struct net_device *dev)
 207{
 208        struct ft1000_info *info;
 209
 210        info = netdev_priv(dev);
 211
 212        remove_proc_entry(dev->name, info->proc_ft1000);
 213        remove_proc_entry(FT1000_PROC, init_net.proc_net);
 214        unregister_netdevice_notifier(&ft1000_netdev_notifier);
 215}
 216