Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / drivers / net / bcm5700 / b57proc.c
1 /******************************************************************************/
2 /*                                                                            */
3 /* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2004 Broadcom  */
4 /* Corporation.                                                               */
5 /* All rights reserved.                                                       */
6 /*                                                                            */
7 /* This program is free software; you can redistribute it and/or modify       */
8 /* it under the terms of the GNU General Public License as published by       */
9 /* the Free Software Foundation, located in the file LICENSE.                 */
10 /*                                                                            */
11 /* /proc file system handling code.                                           */
12 /*                                                                            */
13 /******************************************************************************/
14
15 #include "mm.h"
16 #ifdef BCM_PROC_FS
17
18 #define NICINFO_PROC_DIR "nicinfo"
19
20 static struct proc_dir_entry *bcm5700_procfs_dir;
21
22 extern char bcm5700_driver[], bcm5700_version[];
23 extern int bcm5700_open(struct net_device *dev);
24
25 extern uint64_t bcm5700_crc_count(PUM_DEVICE_BLOCK pUmDevice);
26 extern uint64_t bcm5700_rx_err_count(PUM_DEVICE_BLOCK pUmDevice);
27
28 static char *na_str = "n/a";
29 static char *pause_str = "pause ";
30 static char *asym_pause_str = "asym_pause ";
31 static char *on_str = "on";
32 static char *off_str = "off";
33 static char *up_str = "up";
34 static char *down_str = "down";
35
36 int bcm5700_proc_create_dev(struct net_device *dev);
37 int bcm5700_proc_remove_dev(struct net_device *dev);
38
39 static int bcm5700_netdev_event(struct notifier_block * this, unsigned long event, void * ptr)
40 {
41         struct net_device * event_dev = (struct net_device *)ptr;
42
43         if (event == NETDEV_CHANGENAME) {
44                 if (event_dev->open == bcm5700_open) {
45                         bcm5700_proc_remove_dev(event_dev);
46                         bcm5700_proc_create_dev(event_dev);
47                 }
48         }
49
50         return NOTIFY_DONE;
51 }
52
53 static struct notifier_block bcm5700_netdev_notifier = {
54         .notifier_call = bcm5700_netdev_event
55 };
56
57 static struct proc_dir_entry *
58 proc_getdir(char *name, struct proc_dir_entry *proc_dir)
59 {
60         struct proc_dir_entry *pde = proc_dir;
61
62         lock_kernel();
63         for (pde=pde->subdir; pde; pde = pde->next) {
64                 if (pde->namelen && (strcmp(name, pde->name) == 0)) {
65                         /* directory exists */
66                         break;
67                 }
68         }
69         if (pde == (struct proc_dir_entry *) 0)
70         {
71                 /* create the directory */
72 #if (LINUX_VERSION_CODE > 0x20300)
73                 pde = proc_mkdir(name, proc_dir);
74 #else
75                 pde = create_proc_entry(name, S_IFDIR, proc_dir);
76 #endif
77                 if (pde == (struct proc_dir_entry *) 0) {
78                         unlock_kernel();
79                         return (pde);
80                 }
81         }
82         unlock_kernel();
83         return (pde);
84 }
85
86 int
87 bcm5700_proc_create(void)
88 {
89         bcm5700_procfs_dir = proc_getdir(NICINFO_PROC_DIR, proc_net);
90
91         if (bcm5700_procfs_dir == (struct proc_dir_entry *) 0) {
92                 printk(KERN_DEBUG "Could not create procfs nicinfo directory %s\n", NICINFO_PROC_DIR);
93                 return -1;
94         }
95         register_netdevice_notifier(&bcm5700_netdev_notifier);
96         return 0;
97 }
98
99 int
100 bcm5700_proc_remove_notifier(void)
101 {
102         unregister_netdevice_notifier(&bcm5700_netdev_notifier);
103         return 0;
104 }
105
106 void
107 b57_get_speed_adv(PUM_DEVICE_BLOCK pUmDevice, char *str)
108 {
109         PLM_DEVICE_BLOCK pDevice = &pUmDevice->lm_dev;
110
111         if (pDevice->DisableAutoNeg == TRUE) {
112                 strcpy(str, na_str);
113                 return;
114         }
115         if (pDevice->TbiFlags & ENABLE_TBI_FLAG) {
116                 strcpy(str, "1000full");
117                 return;
118         }
119         if (pDevice->PhyFlags & PHY_IS_FIBER) {
120                 if (pDevice->RequestedDuplexMode != LM_DUPLEX_MODE_HALF)
121                         strcpy(str, "1000full");
122                 else
123                         strcpy(str, "1000half");
124                 return;
125         }
126         str[0] = 0;
127         if (pDevice->advertising & PHY_AN_AD_10BASET_HALF) {
128                 strcat(str, "10half ");
129         }
130         if (pDevice->advertising & PHY_AN_AD_10BASET_FULL) {
131                 strcat(str, "10full ");
132         }
133         if (pDevice->advertising & PHY_AN_AD_100BASETX_HALF) {
134                 strcat(str, "100half ");
135         }
136         if (pDevice->advertising & PHY_AN_AD_100BASETX_FULL) {
137                 strcat(str, "100full ");
138         }
139         if (pDevice->advertising1000 & BCM540X_AN_AD_1000BASET_HALF) {
140                 strcat(str, "1000half ");
141         }
142         if (pDevice->advertising1000 & BCM540X_AN_AD_1000BASET_FULL) {
143                 strcat(str, "1000full ");
144         }
145 }
146
147 void
148 b57_get_fc_adv(PUM_DEVICE_BLOCK pUmDevice, char *str)
149 {
150         PLM_DEVICE_BLOCK pDevice = &pUmDevice->lm_dev;
151
152         if (pDevice->DisableAutoNeg == TRUE) {
153                 strcpy(str, na_str);
154                 return;
155         }
156         str[0] = 0;
157         if (pDevice->TbiFlags & ENABLE_TBI_FLAG) {
158                 if(pDevice->DisableAutoNeg == FALSE ||
159                         pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO) {
160                         if (pDevice->FlowControlCap &
161                                 LM_FLOW_CONTROL_RECEIVE_PAUSE) {
162
163                                 strcpy(str, pause_str);
164                                 if (!(pDevice->FlowControlCap &
165                                         LM_FLOW_CONTROL_TRANSMIT_PAUSE)) {
166
167                                         strcpy(str, asym_pause_str);
168                                 }
169                         }
170                         else if (pDevice->FlowControlCap &
171                                 LM_FLOW_CONTROL_TRANSMIT_PAUSE) {
172
173                                 strcpy(str, asym_pause_str);
174                         }
175                 }
176                 return;
177         }
178         if (pDevice->advertising & PHY_AN_AD_PAUSE_CAPABLE) {
179                 strcat(str, pause_str);
180         }
181         if (pDevice->advertising & PHY_AN_AD_ASYM_PAUSE) {
182                 strcat(str, asym_pause_str);
183         }
184 }
185
186 int
187 bcm5700_read_pfs(char *page, char **start, off_t off, int count,
188         int *eof, void *data)
189 {
190         struct net_device *dev = (struct net_device *) data;
191         PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) dev->priv;
192         PLM_DEVICE_BLOCK pDevice = &pUmDevice->lm_dev;
193         PT3_STATS_BLOCK pStats = (PT3_STATS_BLOCK) pDevice->pStatsBlkVirt;
194         int len = 0;
195         unsigned long rx_mac_errors, rx_crc_errors, rx_align_errors;
196         unsigned long rx_runt_errors, rx_frag_errors, rx_long_errors;
197         unsigned long rx_overrun_errors, rx_jabber_errors;
198         char str[64];
199
200         if (pUmDevice->opened == 0)
201                 pStats = 0;
202
203         len += sprintf(page+len, "Description\t\t\t%s\n", pUmDevice->name);
204         len += sprintf(page+len, "Driver_Name\t\t\t%s\n", bcm5700_driver);
205         len += sprintf(page+len, "Driver_Version\t\t\t%s\n", bcm5700_version);
206         len += sprintf(page+len, "Bootcode_Version\t\t%s\n", pDevice->BootCodeVer);
207         if( pDevice->IPMICodeVer[0] != 0 )
208                 len += sprintf(page+len, "ASF_IPMI_Version\t\t%s\n", pDevice->IPMICodeVer);
209         len += sprintf(page+len, "PCI_Vendor\t\t\t0x%04x\n", pDevice->PciVendorId);
210         len += sprintf(page+len, "PCI_Device_ID\t\t\t0x%04x\n",
211                 pDevice->PciDeviceId);
212         len += sprintf(page+len, "PCI_Subsystem_Vendor\t\t0x%04x\n",
213                 pDevice->SubsystemVendorId);
214         len += sprintf(page+len, "PCI_Subsystem_ID\t\t0x%04x\n",
215                 pDevice->SubsystemId);
216         len += sprintf(page+len, "PCI_Revision_ID\t\t\t0x%02x\n",
217                 pDevice->PciRevId);
218         len += sprintf(page+len, "PCI_Slot\t\t\t%d\n",
219                 PCI_SLOT(pUmDevice->pdev->devfn));
220         if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
221         {
222                 len += sprintf(page+len, "PCI_Function\t\t\t%d\n",
223                         pDevice->FunctNum);
224         }
225         len += sprintf(page+len, "PCI_Bus\t\t\t\t%d\n",
226                 pUmDevice->pdev->bus->number);
227
228         len += sprintf(page+len, "PCI_Bus_Speed\t\t\t%s\n",
229                 pDevice->BusSpeedStr);
230
231         len += sprintf(page+len, "Memory\t\t\t\t0x%lx\n", pUmDevice->dev->base_addr);
232         len += sprintf(page+len, "IRQ\t\t\t\t%d\n", dev->irq);
233         len += sprintf(page+len, "System_Device_Name\t\t%s\n", dev->name);
234         len += sprintf(page+len, "Current_HWaddr\t\t\t%02x:%02x:%02x:%02x:%02x:%02x\n",
235                 dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
236                 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
237         len += sprintf(page+len,
238                 "Permanent_HWaddr\t\t%02x:%02x:%02x:%02x:%02x:%02x\n",
239                 pDevice->NodeAddress[0], pDevice->NodeAddress[1],
240                 pDevice->NodeAddress[2], pDevice->NodeAddress[3],
241                 pDevice->NodeAddress[4], pDevice->NodeAddress[5]);
242         len += sprintf(page+len, "Part_Number\t\t\t%s\n\n", pDevice->PartNo);
243
244         len += sprintf(page+len, "Link\t\t\t\t%s\n", 
245                 (pUmDevice->opened == 0) ? "unknown" :
246                 ((pDevice->LinkStatus == LM_STATUS_LINK_ACTIVE) ? up_str :
247                 down_str));
248         len += sprintf(page+len, "Auto_Negotiate\t\t\t%s\n", 
249                 (pDevice->DisableAutoNeg == TRUE) ? off_str : on_str);
250         b57_get_speed_adv(pUmDevice, str);
251         len += sprintf(page+len, "Speed_Advertisement\t\t%s\n", str);
252         b57_get_fc_adv(pUmDevice, str);
253         len += sprintf(page+len, "Flow_Control_Advertisement\t%s\n", str);
254         len += sprintf(page+len, "Speed\t\t\t\t%s\n", 
255                 ((pDevice->LinkStatus == LM_STATUS_LINK_DOWN) ||
256                 (pUmDevice->opened == 0)) ? na_str :
257                 ((pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) ? "1000" :
258                 ((pDevice->LineSpeed == LM_LINE_SPEED_100MBPS) ? "100" :
259                 (pDevice->LineSpeed == LM_LINE_SPEED_10MBPS) ? "10" : na_str)));
260         len += sprintf(page+len, "Duplex\t\t\t\t%s\n", 
261                 ((pDevice->LinkStatus == LM_STATUS_LINK_DOWN) ||
262                 (pUmDevice->opened == 0)) ? na_str :
263                 ((pDevice->DuplexMode == LM_DUPLEX_MODE_FULL) ? "full" :
264                         "half"));
265         len += sprintf(page+len, "Flow_Control\t\t\t%s\n", 
266                 ((pDevice->LinkStatus == LM_STATUS_LINK_DOWN) ||
267                 (pUmDevice->opened == 0)) ? na_str :
268                 ((pDevice->FlowControl == LM_FLOW_CONTROL_NONE) ? off_str :
269                 (((pDevice->FlowControl & LM_FLOW_CONTROL_RX_TX_PAUSE) ==
270                         LM_FLOW_CONTROL_RX_TX_PAUSE) ? "receive/transmit" :
271                 (pDevice->FlowControl & LM_FLOW_CONTROL_RECEIVE_PAUSE) ?
272                         "receive" : "transmit")));
273         len += sprintf(page+len, "State\t\t\t\t%s\n", 
274                 (pUmDevice->suspended ? "suspended" :
275                 ((dev->flags & IFF_UP) ? up_str : down_str)));
276         len += sprintf(page+len, "MTU_Size\t\t\t%d\n\n", dev->mtu);
277         len += sprintf(page+len, "Rx_Packets\t\t\t%lu\n", 
278                         ((pStats == 0) ? 0 :
279                         MM_GETSTATS(pStats->ifHCInUcastPkts) +
280                         MM_GETSTATS(pStats->ifHCInMulticastPkts) +
281                         MM_GETSTATS(pStats->ifHCInBroadcastPkts)));
282 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
283         if ((dev->mtu > 1500) && !T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId)) {
284                 len += sprintf(page+len, "Rx_Jumbo_Packets\t\t%lu\n", 
285                         ((pStats == 0) ? 0 :
286                         MM_GETSTATS(
287                                 pStats->etherStatsPkts1523Octetsto2047Octets) +
288                         MM_GETSTATS(
289                                 pStats->etherStatsPkts2048Octetsto4095Octets) +
290                         MM_GETSTATS(
291                                 pStats->etherStatsPkts4096Octetsto8191Octets) +
292                         MM_GETSTATS(
293                                 pStats->etherStatsPkts8192Octetsto9022Octets)));
294         }
295 #endif
296         len += sprintf(page+len, "Tx_Packets\t\t\t%lu\n",
297                 ((pStats == 0) ? 0 :
298                 MM_GETSTATS(pStats->ifHCOutUcastPkts) +
299                 MM_GETSTATS(pStats->ifHCOutMulticastPkts) +
300                 MM_GETSTATS(pStats->ifHCOutBroadcastPkts)));
301 #ifdef BCM_TSO
302         len += sprintf(page+len, "TSO_Large_Packets\t\t%lu\n",
303                 pUmDevice->tso_pkt_count);
304 #endif
305         len += sprintf(page+len, "Rx_Bytes\t\t\t%lu\n",
306                 ((pStats == 0) ? 0 :
307                 MM_GETSTATS(pStats->ifHCInOctets)));
308         len += sprintf(page+len, "Tx_Bytes\t\t\t%lu\n",
309                 ((pStats == 0) ? 0 :
310                 MM_GETSTATS(pStats->ifHCOutOctets)));
311         if (pStats == 0) {
312                 rx_crc_errors = 0;
313                 rx_align_errors = 0;
314                 rx_runt_errors = 0;
315                 rx_frag_errors = 0;
316                 rx_long_errors = 0;
317                 rx_overrun_errors = 0;
318                 rx_jabber_errors = 0;
319         }
320         else {
321                 rx_crc_errors = (unsigned long) bcm5700_crc_count(pUmDevice);
322                 rx_align_errors = MM_GETSTATS(pStats->dot3StatsAlignmentErrors);
323                 rx_runt_errors = MM_GETSTATS(pStats->etherStatsUndersizePkts);
324                 rx_frag_errors = MM_GETSTATS(pStats->etherStatsFragments);
325                 rx_long_errors = MM_GETSTATS(pStats->dot3StatsFramesTooLong);
326                 rx_overrun_errors = MM_GETSTATS(pStats->nicNoMoreRxBDs);
327                 rx_jabber_errors = MM_GETSTATS(pStats->etherStatsJabbers);
328         }
329         rx_mac_errors = (unsigned long) bcm5700_rx_err_count(pUmDevice);
330         len += sprintf(page+len, "Rx_Errors\t\t\t%lu\n",
331                 ((pStats == 0) ? 0 :
332                 rx_mac_errors + rx_overrun_errors + pUmDevice->rx_misc_errors));
333         len += sprintf(page+len, "Tx_Errors\t\t\t%lu\n",
334                 ((pStats == 0) ? 0 :
335                 MM_GETSTATS(pStats->ifOutErrors)));
336         len += sprintf(page+len, "\nTx_Carrier_Errors\t\t%lu\n",
337                 ((pStats == 0) ? 0 :
338                 MM_GETSTATS(pStats->dot3StatsCarrierSenseErrors)));
339         len += sprintf(page+len, "Tx_Abort_Excess_Coll\t\t%lu\n",
340                 ((pStats == 0) ? 0 :
341                 MM_GETSTATS(pStats->dot3StatsExcessiveCollisions)));
342         len += sprintf(page+len, "Tx_Abort_Late_Coll\t\t%lu\n",
343                 ((pStats == 0) ? 0 :
344                 MM_GETSTATS(pStats->dot3StatsLateCollisions)));
345         len += sprintf(page+len, "Tx_Deferred_Ok\t\t\t%lu\n",
346                 ((pStats == 0) ? 0 :
347                 MM_GETSTATS(pStats->dot3StatsDeferredTransmissions)));
348         len += sprintf(page+len, "Tx_Single_Coll_Ok\t\t%lu\n",
349                 ((pStats == 0) ? 0 :
350                 MM_GETSTATS(pStats->dot3StatsSingleCollisionFrames)));
351         len += sprintf(page+len, "Tx_Multi_Coll_Ok\t\t%lu\n",
352                 ((pStats == 0) ? 0 :
353                 MM_GETSTATS(pStats->dot3StatsMultipleCollisionFrames)));
354         len += sprintf(page+len, "Tx_Total_Coll_Ok\t\t%lu\n",
355                 ((pStats == 0) ? 0 :
356                 MM_GETSTATS(pStats->etherStatsCollisions)));
357         len += sprintf(page+len, "Tx_XON_Pause_Frames\t\t%lu\n",
358                 ((pStats == 0) ? 0 :
359                 MM_GETSTATS(pStats->outXonSent)));
360         len += sprintf(page+len, "Tx_XOFF_Pause_Frames\t\t%lu\n",
361                 ((pStats == 0) ? 0 :
362                 MM_GETSTATS(pStats->outXoffSent)));
363         len += sprintf(page+len, "\nRx_CRC_Errors\t\t\t%lu\n", rx_crc_errors);
364         len += sprintf(page+len, "Rx_Short_Fragment_Errors\t%lu\n",
365                 rx_frag_errors);
366         len += sprintf(page+len, "Rx_Short_Length_Errors\t\t%lu\n",
367                 rx_runt_errors);
368         len += sprintf(page+len, "Rx_Long_Length_Errors\t\t%lu\n",
369                 rx_long_errors);
370         len += sprintf(page+len, "Rx_Align_Errors\t\t\t%lu\n",
371                 rx_align_errors);
372         len += sprintf(page+len, "Rx_Overrun_Errors\t\t%lu\n",
373                 rx_overrun_errors);
374         len += sprintf(page+len, "Rx_XON_Pause_Frames\t\t%lu\n",
375                 ((pStats == 0) ? 0 :
376                 MM_GETSTATS(pStats->xonPauseFramesReceived)));
377         len += sprintf(page+len, "Rx_XOFF_Pause_Frames\t\t%lu\n",
378                 ((pStats == 0) ? 0 :
379                 MM_GETSTATS(pStats->xoffPauseFramesReceived)));
380         len += sprintf(page+len, "\nTx_MAC_Errors\t\t\t%lu\n",
381                 ((pStats == 0) ? 0 :
382                 MM_GETSTATS(pStats->dot3StatsInternalMacTransmitErrors)));
383         len += sprintf(page+len, "Rx_MAC_Errors\t\t\t%lu\n\n",
384                 rx_mac_errors);
385
386         len += sprintf(page+len, "Tx_Checksum\t\t\t%s\n",
387                 ((pDevice->TaskToOffload & LM_TASK_OFFLOAD_TX_TCP_CHECKSUM) ?
388                 on_str : off_str));
389         len += sprintf(page+len, "Rx_Checksum\t\t\t%s\n",
390                 ((pDevice->TaskToOffload & LM_TASK_OFFLOAD_RX_TCP_CHECKSUM) ?
391                 on_str : off_str));
392         len += sprintf(page+len, "Scatter_Gather\t\t\t%s\n",
393 #if (LINUX_VERSION_CODE >= 0x20400)
394                 ((dev->features & NETIF_F_SG) ? on_str : off_str));
395 #else
396                 off_str);
397 #endif
398 #ifdef BCM_TSO
399         len += sprintf(page+len, "TSO\t\t\t\t%s\n",
400                 ((dev->features & NETIF_F_TSO) ? on_str : off_str));
401 #endif
402         len += sprintf(page+len, "VLAN\t\t\t\t%s\n\n",
403                 ((pDevice->RxMode & RX_MODE_KEEP_VLAN_TAG) ? off_str : on_str));
404
405 #ifdef BCM_NIC_SEND_BD
406         len += sprintf(page+len, "NIC_Tx_BDs\t\t\t%s\n",
407                 (pDevice->Flags & NIC_SEND_BD_FLAG) ? on_str : off_str);
408 #endif
409         len += sprintf(page+len, "Tx_Desc_Count\t\t\t%u\n",
410                 pDevice->TxPacketDescCnt);
411         len += sprintf(page+len, "Rx_Desc_Count\t\t\t%u\n",
412                 pDevice->RxStdDescCnt);
413 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
414         len += sprintf(page+len, "Rx_Jumbo_Desc_Count\t\t%u\n",
415                 pDevice->RxJumboDescCnt);
416 #endif
417 #ifdef BCM_INT_COAL
418         len += sprintf(page+len, "Adaptive_Coalescing\t\t%s\n",
419                 (pUmDevice->adaptive_coalesce ? on_str : off_str));
420         len += sprintf(page+len, "Rx_Coalescing_Ticks\t\t%u\n",
421                 pUmDevice->rx_curr_coalesce_ticks);
422         len += sprintf(page+len, "Rx_Coalesced_Frames\t\t%u\n",
423                 pUmDevice->rx_curr_coalesce_frames);
424         len += sprintf(page+len, "Tx_Coalescing_Ticks\t\t%u\n",
425                 pDevice->TxCoalescingTicks);
426         len += sprintf(page+len, "Tx_Coalesced_Frames\t\t%u\n",
427                 pUmDevice->tx_curr_coalesce_frames);
428         len += sprintf(page+len, "Stats_Coalescing_Ticks\t\t%u\n",
429                 pDevice->StatsCoalescingTicks);
430 #endif
431 #ifdef BCM_WOL
432         len += sprintf(page+len, "Wake_On_LAN\t\t\t%s\n",
433                 ((pDevice->WakeUpMode & LM_WAKE_UP_MODE_MAGIC_PACKET) ?
434                 on_str : off_str));
435 #endif
436 #if TIGON3_DEBUG
437         len += sprintf(page+len, "\nDmaReadWriteCtrl\t\t%x\n",
438                 pDevice->DmaReadWriteCtrl);
439         len += sprintf(page+len, "\nTx_Zero_Copy_Packets\t\t%u\n",
440                 pUmDevice->tx_zc_count);
441         len += sprintf(page+len, "Tx_Chksum_Packets\t\t%u\n",
442                 pUmDevice->tx_chksum_count);
443         len += sprintf(page+len, "Tx_Highmem_Fragments\t\t%u\n",
444                 pUmDevice->tx_himem_count);
445         len += sprintf(page+len, "Rx_Good_Chksum_Packets\t\t%u\n",
446                 pUmDevice->rx_good_chksum_count);
447         len += sprintf(page+len, "Rx_Bad_Chksum_Packets\t\t%u\n",
448                 pUmDevice->rx_bad_chksum_count);
449
450 #endif
451
452         *eof = 1;
453         return len;
454 }
455
456 int
457 bcm5700_proc_create_dev(struct net_device *dev)
458 {
459         PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) dev->priv;
460
461         if (!bcm5700_procfs_dir)
462                 return -1;
463
464         sprintf(pUmDevice->pfs_name, "%s.info", dev->name);
465         pUmDevice->pfs_entry = create_proc_entry(pUmDevice->pfs_name,
466                 S_IFREG, bcm5700_procfs_dir);
467         if (pUmDevice->pfs_entry == 0)
468                 return -1;
469         pUmDevice->pfs_entry->read_proc = bcm5700_read_pfs;
470         pUmDevice->pfs_entry->data = dev;
471         return 0;
472 }
473 int
474 bcm5700_proc_remove_dev(struct net_device *dev)
475 {
476         PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) dev->priv;
477
478         remove_proc_entry(pUmDevice->pfs_name, bcm5700_procfs_dir);
479         return 0;
480 }
481
482 #endif