linux-bk/drivers/net/e1000/e1000_proc.c
<<
>>
Prefs
   1/*******************************************************************************
   2
   3  
   4  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
   5  
   6  This program is free software; you can redistribute it and/or modify it 
   7  under the terms of the GNU General Public License as published by the Free 
   8  Software Foundation; either version 2 of the License, or (at your option) 
   9  any later version.
  10  
  11  This program is distributed in the hope that it will be useful, but WITHOUT 
  12  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
  13  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
  14  more details.
  15  
  16  You should have received a copy of the GNU General Public License along with
  17  this program; if not, write to the Free Software Foundation, Inc., 59 
  18  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19  
  20  The full GNU General Public License is included in this distribution in the
  21  file called LICENSE.
  22  
  23  Contact Information:
  24  Linux NICS <linux.nics@intel.com>
  25  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  26
  27*******************************************************************************/
  28
  29/*
  30 * Proc fs support.
  31 *
  32 * Read-only files created by driver (if CONFIG_PROC_FS):
  33 *
  34 * /proc/net/PRO_LAN_Adapters/<ethx>.info
  35 * /proc/net/PRO_LAN_Adapters/<ethx>/<attribute>
  36 *
  37 * where <ethx>      is the system device name, i.e eth0.
  38 *       <attribute> is the driver attribute name.
  39 *
  40 * There is one file for each driver attribute, where the contents
  41 * of the file is the attribute value.  The ethx.info file contains
  42 * a list of all driver attributes in one file.
  43 *
  44 */
  45
  46#include "e1000.h"
  47
  48#ifdef CONFIG_PROC_FS
  49
  50#include <linux/proc_fs.h>
  51
  52#define ADAPTERS_PROC_DIR           "PRO_LAN_Adapters"
  53#define TAG_MAX_LENGTH              32
  54#define LINE_MAX_LENGTH             80
  55#define FIELD_MAX_LENGTH            LINE_MAX_LENGTH - TAG_MAX_LENGTH - 3
  56
  57extern char e1000_driver_name[];
  58extern char e1000_driver_version[];
  59
  60/*
  61 * The list of driver proc attributes is stored in a proc_list link
  62 * list.  The list is build with proc_list_setup and is used to
  63 * build the proc fs nodes.  The private data for each node is the
  64 * corresponding link in the link list.
  65 */
  66
  67struct proc_list {
  68        struct list_head list;                  /* link list */
  69        char tag[TAG_MAX_LENGTH + 1];           /* attribute name */
  70        void *data;                             /* attribute data */
  71        size_t len;                             /* sizeof data */
  72        char *(*func)(void *, size_t, char *);  /* format data func */
  73};
  74
  75static int
  76e1000_proc_read(char *page, char **start, off_t off, int count, int *eof)
  77{
  78        int len = strlen(page);
  79
  80        page[len++] = '\n';
  81
  82        if(len <= off + count)
  83                *eof = 1;
  84        *start = page + off;
  85        len -= off;
  86        if(len > count)
  87                len = count;
  88        if(len < 0)
  89                len = 0;
  90
  91        return len;
  92}
  93
  94static int
  95e1000_proc_info_read(char *page, char **start, off_t off,
  96                     int count, int *eof, void *data)
  97{
  98        struct list_head *proc_list_head = data, *curr;
  99        struct proc_list *elem;
 100        char *p = page;
 101        char buf[FIELD_MAX_LENGTH + 1];
 102
 103        list_for_each(curr, proc_list_head) {
 104                elem = list_entry(curr, struct proc_list, list);
 105
 106                if (p - page + LINE_MAX_LENGTH >= PAGE_SIZE)
 107                        break;
 108
 109                if(!strlen(elem->tag))
 110                        p += sprintf(p, "\n");
 111                else
 112                        p += sprintf(p, "%-*.*s %.*s\n", 
 113                                TAG_MAX_LENGTH, TAG_MAX_LENGTH,
 114                                elem->tag, FIELD_MAX_LENGTH,
 115                                elem->func(elem->data, elem->len, buf));
 116        }
 117
 118        *p = '\0';
 119
 120        return e1000_proc_read(page, start, off, count, eof);
 121}
 122
 123static int
 124e1000_proc_single_read(char *page, char **start, off_t off,
 125                       int count, int *eof, void *data)
 126{
 127        struct proc_list *elem = data;
 128
 129        sprintf(page, "%.*s", FIELD_MAX_LENGTH, elem->func(elem->data, 
 130                elem->len, page));
 131
 132        return e1000_proc_read(page, start, off, count, eof);
 133}
 134
 135static void __devexit
 136e1000_proc_dirs_free(char *name, struct list_head *proc_list_head)
 137{
 138        struct proc_dir_entry *intel_proc_dir, *proc_dir;
 139        char info_name[strlen(name) + strlen(".info")];
 140
 141        for(intel_proc_dir = proc_net->subdir; intel_proc_dir;
 142                intel_proc_dir = intel_proc_dir->next) {
 143                if((intel_proc_dir->namelen == strlen(ADAPTERS_PROC_DIR)) &&
 144                   !memcmp(intel_proc_dir->name, ADAPTERS_PROC_DIR, strlen(ADAPTERS_PROC_DIR)))
 145                        break;
 146        }
 147
 148        if(!intel_proc_dir)
 149                return;
 150
 151        for(proc_dir = intel_proc_dir->subdir; proc_dir;
 152                proc_dir = proc_dir->next) {
 153                if ((proc_dir->namelen == strlen(name)) &&
 154                    !memcmp(proc_dir->name, name, strlen(name)))
 155                        break;
 156        }
 157
 158        if(proc_dir) {
 159                struct list_head *curr;
 160                struct proc_list *elem;
 161
 162                list_for_each(curr, proc_list_head) {
 163                        elem = list_entry(curr, struct proc_list, list);
 164                        remove_proc_entry(elem->tag, proc_dir);
 165                }
 166
 167                strcpy(info_name, name);
 168                strcat(info_name, ".info");
 169
 170                remove_proc_entry(info_name, intel_proc_dir);
 171                remove_proc_entry(name, intel_proc_dir);
 172        }
 173
 174        /* If the intel dir is empty, remove it */
 175
 176        for(proc_dir = intel_proc_dir->subdir; proc_dir;
 177                proc_dir = proc_dir->next) {
 178
 179                /* ignore . and .. */
 180
 181                if(*(proc_dir->name) == '.')
 182                        continue;
 183                break;
 184        }
 185
 186        if(!proc_dir)
 187                remove_proc_entry(ADAPTERS_PROC_DIR, proc_net);
 188}
 189
 190
 191static int __devinit
 192e1000_proc_singles_create(struct proc_dir_entry *parent,
 193                          struct list_head *proc_list_head)
 194{
 195        struct list_head *curr;
 196        struct proc_list *elem;
 197
 198        list_for_each(curr, proc_list_head) {
 199                struct proc_dir_entry *proc_entry;
 200
 201                elem = list_entry(curr, struct proc_list, list);
 202
 203                if(!strlen(elem->tag))
 204                        continue;
 205
 206                if(!(proc_entry =
 207                        create_proc_entry(elem->tag, S_IFREG, parent)))
 208                        return 0;
 209
 210                proc_entry->read_proc = e1000_proc_single_read;
 211                proc_entry->data = elem;
 212                SET_MODULE_OWNER(proc_entry);
 213        }
 214
 215        return 1;
 216}
 217
 218static void __devinit
 219e1000_proc_dirs_create(void *data, char *name, 
 220                       struct list_head *proc_list_head)
 221{
 222        struct proc_dir_entry *intel_proc_dir, *proc_dir, *info_entry;
 223        char info_name[strlen(name) + strlen(".info")];
 224
 225        for(intel_proc_dir = proc_net->subdir; intel_proc_dir;
 226                intel_proc_dir = intel_proc_dir->next) {
 227                if((intel_proc_dir->namelen == strlen(ADAPTERS_PROC_DIR)) &&
 228                   !memcmp(intel_proc_dir->name, ADAPTERS_PROC_DIR, strlen(ADAPTERS_PROC_DIR)))
 229                        break;
 230        }
 231
 232        if(!intel_proc_dir)
 233                if(!(intel_proc_dir =
 234                        create_proc_entry(ADAPTERS_PROC_DIR,
 235                                S_IFDIR, proc_net)))
 236                        return;
 237
 238        if(!(proc_dir =
 239                create_proc_entry(name, S_IFDIR, intel_proc_dir)))
 240                return;
 241        SET_MODULE_OWNER(proc_dir);
 242
 243        if(!e1000_proc_singles_create(proc_dir, proc_list_head))
 244                return;
 245
 246        strcpy(info_name, name);
 247        strcat(info_name, ".info");
 248
 249        if(!(info_entry =
 250                create_proc_entry(info_name, S_IFREG, intel_proc_dir)))
 251                return;
 252        SET_MODULE_OWNER(info_entry);
 253
 254        info_entry->read_proc = e1000_proc_info_read;
 255        info_entry->data = proc_list_head;
 256}
 257
 258static void __devinit
 259e1000_proc_list_add(struct list_head *proc_list_head, char *tag,
 260                    void *data, size_t len, 
 261                    char *(*func)(void *, size_t, char *))
 262{
 263        struct proc_list *new = (struct proc_list *)
 264                kmalloc(sizeof(struct proc_list), GFP_KERNEL);
 265
 266        if(!new)
 267                return;
 268
 269        strncpy(new->tag, tag, TAG_MAX_LENGTH);
 270        new->data = data;
 271        new->len  = len;
 272        new->func = func;
 273
 274        list_add_tail(&new->list, proc_list_head);
 275}
 276
 277static void __devexit
 278e1000_proc_list_free(struct list_head *proc_list_head)
 279{
 280        struct proc_list *elem;
 281
 282        while(!list_empty(proc_list_head)) {
 283                elem = list_entry(proc_list_head->next, struct proc_list, list);
 284                list_del(&elem->list);
 285                kfree(elem);
 286        }
 287}
 288
 289/*
 290 * General purpose formating functions
 291 */
 292
 293static char *
 294e1000_proc_str(void *data, size_t len, char *buf)
 295{
 296        sprintf(buf, "%s", (char *)data);
 297        return buf;
 298}
 299
 300static char *
 301e1000_proc_hex(void *data, size_t len, char *buf)
 302{
 303        switch(len) {
 304        case sizeof(uint8_t):
 305                sprintf(buf, "0x%02x", *(uint8_t *)data);
 306                break;
 307        case sizeof(uint16_t):
 308                sprintf(buf, "0x%04x", *(uint16_t *)data);
 309                break;
 310        case sizeof(uint32_t):
 311                sprintf(buf, "0x%08x", *(uint32_t *)data);
 312                break;
 313        case sizeof(uint64_t):
 314                sprintf(buf, "0x%08Lx", (unsigned long long)*(uint64_t *)data);
 315                break;
 316        }
 317        return buf;
 318}
 319
 320static char *
 321e1000_proc_unsigned(void *data, size_t len, char *buf)
 322{
 323        switch(len) {
 324        case sizeof(uint8_t):
 325                sprintf(buf, "%u", *(uint8_t *)data);
 326                break;
 327        case sizeof(uint16_t):
 328                sprintf(buf, "%u", *(uint16_t *)data);
 329                break;
 330        case sizeof(uint32_t):
 331                sprintf(buf, "%u", *(uint32_t *)data);
 332                break;
 333        case sizeof(uint64_t):
 334                sprintf(buf, "%Lu", (unsigned long long)*(uint64_t *)data);
 335                break;
 336        }
 337        return buf;
 338}
 339
 340/*
 341 * Specific formating functions
 342 */
 343
 344static char *
 345e1000_proc_part_number(void *data, size_t len, char *buf)
 346{
 347        sprintf(buf, "%06x-%03x", *(uint32_t *)data >> 8,
 348                *(uint32_t *)data & 0x000000FF);
 349        return buf;
 350}
 351
 352static char *
 353e1000_proc_slot(void *data, size_t len, char *buf)
 354{
 355        struct e1000_adapter *adapter = data;
 356        sprintf(buf, "%u", PCI_SLOT(adapter->pdev->devfn));
 357        return buf;
 358}
 359
 360static char *
 361e1000_proc_bus_type(void *data, size_t len, char *buf)
 362{
 363        e1000_bus_type bus_type = *(e1000_bus_type *)data;
 364        sprintf(buf,
 365                bus_type == e1000_bus_type_pci  ? "PCI"   :
 366                bus_type == e1000_bus_type_pcix ? "PCI-X" :
 367                "UNKNOWN");
 368        return buf;
 369}
 370
 371static char *
 372e1000_proc_bus_speed(void *data, size_t len, char *buf)
 373{
 374        e1000_bus_speed bus_speed = *(e1000_bus_speed *)data;
 375        sprintf(buf,
 376                bus_speed == e1000_bus_speed_33  ? "33MHz"  :
 377                bus_speed == e1000_bus_speed_66  ? "66MHz"  :
 378                bus_speed == e1000_bus_speed_100 ? "100MHz" :
 379                bus_speed == e1000_bus_speed_133 ? "133MHz" :
 380                "UNKNOWN");
 381        return buf;
 382}
 383
 384static char *
 385e1000_proc_bus_width(void *data, size_t len, char *buf)
 386{
 387        e1000_bus_width bus_width = *(e1000_bus_width *)data;
 388        sprintf(buf,
 389                bus_width == e1000_bus_width_32 ? "32-bit"   :
 390                bus_width == e1000_bus_width_64 ? "64-bit" :
 391                "UNKNOWN");
 392        return buf;
 393}
 394
 395static char *
 396e1000_proc_hwaddr(void *data, size_t len, char *buf)
 397{
 398        unsigned char *hwaddr = data;
 399        sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
 400                hwaddr[0], hwaddr[1], hwaddr[2],
 401                hwaddr[3], hwaddr[4], hwaddr[5]);
 402        return buf;
 403}
 404
 405static char *
 406e1000_proc_link(void *data, size_t len, char *buf)
 407{
 408        struct e1000_adapter *adapter = data;
 409        sprintf(buf, netif_running(adapter->netdev) ?
 410                netif_carrier_ok(adapter->netdev) ?
 411                "up" : "down" : "N/A");
 412        return buf;
 413}
 414
 415static char *
 416e1000_proc_link_speed(void *data, size_t len, char *buf)
 417{
 418        uint16_t link_speed = *(uint16_t *)data;
 419        sprintf(buf, link_speed ? "%u" : "N/A", link_speed);
 420        return buf;
 421}
 422
 423static char *
 424e1000_proc_link_duplex(void *data, size_t len, char *buf)
 425{
 426        uint16_t link_duplex = *(uint16_t *)data;
 427        sprintf(buf,
 428                link_duplex == FULL_DUPLEX ? "Full" :
 429                link_duplex == HALF_DUPLEX ? "Half" :
 430                "N/A");
 431        return buf;
 432}
 433
 434static char *
 435e1000_proc_state(void *data, size_t len, char *buf)
 436{
 437        struct e1000_adapter *adapter = data;
 438        sprintf(buf, adapter->netdev->flags & IFF_UP ? "up" : "down");
 439        return buf;
 440}
 441
 442static char *
 443e1000_proc_media_type(void *data, size_t len, char *buf)
 444{
 445        struct e1000_adapter *adapter = data;
 446        sprintf(buf,
 447                adapter->hw.media_type == e1000_media_type_copper ?
 448                "Copper" : "Fiber");
 449        return buf;
 450}
 451
 452static char *
 453e1000_proc_cable_length(void *data, size_t len, char *buf)
 454{
 455        struct e1000_adapter *adapter = data;
 456        e1000_cable_length cable_length = adapter->phy_info.cable_length;
 457        sprintf(buf, "%s%s",
 458                cable_length == e1000_cable_length_50      ? "0-50"    :
 459                cable_length == e1000_cable_length_50_80   ? "50-80"   :
 460                cable_length == e1000_cable_length_80_110  ? "80-110"  :
 461                cable_length == e1000_cable_length_110_140 ? "110-140" :
 462                cable_length == e1000_cable_length_140     ? "> 140"   :
 463                "Unknown",
 464                cable_length != e1000_cable_length_undefined ?
 465                " Meters (+/- 20 Meters)" : "");
 466        return buf;
 467}
 468
 469static char *
 470e1000_proc_extended(void *data, size_t len, char *buf)
 471{
 472        struct e1000_adapter *adapter = data;
 473        e1000_10bt_ext_dist_enable dist_enable =
 474                adapter->phy_info.extended_10bt_distance;
 475        sprintf(buf,
 476                dist_enable == e1000_10bt_ext_dist_enable_normal ? "Disabled" :
 477                dist_enable == e1000_10bt_ext_dist_enable_lower  ? "Enabled"  :
 478                "Unknown");
 479        return buf;
 480}
 481
 482static char *
 483e1000_proc_cable_polarity(void *data, size_t len, char *buf)
 484{
 485        struct e1000_adapter *adapter = data;
 486        e1000_rev_polarity polarity = adapter->phy_info.cable_polarity;
 487        sprintf(buf,
 488                polarity == e1000_rev_polarity_normal   ? "Normal"   :
 489                polarity == e1000_rev_polarity_reversed ? "Reversed" :
 490                "Unknown");
 491        return buf;
 492}
 493
 494static char *
 495e1000_proc_polarity_correction(void *data, size_t len, char *buf)
 496{
 497        struct e1000_adapter *adapter = data;
 498        e1000_polarity_reversal correction =
 499                adapter->phy_info.polarity_correction;
 500        sprintf(buf,
 501                correction == e1000_polarity_reversal_enabled  ? "Disabled" :
 502                correction == e1000_polarity_reversal_disabled ? "Enabled"  :
 503                "Unknown");
 504        return buf;
 505}
 506
 507static char *
 508e1000_proc_mdi_x_enabled(void *data, size_t len, char *buf)
 509{
 510        struct e1000_adapter *adapter = data;
 511        e1000_auto_x_mode mdix_mode = adapter->phy_info.mdix_mode;
 512        sprintf(buf, 
 513                mdix_mode == e1000_auto_x_mode_manual_mdi  ? "MDI"   : 
 514                mdix_mode == e1000_auto_x_mode_manual_mdix ? "MDI-X" :
 515                "Unknown");
 516        return buf;
 517}
 518
 519static char *
 520e1000_proc_rx_status(void *data, size_t len, char *buf)
 521{
 522        e1000_1000t_rx_status rx_status = *(e1000_1000t_rx_status *)data;
 523        sprintf(buf,
 524                rx_status == e1000_1000t_rx_status_not_ok ? "NOT_OK" :
 525                rx_status == e1000_1000t_rx_status_ok     ? "OK"     :
 526                "Unknown");
 527        return buf;
 528}
 529
 530/*
 531 * e1000_proc_list_setup - build link list of proc praramters
 532 * @adapter: board private structure
 533 *
 534 * Order matters - ethx.info entries are ordered in the order links 
 535 * are added to list.
 536 */
 537
 538#define LIST_ADD_F(T,D,F) \
 539        e1000_proc_list_add(proc_list_head, (T), (D), sizeof(*(D)), (F))
 540#define LIST_ADD_BLANK() LIST_ADD_F("", NULL, NULL)
 541#define LIST_ADD_S(T,D) LIST_ADD_F((T), (D), e1000_proc_str)
 542#define LIST_ADD_H(T,D) LIST_ADD_F((T), (D), e1000_proc_hex)
 543#define LIST_ADD_U(T,D) LIST_ADD_F((T), (D), e1000_proc_unsigned)
 544
 545static void __devinit
 546e1000_proc_list_setup(struct e1000_adapter *adapter)
 547{
 548        struct e1000_hw *hw = &adapter->hw;
 549        struct list_head *proc_list_head = &adapter->proc_list_head;
 550
 551        INIT_LIST_HEAD(proc_list_head);
 552
 553        LIST_ADD_S("Description", adapter->id_string);
 554        LIST_ADD_F("Part_Number", &adapter->part_num, e1000_proc_part_number);
 555        LIST_ADD_S("Driver_Name", e1000_driver_name);
 556        LIST_ADD_S("Driver_Version", e1000_driver_version);
 557        LIST_ADD_H("PCI_Vendor", &hw->vendor_id);
 558        LIST_ADD_H("PCI_Device_ID", &hw->device_id);
 559        LIST_ADD_H("PCI_Subsystem_Vendor", &hw->subsystem_vendor_id);
 560        LIST_ADD_H("PCI_Subsystem_ID", &hw->subsystem_id);
 561        LIST_ADD_H("PCI_Revision_ID", &hw->revision_id);
 562        LIST_ADD_U("PCI_Bus", &adapter->pdev->bus->number);
 563        LIST_ADD_F("PCI_Slot", adapter, e1000_proc_slot);
 564
 565        if(adapter->hw.mac_type >= e1000_82543) {
 566                LIST_ADD_F("PCI_Bus_Type",
 567                           &hw->bus_type, e1000_proc_bus_type);
 568                LIST_ADD_F("PCI_Bus_Speed",
 569                           &hw->bus_speed, e1000_proc_bus_speed);
 570                LIST_ADD_F("PCI_Bus_Width",
 571                           &hw->bus_width, e1000_proc_bus_width);
 572        }
 573
 574        LIST_ADD_U("IRQ", &adapter->pdev->irq);
 575        LIST_ADD_S("System_Device_Name", adapter->netdev->name);
 576        LIST_ADD_F("Current_HWaddr",
 577                    adapter->netdev->dev_addr, e1000_proc_hwaddr);
 578        LIST_ADD_F("Permanent_HWaddr",
 579                    adapter->hw.perm_mac_addr, e1000_proc_hwaddr);
 580
 581        LIST_ADD_BLANK();
 582
 583        LIST_ADD_F("Link", adapter, e1000_proc_link);
 584        LIST_ADD_F("Speed", &adapter->link_speed, e1000_proc_link_speed);
 585        LIST_ADD_F("Duplex", &adapter->link_duplex, e1000_proc_link_duplex);
 586        LIST_ADD_F("State", adapter, e1000_proc_state);
 587
 588        LIST_ADD_BLANK();
 589
 590        /* Standard net device stats */
 591        LIST_ADD_U("Rx_Packets", &adapter->net_stats.rx_packets);
 592        LIST_ADD_U("Tx_Packets", &adapter->net_stats.tx_packets);
 593        LIST_ADD_U("Rx_Bytes", &adapter->net_stats.rx_bytes);
 594        LIST_ADD_U("Tx_Bytes", &adapter->net_stats.tx_bytes);
 595        LIST_ADD_U("Rx_Errors", &adapter->net_stats.rx_errors);
 596        LIST_ADD_U("Tx_Errors", &adapter->net_stats.tx_errors);
 597        LIST_ADD_U("Rx_Dropped", &adapter->net_stats.rx_dropped);
 598        LIST_ADD_U("Tx_Dropped", &adapter->net_stats.tx_dropped);
 599
 600        LIST_ADD_U("Multicast", &adapter->net_stats.multicast);
 601        LIST_ADD_U("Collisions", &adapter->net_stats.collisions);
 602
 603        LIST_ADD_U("Rx_Length_Errors", &adapter->net_stats.rx_length_errors);
 604        LIST_ADD_U("Rx_Over_Errors", &adapter->net_stats.rx_over_errors);
 605        LIST_ADD_U("Rx_CRC_Errors", &adapter->net_stats.rx_crc_errors);
 606        LIST_ADD_U("Rx_Frame_Errors", &adapter->net_stats.rx_frame_errors);
 607        LIST_ADD_U("Rx_FIFO_Errors", &adapter->net_stats.rx_fifo_errors);
 608        LIST_ADD_U("Rx_Missed_Errors", &adapter->net_stats.rx_missed_errors);
 609
 610        LIST_ADD_U("Tx_Aborted_Errors", &adapter->net_stats.tx_aborted_errors);
 611        LIST_ADD_U("Tx_Carrier_Errors", &adapter->net_stats.tx_carrier_errors);
 612        LIST_ADD_U("Tx_FIFO_Errors", &adapter->net_stats.tx_fifo_errors);
 613        LIST_ADD_U("Tx_Heartbeat_Errors", 
 614                   &adapter->net_stats.tx_heartbeat_errors);
 615        LIST_ADD_U("Tx_Window_Errors", &adapter->net_stats.tx_window_errors);
 616
 617        /* 8254x-specific stats */
 618        LIST_ADD_U("Tx_Abort_Late_Coll", &adapter->stats.latecol);
 619        LIST_ADD_U("Tx_Deferred_Ok", &adapter->stats.dc);
 620        LIST_ADD_U("Tx_Single_Coll_Ok", &adapter->stats.scc);
 621        LIST_ADD_U("Tx_Multi_Coll_Ok", &adapter->stats.mcc);
 622        LIST_ADD_U("Rx_Long_Length_Errors", &adapter->stats.roc);
 623        LIST_ADD_U("Rx_Short_Length_Errors", &adapter->stats.ruc);
 624        
 625        /* The 82542 does not have some of these stats */
 626        if(adapter->hw.mac_type >= e1000_82543) {
 627                LIST_ADD_U("Rx_Align_Errors", &adapter->stats.algnerrc);
 628                LIST_ADD_U("Tx_TCP_Seg_Good", &adapter->stats.tsctc);
 629                LIST_ADD_U("Tx_TCP_Seg_Failed", &adapter->stats.tsctfc);
 630        }
 631        
 632        LIST_ADD_U("Rx_Flow_Control_XON", &adapter->stats.xonrxc);
 633        LIST_ADD_U("Rx_Flow_Control_XOFF", &adapter->stats.xoffrxc);
 634        LIST_ADD_U("Tx_Flow_Control_XON", &adapter->stats.xontxc);
 635        LIST_ADD_U("Tx_Flow_Control_XOFF", &adapter->stats.xofftxc);
 636        LIST_ADD_U("Rx_CSum_Offload_Good", &adapter->hw_csum_good);
 637        LIST_ADD_U("Rx_CSum_Offload_Errors", &adapter->hw_csum_err);
 638
 639        LIST_ADD_BLANK();
 640
 641        /* Cable diags */
 642        LIST_ADD_F("PHY_Media_Type", adapter, e1000_proc_media_type);
 643        if(adapter->hw.media_type == e1000_media_type_copper) {
 644                LIST_ADD_F("PHY_Cable_Length",
 645                           adapter, e1000_proc_cable_length);
 646                LIST_ADD_F("PHY_Extended_10Base_T_Distance",
 647                           adapter, e1000_proc_extended);
 648                LIST_ADD_F("PHY_Cable_Polarity",
 649                           adapter, e1000_proc_cable_polarity);
 650                LIST_ADD_F("PHY_Disable_Polarity_Correction",
 651                           adapter, e1000_proc_polarity_correction);
 652                LIST_ADD_U("PHY_Idle_Errors", 
 653                           &adapter->phy_stats.idle_errors);
 654                LIST_ADD_U("PHY_Receive_Errors",
 655                           &adapter->phy_stats.receive_errors);
 656                LIST_ADD_F("PHY_MDI_X_Enabled",
 657                           adapter, e1000_proc_mdi_x_enabled);
 658                LIST_ADD_F("PHY_Local_Receiver_Status",
 659                           &adapter->phy_info.local_rx, 
 660                           e1000_proc_rx_status);
 661                LIST_ADD_F("PHY_Remote_Receiver_Status",
 662                           &adapter->phy_info.remote_rx, 
 663                           e1000_proc_rx_status);
 664        }
 665
 666}
 667
 668/*
 669 * e1000_proc_dev_setup - create proc fs nodes and link list
 670 * @adapter: board private structure
 671 */
 672
 673void __devinit
 674e1000_proc_dev_setup(struct e1000_adapter *adapter)
 675{
 676        e1000_proc_list_setup(adapter);
 677
 678        e1000_proc_dirs_create(adapter, 
 679                               adapter->netdev->name,
 680                               &adapter->proc_list_head);
 681}
 682
 683/*
 684 * e1000_proc_dev_free - free proc fs nodes and link list
 685 * @adapter: board private structure
 686 */
 687
 688void __devexit
 689e1000_proc_dev_free(struct e1000_adapter *adapter)
 690{
 691        e1000_proc_dirs_free(adapter->netdev->name, &adapter->proc_list_head);
 692
 693        e1000_proc_list_free(&adapter->proc_list_head);
 694}
 695
 696#else /* CONFIG_PROC_FS */
 697
 698void __devinit e1000_proc_dev_setup(struct e1000_adapter *adapter) {}
 699void __devexit e1000_proc_dev_free(struct e1000_adapter *adapter) {}
 700
 701#endif /* CONFIG_PROC_FS */
 702
 703
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.