1 /******************************************************************************/
3 /* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2005 Broadcom */
5 /* All rights reserved. */
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. */
11 /******************************************************************************/
13 /* $Id: b57um.c,v 1.32 2007/09/06 07:28:06 yogo Exp $ */
15 char bcm5700_driver
[] = "bcm57xx";
16 char bcm5700_version
[] = "8.3.14";
17 char bcm5700_date
[] = "(11/2/05)";
21 #include "linux/mii.h" //@.@jack add it 2006/06/28.
30 #include "robo_register.c"
32 #include "bcmendian.h"
34 #include "proto/ethernet.h"
35 #include "proto/vlan.h"
36 #include "proto/bcmtcp.h"
37 #include "proto/bcmip.h"
38 #define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data)
40 /* this is needed to get good and stable performances */
41 #define EXTRA_HDR BCMEXTRAHDROOM
43 #define SIOCGREG_STATUS 0x8996 /* Read Switch register (for debug)*/
44 #define SIOCSREG_STATUS 0x8997 /* Write Switch register(for debug)*/
46 /* This structure is used in SIOCXREG_STATUS ioctl calls*/
47 struct reg_ioctl_data
{
55 /* A few user-configurable values. */
58 /* Used to pass the full-duplex flag, etc. */
59 static int line_speed
[MAX_UNITS
] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
60 static int auto_speed
[MAX_UNITS
] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
61 static int full_duplex
[MAX_UNITS
] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
62 static int rx_flow_control
[MAX_UNITS
] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
63 static int tx_flow_control
[MAX_UNITS
] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
64 static int auto_flow_control
[MAX_UNITS
] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
65 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
66 static int mtu
[MAX_UNITS
] = {1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500}; /* Jumbo MTU for interfaces. */
68 static int tx_checksum
[MAX_UNITS
] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
69 static int rx_checksum
[MAX_UNITS
] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
70 static int scatter_gather
[MAX_UNITS
] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
71 static int activate_gpio
= -1;
73 #define TX_DESC_CNT DEFAULT_TX_PACKET_DESC_COUNT
74 static unsigned int tx_pkt_desc_cnt
[MAX_UNITS
] =
75 {TX_DESC_CNT
,TX_DESC_CNT
,TX_DESC_CNT
,TX_DESC_CNT
,TX_DESC_CNT
,
76 TX_DESC_CNT
,TX_DESC_CNT
,TX_DESC_CNT
,TX_DESC_CNT
,TX_DESC_CNT
,
77 TX_DESC_CNT
,TX_DESC_CNT
,TX_DESC_CNT
,TX_DESC_CNT
,TX_DESC_CNT
,
80 #define RX_DESC_CNT DEFAULT_STD_RCV_DESC_COUNT
81 static unsigned int rx_std_desc_cnt
[MAX_UNITS
] =
82 {RX_DESC_CNT
,RX_DESC_CNT
,RX_DESC_CNT
,RX_DESC_CNT
,RX_DESC_CNT
,
83 RX_DESC_CNT
,RX_DESC_CNT
,RX_DESC_CNT
,RX_DESC_CNT
,RX_DESC_CNT
,
84 RX_DESC_CNT
,RX_DESC_CNT
,RX_DESC_CNT
,RX_DESC_CNT
,RX_DESC_CNT
,
87 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
88 #define JBO_DESC_CNT DEFAULT_JUMBO_RCV_DESC_COUNT
89 static unsigned int rx_jumbo_desc_cnt
[MAX_UNITS
] =
90 {JBO_DESC_CNT
,JBO_DESC_CNT
,JBO_DESC_CNT
,JBO_DESC_CNT
,JBO_DESC_CNT
,
91 JBO_DESC_CNT
,JBO_DESC_CNT
,JBO_DESC_CNT
,JBO_DESC_CNT
,JBO_DESC_CNT
,
92 JBO_DESC_CNT
,JBO_DESC_CNT
,JBO_DESC_CNT
,JBO_DESC_CNT
,JBO_DESC_CNT
,
97 #ifdef BCM_NAPI_RXPOLL
98 static unsigned int adaptive_coalesce
[MAX_UNITS
] =
99 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
101 static unsigned int adaptive_coalesce
[MAX_UNITS
] =
102 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
105 #define RX_COAL_TK DEFAULT_RX_COALESCING_TICKS
106 static unsigned int rx_coalesce_ticks
[MAX_UNITS
] =
107 {RX_COAL_TK
,RX_COAL_TK
,RX_COAL_TK
,RX_COAL_TK
,RX_COAL_TK
,
108 RX_COAL_TK
, RX_COAL_TK
,RX_COAL_TK
,RX_COAL_TK
,RX_COAL_TK
,
109 RX_COAL_TK
,RX_COAL_TK
, RX_COAL_TK
,RX_COAL_TK
,RX_COAL_TK
,
112 #define RX_COAL_FM DEFAULT_RX_MAX_COALESCED_FRAMES
113 static unsigned int rx_max_coalesce_frames
[MAX_UNITS
] =
114 {RX_COAL_FM
,RX_COAL_FM
,RX_COAL_FM
,RX_COAL_FM
,RX_COAL_FM
,
115 RX_COAL_FM
,RX_COAL_FM
,RX_COAL_FM
,RX_COAL_FM
,RX_COAL_FM
,
116 RX_COAL_FM
,RX_COAL_FM
,RX_COAL_FM
,RX_COAL_FM
,RX_COAL_FM
,
119 #define TX_COAL_TK DEFAULT_TX_COALESCING_TICKS
120 static unsigned int tx_coalesce_ticks
[MAX_UNITS
] =
121 {TX_COAL_TK
,TX_COAL_TK
,TX_COAL_TK
,TX_COAL_TK
,TX_COAL_TK
,
122 TX_COAL_TK
, TX_COAL_TK
,TX_COAL_TK
,TX_COAL_TK
,TX_COAL_TK
,
123 TX_COAL_TK
,TX_COAL_TK
, TX_COAL_TK
,TX_COAL_TK
,TX_COAL_TK
,
126 #define TX_COAL_FM DEFAULT_TX_MAX_COALESCED_FRAMES
127 static unsigned int tx_max_coalesce_frames
[MAX_UNITS
] =
128 {TX_COAL_FM
,TX_COAL_FM
,TX_COAL_FM
,TX_COAL_FM
,TX_COAL_FM
,
129 TX_COAL_FM
,TX_COAL_FM
,TX_COAL_FM
,TX_COAL_FM
,TX_COAL_FM
,
130 TX_COAL_FM
,TX_COAL_FM
,TX_COAL_FM
,TX_COAL_FM
,TX_COAL_FM
,
133 #define ST_COAL_TK DEFAULT_STATS_COALESCING_TICKS
134 static unsigned int stats_coalesce_ticks
[MAX_UNITS
] =
135 {ST_COAL_TK
,ST_COAL_TK
,ST_COAL_TK
,ST_COAL_TK
,ST_COAL_TK
,
136 ST_COAL_TK
,ST_COAL_TK
,ST_COAL_TK
,ST_COAL_TK
,ST_COAL_TK
,
137 ST_COAL_TK
,ST_COAL_TK
,ST_COAL_TK
,ST_COAL_TK
,ST_COAL_TK
,
142 static int enable_wol
[MAX_UNITS
] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
145 static int enable_tso
[MAX_UNITS
] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
147 #ifdef BCM_NIC_SEND_BD
148 static int nic_tx_bd
[MAX_UNITS
] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
151 static int vlan_tag_mode
[MAX_UNITS
] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
153 static int delay_link
[MAX_UNITS
] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
154 static int disable_d3hot
[MAX_UNITS
] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
156 #if defined(CONFIG_PCI_MSI) || defined(CONFIG_PCI_USE_VECTOR)
157 static int disable_msi
[MAX_UNITS
] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
158 static int bcm_msi_chipset_bug
= 0;
161 #define BCM_TIMER_GRANULARITY (1000000 / HZ)
163 /* Hack to hook the data path to the BCM WL dirver */
164 #ifdef BCM_WL_EMULATOR
165 #include "bcmnvram.h"
166 #include "wl_bcm57emu.h"
168 int skb_old_alloc
= 0;
170 #endif /* BCM_WL_EMULATOR */
172 /* Operational parameters that usually are not changed. */
173 /* Time in jiffies before concluding the transmitter is hung. */
174 #define TX_TIMEOUT (2*HZ)
176 #if (LINUX_VERSION_CODE < 0x02030d)
177 #define pci_resource_start(dev, bar) (dev->base_address[bar] & PCI_BASE_ADDRESS_MEM_MASK)
178 #elif (LINUX_VERSION_CODE < 0x02032b)
179 #define pci_resource_start(dev, bar) (dev->resource[bar] & PCI_BASE_ADDRESS_MEM_MASK)
182 #if (LINUX_VERSION_CODE < 0x02032b)
183 #define dev_kfree_skb_irq(skb) dev_kfree_skb(skb)
184 #define netif_wake_queue(dev) clear_bit(0, &dev->tbusy); mark_bh(NET_BH)
185 #define netif_stop_queue(dev) set_bit(0, &dev->tbusy)
187 static inline void netif_start_queue(struct net_device
*dev
)
194 #define netif_queue_stopped(dev) dev->tbusy
195 #define netif_running(dev) dev->start
197 static inline void tasklet_schedule(struct tasklet_struct
*tasklet
)
199 queue_task(tasklet
, &tq_immediate
);
200 mark_bh(IMMEDIATE_BH
);
203 static inline void tasklet_init(struct tasklet_struct
*tasklet
,
204 void (*func
)(unsigned long),
207 tasklet
->next
= NULL
;
209 tasklet
->routine
= (void (*)(void *))func
;
210 tasklet
->data
= (void *)data
;
213 #define tasklet_kill(tasklet)
217 #if (LINUX_VERSION_CODE < 0x020300)
218 struct pci_device_id
{
219 unsigned int vendor
, device
; /* Vendor and device ID or PCI_ANY_ID */
220 unsigned int subvendor
, subdevice
; /* Subsystem ID's or PCI_ANY_ID */
221 unsigned int class, class_mask
; /* (class,subclass,prog-if) triplet */
222 unsigned long driver_data
; /* Data private to the driver */
227 #define pci_set_drvdata(pdev, dev)
228 #define pci_get_drvdata(pdev) 0
230 #define pci_enable_device(pdev) 0
232 #define __devinit __init
233 #define __devinitdata __initdata
236 #define SET_MODULE_OWNER(dev)
237 #define MODULE_DEVICE_TABLE(pci, pci_tbl)
241 #if (LINUX_VERSION_CODE < 0x020411)
243 #define __devexit_p(x) x
247 #ifndef MODULE_LICENSE
248 #define MODULE_LICENSE(license)
252 typedef void irqreturn_t
;
253 #define IRQ_RETVAL(x)
256 #if (LINUX_VERSION_CODE < 0x02032a)
257 static inline void *pci_alloc_consistent(struct pci_dev
*pdev
, size_t size
,
258 dma_addr_t
*dma_handle
)
262 /* Maximum in slab.c */
266 virt_ptr
= kmalloc(size
, GFP_KERNEL
);
267 *dma_handle
= virt_to_bus(virt_ptr
);
270 #define pci_free_consistent(dev, size, ptr, dma_ptr) kfree(ptr)
272 #endif /*#if (LINUX_VERSION_CODE < 0x02032a) */
275 #if (LINUX_VERSION_CODE < 0x02040d)
277 #if (LINUX_VERSION_CODE >= 0x020409) && defined(RED_HAT_LINUX_KERNEL)
279 #define BCM_32BIT_DMA_MASK ((u64) 0x00000000ffffffffULL)
280 #define BCM_64BIT_DMA_MASK ((u64) 0xffffffffffffffffULL)
283 /* pci_set_dma_mask is using dma_addr_t */
285 #define BCM_32BIT_DMA_MASK ((dma_addr_t) 0xffffffff)
286 #define BCM_64BIT_DMA_MASK ((dma_addr_t) 0xffffffff)
290 #else /* (LINUX_VERSION_CODE < 0x02040d) */
292 #define BCM_32BIT_DMA_MASK ((u64) 0x00000000ffffffffULL)
293 #define BCM_64BIT_DMA_MASK ((u64) 0xffffffffffffffffULL)
296 #if (LINUX_VERSION_CODE < 0x020329)
297 #define pci_set_dma_mask(pdev, mask) (0)
299 #if (LINUX_VERSION_CODE < 0x020403)
301 pci_set_dma_mask(struct pci_dev
*dev
, dma_addr_t mask
)
303 if(! pci_dma_supported(dev
, mask
))
306 dev
->dma_mask
= mask
;
313 #if (LINUX_VERSION_CODE < 0x020547)
314 #define pci_set_consistent_dma_mask(pdev, mask) (0)
317 #if (LINUX_VERSION_CODE < 0x020402)
318 #define pci_request_regions(pdev, name) (0)
319 #define pci_release_regions(pdev)
322 #if !defined(spin_is_locked)
323 #define spin_is_locked(lock) (test_bit(0,(lock)))
326 #define BCM5700_LOCK(pUmDevice, flags) \
327 if ((pUmDevice)->do_global_lock) { \
328 spin_lock_irqsave(&(pUmDevice)->global_lock, flags); \
331 #define BCM5700_UNLOCK(pUmDevice, flags) \
332 if ((pUmDevice)->do_global_lock) { \
333 spin_unlock_irqrestore(&(pUmDevice)->global_lock, flags);\
337 bcm5700_intr_lock(PUM_DEVICE_BLOCK pUmDevice
)
339 if (pUmDevice
->do_global_lock
) {
340 spin_lock(&pUmDevice
->global_lock
);
345 bcm5700_intr_unlock(PUM_DEVICE_BLOCK pUmDevice
)
347 if (pUmDevice
->do_global_lock
) {
348 spin_unlock(&pUmDevice
->global_lock
);
353 bcm5700_intr_off(PUM_DEVICE_BLOCK pUmDevice
)
355 atomic_inc(&pUmDevice
->intr_sem
);
356 LM_DisableInterrupt(&pUmDevice
->lm_dev
);
357 #if (LINUX_VERSION_CODE >= 0x2051c)
358 synchronize_irq(pUmDevice
->dev
->irq
);
362 LM_DisableInterrupt(&pUmDevice
->lm_dev
);
366 bcm5700_intr_on(PUM_DEVICE_BLOCK pUmDevice
)
368 if (atomic_dec_and_test(&pUmDevice
->intr_sem
)) {
369 LM_EnableInterrupt(&pUmDevice
->lm_dev
);
374 int MM_Packet_Desc_Size
= sizeof(UM_PACKET
);
377 MODULE_AUTHOR("Michael Chan <mchan at broadcom dot com> and Gary Zambrano <zambrano at broadcom dot com>");
378 MODULE_DESCRIPTION("BCM5700 Driver");
379 MODULE_LICENSE("GPL");
381 #if (LINUX_VERSION_CODE < 0x020605)
383 MODULE_PARM(debug
, "i");
384 MODULE_PARM(msglevel
, "i");
385 MODULE_PARM(activate_gpio
, "0-15i");
386 MODULE_PARM(line_speed
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
387 MODULE_PARM(auto_speed
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
388 MODULE_PARM(full_duplex
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
389 MODULE_PARM(rx_flow_control
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
390 MODULE_PARM(tx_flow_control
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
391 MODULE_PARM(auto_flow_control
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
392 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
393 MODULE_PARM(mtu
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
395 MODULE_PARM(tx_checksum
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
396 MODULE_PARM(rx_checksum
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
397 MODULE_PARM(scatter_gather
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
398 MODULE_PARM(tx_pkt_desc_cnt
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
399 MODULE_PARM(rx_std_desc_cnt
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
400 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
401 MODULE_PARM(rx_jumbo_desc_cnt
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
404 MODULE_PARM(adaptive_coalesce
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
405 MODULE_PARM(rx_coalesce_ticks
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
406 MODULE_PARM(rx_max_coalesce_frames
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
407 MODULE_PARM(tx_coalesce_ticks
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
408 MODULE_PARM(tx_max_coalesce_frames
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
409 MODULE_PARM(stats_coalesce_ticks
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
412 MODULE_PARM(enable_wol
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
415 MODULE_PARM(enable_tso
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
417 #ifdef BCM_NIC_SEND_BD
418 MODULE_PARM(nic_tx_bd
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
421 MODULE_PARM(vlan_tag_mode
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
423 MODULE_PARM(delay_link
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
424 MODULE_PARM(disable_d3hot
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
426 #if defined(CONFIG_PCI_MSI) || defined(CONFIG_PCI_USE_VECTOR)
427 MODULE_PARM(disable_msi
, "1-" __MODULE_STRING(MAX_UNITS
) "i");
432 #if (LINUX_VERSION_CODE >= 0x020605) && (LINUX_VERSION_CODE < 0x02060a)
440 #if (LINUX_VERSION_CODE >= 0x2060a)
446 module_param_array(line_speed
, int, numvar
, 0);
447 module_param_array(auto_speed
, int, numvar
, 0);
448 module_param_array(full_duplex
, int, numvar
, 0);
449 module_param_array(rx_flow_control
, int, numvar
, 0);
450 module_param_array(tx_flow_control
, int, numvar
, 0);
451 module_param_array(auto_flow_control
, int, numvar
, 0);
452 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
453 module_param_array(mtu
, int, numvar
, 0);
455 module_param_array(tx_checksum
, int, numvar
, 0);
456 module_param_array(rx_checksum
, int, numvar
, 0);
457 module_param_array(scatter_gather
, int, numvar
, 0);
458 module_param_array(tx_pkt_desc_cnt
, int, numvar
, 0);
459 module_param_array(rx_std_desc_cnt
, int, numvar
, 0);
460 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
461 module_param_array(rx_jumbo_desc_cnt
, int, numvar
, 0);
464 module_param_array(adaptive_coalesce
, int, numvar
, 0);
465 module_param_array(rx_coalesce_ticks
, int, numvar
, 0);
466 module_param_array(rx_max_coalesce_frames
, int, numvar
, 0);
467 module_param_array(tx_coalesce_ticks
, int, numvar
, 0);
468 module_param_array(tx_max_coalesce_frames
, int, numvar
, 0);
469 module_param_array(stats_coalesce_ticks
, int, numvar
, 0);
472 module_param_array(enable_wol
, int, numvar
, 0);
475 module_param_array(enable_tso
, int, numvar
, 0);
477 #ifdef BCM_NIC_SEND_BD
478 module_param_array(nic_tx_bd
, int, numvar
, 0);
481 module_param_array(vlan_tag_mode
, int, numvar
, 0);
483 module_param_array(delay_link
, int, numvar
, 0);
484 module_param_array(disable_d3hot
, int, numvar
, 0);
486 #if defined(CONFIG_PCI_MSI) || defined(CONFIG_PCI_USE_VECTOR)
487 module_param_array(disable_msi
, int, numvar
, 0);
496 #define RUN_AT(x) (jiffies + (x))
498 char kernel_version
[] = UTS_RELEASE
;
500 #define PCI_SUPPORT_VER2
502 #if !defined(CAP_NET_ADMIN)
503 #define capable(CAP_XXX) (suser())
506 #define tigon3_debug debug
508 static int tigon3_debug
= TIGON3_DEBUG
;
510 static int tigon3_debug
= 0;
512 static int msglevel
= 0xdeadbeef;
515 int bcm5700_open(struct net_device
*dev
);
516 STATIC
void bcm5700_timer(unsigned long data
);
517 STATIC
void bcm5700_stats_timer(unsigned long data
);
518 STATIC
void bcm5700_reset(struct net_device
*dev
);
519 STATIC
int bcm5700_start_xmit(struct sk_buff
*skb
, struct net_device
*dev
);
520 STATIC irqreturn_t
bcm5700_interrupt(int irq
, void *dev_instance
, struct pt_regs
*regs
);
522 STATIC
void bcm5700_tasklet(unsigned long data
);
524 STATIC
int bcm5700_close(struct net_device
*dev
);
525 STATIC
struct net_device_stats
*bcm5700_get_stats(struct net_device
*dev
);
526 STATIC
int bcm5700_ioctl(struct net_device
*dev
, struct ifreq
*rq
, int cmd
);
527 STATIC
void bcm5700_do_rx_mode(struct net_device
*dev
);
528 STATIC
void bcm5700_set_rx_mode(struct net_device
*dev
);
529 STATIC
int bcm5700_set_mac_addr(struct net_device
*dev
, void *p
);
530 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
531 STATIC
int bcm5700_change_mtu(struct net_device
*dev
, int new_mtu
);
533 #ifdef BCM_NAPI_RXPOLL
534 STATIC
int bcm5700_poll(struct net_device
*dev
, int *budget
);
536 STATIC
int replenish_rx_buffers(PUM_DEVICE_BLOCK pUmDevice
, int max
);
537 STATIC
int bcm5700_freemem(struct net_device
*dev
);
539 #ifndef BCM_NAPI_RXPOLL
540 STATIC
int bcm5700_adapt_coalesce(PUM_DEVICE_BLOCK pUmDevice
);
543 STATIC
void bcm5700_set_vlan_mode(UM_DEVICE_BLOCK
*pUmDevice
);
544 STATIC
int bcm5700_init_counters(PUM_DEVICE_BLOCK pUmDevice
);
546 STATIC
void bcm5700_vlan_rx_register(struct net_device
*dev
, struct vlan_group
*vlgrp
);
547 STATIC
void bcm5700_vlan_rx_kill_vid(struct net_device
*dev
, uint16_t vid
);
549 void bcm5700_shutdown(UM_DEVICE_BLOCK
*pUmDevice
);
550 void bcm5700_free_remaining_rx_bufs(UM_DEVICE_BLOCK
*pUmDevice
);
551 void bcm5700_validate_param_range(UM_DEVICE_BLOCK
*pUmDevice
, int *param
,
552 char *param_name
, int min
, int max
, int deflt
);
554 static int bcm5700_notify_reboot(struct notifier_block
*this, unsigned long event
, void *unused
);
555 static struct notifier_block bcm5700_reboot_notifier
= {
556 bcm5700_notify_reboot
,
561 #if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
562 STATIC
void poll_bcm5700(struct net_device
*dev
);
565 /* A list of all installed bcm5700 devices. */
566 static struct net_device
*root_tigon3_dev
= NULL
;
568 #if defined(CONFIG_SPARC64) || defined(CONFIG_X86_64) ||defined(CONFIG_PPC64)
653 /* indexed by board_t, above */
656 } board_info
[] __devinitdata
= {
657 { "Broadcom BCM5700 1000Base-T" },
658 { "Broadcom BCM5700 1000Base-SX" },
659 { "Broadcom BCM5700 1000Base-SX" },
660 { "Broadcom BCM5700 1000Base-T" },
661 { "Broadcom BCM5700" },
662 { "Broadcom BCM5701 1000Base-T" },
663 { "Broadcom BCM5701 1000Base-T" },
664 { "Broadcom BCM5701 1000Base-T" },
665 { "Broadcom BCM5701 1000Base-SX" },
666 { "Broadcom BCM5701 1000Base-T" },
667 { "Broadcom BCM5701 1000Base-T" },
668 { "Broadcom BCM5701" },
669 { "Broadcom BCM5702 1000Base-T" },
670 { "Broadcom BCM5703 1000Base-T" },
671 { "Broadcom BCM5703 1000Base-SX" },
672 { "Broadcom B5703 1000Base-SX" },
673 { "3Com 3C996 10/100/1000 Server NIC" },
674 { "3Com 3C996 10/100/1000 Server NIC" },
675 { "3Com 3C996 Gigabit Fiber-SX Server NIC" },
676 { "3Com 3C996 Gigabit Fiber-SX Server NIC" },
677 { "3Com 3C996B Gigabit Server NIC" },
678 { "3Com 3C997 Gigabit Server NIC" },
679 { "3Com 3C997 Gigabit Fiber-SX Server NIC" },
680 { "3Com 3C1000 Gigabit NIC" },
681 { "3Com 3C1000B-T 10/100/1000 PCI" },
682 { "3Com 3C940 Gigabit LOM (21X21)" },
683 { "3Com 3C942 Gigabit LOM (31X31)" },
684 { "3Com 3C998-T Dual Port 10/100/1000 PCI-X Server NIC" },
685 { "3Com 3C998-SX Dual Port 1000-SX PCI-X Server NIC" },
686 { "3Com 3C999-T Quad Port 10/100/1000 PCI-X Server NIC" },
687 { "HP NC6770 Gigabit Server Adapter" },
688 { "NC1020 HP ProLiant Gigabit Server Adapter 32 PCI" },
689 { "HP ProLiant NC 150T PCI 4-port Gigabit Combo Switch Adapter" },
690 { "HP NC7760 Gigabit Server Adapter" },
691 { "HP NC7761 Gigabit Server Adapter" },
692 { "HP NC7770 Gigabit Server Adapter" },
693 { "HP NC7771 Gigabit Server Adapter" },
694 { "HP NC7780 Gigabit Server Adapter" },
695 { "HP NC7781 Gigabit Server Adapter" },
696 { "HP NC7772 Gigabit Server Adapter" },
697 { "HP NC7782 Gigabit Server Adapter" },
698 { "HP NC7783 Gigabit Server Adapter" },
699 { "HP ProLiant NC 320T PCI Express Gigabit Server Adapter" },
700 { "HP ProLiant NC 320i PCI Express Gigabit Server Adapter" },
701 { "HP NC325i Integrated Dual Port PCI Express Gigabit Server Adapter" },
702 { "HP NC324i Integrated Dual Port PCI Express Gigabit Server Adapter" },
703 { "HP NC326i Integrated Dual Port PCI Express Gigabit Server Adapter" },
704 { "Broadcom BCM5704 CIOB-E 1000Base-T" },
705 { "Broadcom BCM5704 1000Base-T" },
706 { "Broadcom BCM5704 1000Base-SX" },
707 { "Broadcom BCM5705 1000Base-T" },
708 { "Broadcom BCM5705M 1000Base-T" },
709 { "Broadcom 570x 10/100 Integrated Controller" },
710 { "Broadcom BCM5901 100Base-TX" },
711 { "Broadcom NetXtreme Gigabit Ethernet for hp" },
712 { "Broadcom BCM5788 NetLink 1000Base-T" },
713 { "Broadcom BCM5789 NetLink 1000Base-T PCI Express" },
714 { "Broadcom BCM5750 1000Base-T PCI" },
715 { "Broadcom BCM5750M 1000Base-T PCI" },
716 { "Broadcom BCM5720 1000Base-T PCI" },
717 { "Broadcom BCM5751 1000Base-T PCI Express" },
718 { "Broadcom BCM5751M 1000Base-T PCI Express" },
719 { "Broadcom BCM5751F 100Base-TX PCI Express" },
720 { "Broadcom BCM5721 1000Base-T PCI Express" },
721 { "Broadcom BCM5753 1000Base-T PCI Express" },
722 { "Broadcom BCM5753M 1000Base-T PCI Express" },
723 { "Broadcom BCM5753F 100Base-TX PCI Express" },
724 { "Broadcom BCM5781 NetLink 1000Base-T PCI Express" },
725 { "Broadcom BCM5752 1000Base-T PCI Express" },
726 { "Broadcom BCM5752M 1000Base-T PCI Express" },
727 { "Broadcom BCM5714 1000Base-T " },
728 { "Broadcom BCM5780 1000Base-T" },
729 { "Broadcom BCM5780S 1000Base-SX" },
730 { "Broadcom BCM5715 1000Base-T " },
731 { "Broadcom BCM4785 10/100/1000 Integrated Controller" },
732 { "Broadcom BCM5903M Gigabit Ethernet " },
733 { "Unknown BCM5788 Gigabit Ethernet " },
737 static struct pci_device_id bcm5700_pci_tbl
[] __devinitdata
= {
738 {0x14e4, 0x1644, 0x14e4, 0x1644, 0, 0, BCM5700A6
},
739 {0x14e4, 0x1644, 0x14e4, 0x2, 0, 0, BCM5700T6
},
740 {0x14e4, 0x1644, 0x14e4, 0x3, 0, 0, BCM5700A9
},
741 {0x14e4, 0x1644, 0x14e4, 0x4, 0, 0, BCM5700T9
},
742 {0x14e4, 0x1644, 0x1028, 0xd1, 0, 0, BCM5700
},
743 {0x14e4, 0x1644, 0x1028, 0x0106, 0, 0, BCM5700
},
744 {0x14e4, 0x1644, 0x1028, 0x0109, 0, 0, BCM5700
},
745 {0x14e4, 0x1644, 0x1028, 0x010a, 0, 0, BCM5700
},
746 {0x14e4, 0x1644, 0x10b7, 0x1000, 0, 0, TC996T
},
747 {0x14e4, 0x1644, 0x10b7, 0x1001, 0, 0, TC996ST
},
748 {0x14e4, 0x1644, 0x10b7, 0x1002, 0, 0, TC996SSX
},
749 {0x14e4, 0x1644, 0x10b7, 0x1003, 0, 0, TC997T
},
750 {0x14e4, 0x1644, 0x10b7, 0x1005, 0, 0, TC997SX
},
751 {0x14e4, 0x1644, 0x10b7, 0x1008, 0, 0, TC942BR01
},
752 {0x14e4, 0x1644, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5700
},
753 {0x14e4, 0x1645, 0x14e4, 1, 0, 0, BCM5701A5
},
754 {0x14e4, 0x1645, 0x14e4, 5, 0, 0, BCM5701T1
},
755 {0x14e4, 0x1645, 0x14e4, 6, 0, 0, BCM5701T8
},
756 {0x14e4, 0x1645, 0x14e4, 7, 0, 0, BCM5701A7
},
757 {0x14e4, 0x1645, 0x14e4, 8, 0, 0, BCM5701A10
},
758 {0x14e4, 0x1645, 0x14e4, 0x8008, 0, 0, BCM5701A12
},
759 {0x14e4, 0x1645, 0x0e11, 0xc1, 0, 0, NC6770
},
760 {0x14e4, 0x1645, 0x0e11, 0x7c, 0, 0, NC7770
},
761 {0x14e4, 0x1645, 0x0e11, 0x85, 0, 0, NC7780
},
762 {0x14e4, 0x1645, 0x1028, 0x0121, 0, 0, BCM5701
},
763 {0x14e4, 0x1645, 0x10b7, 0x1004, 0, 0, TC996SX
},
764 {0x14e4, 0x1645, 0x10b7, 0x1006, 0, 0, TC996BT
},
765 {0x14e4, 0x1645, 0x10b7, 0x1007, 0, 0, TC1000T
},
766 {0x14e4, 0x1645, 0x10b7, 0x1008, 0, 0, TC940BR01
},
767 {0x14e4, 0x1645, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5701
},
768 {0x14e4, 0x1646, 0x14e4, 0x8009, 0, 0, BCM5702
},
769 {0x14e4, 0x1646, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5702
},
770 {0x14e4, 0x16a6, 0x14e4, 0x8009, 0, 0, BCM5702
},
771 {0x14e4, 0x16a6, 0x14e4, 0x000c, 0, 0, BCM5702
},
772 {0x14e4, 0x16a6, 0x0e11, 0xbb, 0, 0, NC7760
},
773 {0x14e4, 0x16a6, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5702
},
774 {0x14e4, 0x16c6, 0x10b7, 0x1100, 0, 0, TC1000BT
},
775 {0x14e4, 0x16c6, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5702
},
776 {0x14e4, 0x1647, 0x14e4, 0x0009, 0, 0, BCM5703
},
777 {0x14e4, 0x1647, 0x14e4, 0x000a, 0, 0, BCM5703A31
},
778 {0x14e4, 0x1647, 0x14e4, 0x000b, 0, 0, BCM5703
},
779 {0x14e4, 0x1647, 0x14e4, 0x800a, 0, 0, BCM5703
},
780 {0x14e4, 0x1647, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5703
},
781 {0x14e4, 0x16a7, 0x14e4, 0x0009, 0, 0, BCM5703
},
782 {0x14e4, 0x16a7, 0x14e4, 0x000a, 0, 0, BCM5703A31
},
783 {0x14e4, 0x16a7, 0x14e4, 0x000b, 0, 0, BCM5703
},
784 {0x14e4, 0x16a7, 0x14e4, 0x800a, 0, 0, BCM5703
},
785 {0x14e4, 0x16a7, 0x0e11, 0xca, 0, 0, NC7771
},
786 {0x14e4, 0x16a7, 0x0e11, 0xcb, 0, 0, NC7781
},
787 {0x14e4, 0x16a7, 0x1014, 0x0281, 0, 0, BCM5703ARBUCKLE
},
788 {0x14e4, 0x16a7, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5703
},
789 {0x14e4, 0x16c7, 0x14e4, 0x000a, 0, 0, BCM5703A31
},
790 {0x14e4, 0x16c7, 0x0e11, 0xca, 0, 0, NC7771
},
791 {0x14e4, 0x16c7, 0x0e11, 0xcb, 0, 0, NC7781
},
792 {0x14e4, 0x16c7, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5703
},
793 {0x14e4, 0x1648, 0x0e11, 0xcf, 0, 0, NC7772
},
794 {0x14e4, 0x1648, 0x0e11, 0xd0, 0, 0, NC7782
},
795 {0x14e4, 0x1648, 0x0e11, 0xd1, 0, 0, NC7783
},
796 {0x14e4, 0x1648, 0x10b7, 0x2000, 0, 0, TC998T
},
797 {0x14e4, 0x1648, 0x10b7, 0x3000, 0, 0, TC999T
},
798 {0x14e4, 0x1648, 0x1166, 0x1648, 0, 0, BCM5704CIOBE
},
799 {0x14e4, 0x1648, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5704
},
800 {0x14e4, 0x1649, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5704S
},
801 {0x14e4, 0x16a8, 0x14e4, 0x16a8, 0, 0, BCM5704S
},
802 {0x14e4, 0x16a8, 0x10b7, 0x2001, 0, 0, TC998SX
},
803 {0x14e4, 0x16a8, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5704S
},
804 {0x14e4, 0x1653, 0x0e11, 0x00e3, 0, 0, NC7761
},
805 {0x14e4, 0x1653, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5705
},
806 {0x14e4, 0x1654, 0x0e11, 0x00e3, 0, 0, NC7761
},
807 {0x14e4, 0x1654, 0x103c, 0x3100, 0, 0, NC1020
},
808 {0x14e4, 0x1654, 0x103c, 0x3226, 0, 0, NC150T
},
809 {0x14e4, 0x1654, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5705
},
810 {0x14e4, 0x165d, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5705M
},
811 {0x14e4, 0x165e, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5705M
},
812 {0x14e4, 0x166e, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5705F
},
813 {0x14e4, 0x1696, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5782
},
814 {0x14e4, 0x169c, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5788
},
815 {0x14e4, 0x169d, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5789
},
816 {0x14e4, 0x170d, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5901
},
817 {0x14e4, 0x170e, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5901
},
818 {0x14e4, 0x1676, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5750
},
819 {0x14e4, 0x167c, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5750M
},
820 {0x14e4, 0x1677, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5751
},
821 {0x14e4, 0x167d, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5751M
},
822 {0x14e4, 0x167e, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5751F
},
823 {0x14e4, 0x1658, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5720
},
824 {0x14e4, 0x1659, 0x103c, 0x7031, 0, 0, NC320T
},
825 {0x14e4, 0x1659, 0x103c, 0x7032, 0, 0, NC320T
},
826 {0x14e4, 0x166a, 0x103c, 0x7035, 0, 0, NC325I
},
827 {0x14e4, 0x166b, 0x103c, 0x7036, 0, 0, NC325I
},
828 {0x14e4, 0x1668, 0x103c, 0x7039, 0, 0, NC324I
},
829 {0x14e4, 0x1669, 0x103c, 0x703a, 0, 0, NC324I
},
830 {0x14e4, 0x1678, 0x103c, 0x703e, 0, 0, NC326I
},
831 {0x14e4, 0x1679, 0x103c, 0x703c, 0, 0, NC326I
},
832 {0x14e4, 0x1659, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5721
},
833 {0x14e4, 0x16f7, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5753
},
834 {0x14e4, 0x16fd, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5753M
},
835 {0x14e4, 0x16fe, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5753F
},
836 {0x14e4, 0x16dd, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5781
},
837 {0x14e4, 0x1600, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5752
},
838 {0x14e4, 0x1601, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5752M
},
839 {0x14e4, 0x1668, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5714
},
840 {0x14e4, 0x166a, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5780
},
841 {0x14e4, 0x166b, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5780S
},
842 {0x14e4, 0x1678, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5715
},
843 {0x14e4, 0x471f, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM4785
},
844 {0x14e4, 0x16ff, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, BCM5903M
},
845 {0x173b, 0x03ed, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, UNK5788
},
849 MODULE_DEVICE_TABLE(pci
, bcm5700_pci_tbl
);
851 #if (LINUX_VERSION_CODE >= 0x2060a)
852 static struct pci_device_id pci_AMD762id
[]={
853 { PCI_DEVICE(PCI_VENDOR_ID_AMD
,
854 PCI_DEVICE_ID_AMD_FE_GATE_700C
) },
859 static int sbgige
= -1;
861 /*******************************************************************************
862 *******************************************************************************
865 int get_csum_flag(LM_UINT32 ChipRevId
)
867 return NETIF_F_IP_CSUM
;
870 /*******************************************************************************
871 *******************************************************************************
873 This function returns true if the device passed to it is attached to an
874 ICH-ICH4. If the chip is not attached to an ICH, or is attached to an ICH5
875 or newer, it returns false.
877 This function determines which bridge it is attached to by scaning the pci
878 bus looking for bridge chips (hdr_type=1). When a bridge chip is detected,
879 the bridge's subordinate's secondary bus number is compared with this
880 devices bus number. If they match, then the device is attached to this
881 bridge. The bridge's device id is compared to a list of known device ids for
882 ICH-ICH4. Since many older ICH's (ICH2-ICH7) share the same device id, the
883 chip revision must also be checked to determine if the chip is older than an
886 To scan the bus, one of two functions is used depending on the kernel
887 version. For 2.4 kernels, the pci_find_device function is used. This
888 function has been depricated in the 2.6 kernel and replaced with the
889 fucntion pci_get_device. The macro walk_pci_bus determines which function to
890 use when the driver is built.
893 #if (LINUX_VERSION_CODE >= 0x2060a)
894 #define walk_pci_bus(d) while ((d = pci_get_device( \
895 PCI_ANY_ID, PCI_ANY_ID, d)) != NULL)
897 #define unwalk_pci_bus(d) pci_dev_put(d)
900 #define walk_pci_bus(d) while ((d = pci_find_device( \
901 PCI_ANY_ID, PCI_ANY_ID, d)) != NULL)
902 #define unwalk_pci_bus(d)
906 #define ICH5_CHIP_VERSION 0xc0
908 static struct pci_device_id pci_ICHtable
[] = {
909 {0x8086, 0x2418}, /* PCI_DEVICE_ID_INTEL_82801AA_8 */
910 {0x8086, 0x2428}, /* PCI_DEVICE_ID_INTEL_82801AB_8 */
911 {0x8086, 0x244e}, /* PCI_DEVICE_ID_INTEL_82801BA_6 */
912 {0x8086, 0x2448}, /* PCI_DEVICE_ID_INTEL_82801BA_11 */
916 int attached_to_ICH4_or_older( struct pci_dev
*pdev
)
918 struct pci_dev
*tmp_pdev
= NULL
;
919 struct pci_device_id
*ich_table
;
922 walk_pci_bus (tmp_pdev
) {
923 if ((tmp_pdev
->hdr_type
== 1) &&
924 (tmp_pdev
->subordinate
!= NULL
) &&
925 (tmp_pdev
->subordinate
->secondary
== pdev
->bus
->number
)) {
927 ich_table
= pci_ICHtable
;
929 while (ich_table
->vendor
) {
930 if ((ich_table
->vendor
== tmp_pdev
->vendor
) &&
931 (ich_table
->device
== tmp_pdev
->device
)) {
933 pci_read_config_byte( tmp_pdev
,
934 PCI_REVISION_ID
, &chip_rev
);
936 if (chip_rev
< ICH5_CHIP_VERSION
) {
937 unwalk_pci_bus( tmp_pdev
);
948 static void robo_set_power_mode(void *h
)
954 uint32 flags
= 0, temp32
= 0,val32
= 0, savephyaddr
= 0;
955 PUM_DEVICE_BLOCK pudev
= (PUM_DEVICE_BLOCK
)h
;
956 PLM_DEVICE_BLOCK pdev
= &pudev
->lm_dev
;
958 /*Brcm,Alex,2006.7.20. Adding Phy power mode setting*/
959 BCM5700_PHY_LOCK(pudev
, flags
);
960 savephyaddr
= pdev
->PhyAddr
;
962 for(i
= 0; i
< 8; i
++)
966 LM_WritePhy(pdev
, 0x18, temp32
);
967 LM_ReadPhy(pdev
, 0x18, &val32
);
968 // printk(KERN_DEBUG "Alex: port = %x, read value =%x\n",i, val32);
970 LM_WritePhy(pdev
, 0x18, temp32
);
974 LM_WritePhy(pdev
, 0x18, temp32
);
975 LM_ReadPhy(pdev
, 0x18, &val32
);
976 // printk(KERN_ERR "Alex: read back value =%x\n",val32);
979 pdev
->PhyAddr
= savephyaddr
;
980 BCM5700_PHY_UNLOCK(pudev
, flags
);
982 /*end of Brcm,Alex,2006.7.20. Adding Phy power mode setting*/
987 __devinit
bcm5700_init_board(struct pci_dev
*pdev
, struct net_device
**dev_out
, int board_idx
)
989 struct net_device
*dev
;
990 PUM_DEVICE_BLOCK pUmDevice
;
991 PLM_DEVICE_BLOCK pDevice
;
998 /* dev zeroed in init_etherdev */
999 #if (LINUX_VERSION_CODE >= 0x20600)
1000 dev
= alloc_etherdev(sizeof(*pUmDevice
));
1002 dev
= init_etherdev(NULL
, sizeof(*pUmDevice
));
1005 printk(KERN_ERR
"%s: unable to alloc new ethernet\n", bcm5700_driver
);
1008 SET_MODULE_OWNER(dev
);
1009 #if (LINUX_VERSION_CODE >= 0x20600)
1010 SET_NETDEV_DEV(dev
, &pdev
->dev
);
1012 pUmDevice
= (PUM_DEVICE_BLOCK
) dev
->priv
;
1014 /* enable device (incl. PCI PM wakeup), and bus-mastering */
1015 rc
= pci_enable_device(pdev
);
1019 /* init core specific stuff */
1020 if (pdev
->device
== T3_PCI_DEVICE_ID(T3_PCI_ID_BCM471F
)) {
1021 sbh
= sb_kattach(SB_OSH
);
1022 sb_gige_init(sbh
, ++sbgige
, &rgmii
);
1025 rc
= pci_request_regions(pdev
, bcm5700_driver
);
1029 printk(KERN_INFO
"bcm5700_init_board: pci_request_regions returned error %d\n"
1030 "This may be because the region is already requested by"
1031 " the SMBus driver. Ignore the PCI error messages.\n", rc
);
1034 pci_set_master(pdev
);
1036 if (pci_set_dma_mask(pdev
, BCM_64BIT_DMA_MASK
) == 0) {
1037 pUmDevice
->using_dac
= 1;
1038 if (pci_set_consistent_dma_mask(pdev
, BCM_64BIT_DMA_MASK
) != 0) {
1039 printk(KERN_ERR
"pci_set_consistent_dma_mask failed\n");
1040 pci_release_regions(pdev
);
1043 } else if (pci_set_dma_mask(pdev
, BCM_32BIT_DMA_MASK
) == 0) {
1044 pUmDevice
->using_dac
= 0;
1046 printk(KERN_ERR
"System does not support DMA\n");
1047 pci_release_regions(pdev
);
1051 pUmDevice
->dev
= dev
;
1052 pUmDevice
->pdev
= pdev
;
1053 pUmDevice
->mem_list_num
= 0;
1054 pUmDevice
->next_module
= root_tigon3_dev
;
1055 pUmDevice
->index
= board_idx
;
1056 pUmDevice
->sbh
= (void *)sbh
;
1057 root_tigon3_dev
= dev
;
1059 spin_lock_init(&pUmDevice
->global_lock
);
1061 spin_lock_init(&pUmDevice
->undi_lock
);
1063 spin_lock_init(&pUmDevice
->phy_lock
);
1065 pDevice
= &pUmDevice
->lm_dev
;
1067 pDevice
->FunctNum
= PCI_FUNC(pUmDevice
->pdev
->devfn
);
1068 pUmDevice
->boardflags
= getintvar(NULL
, "boardflags");
1070 if (pUmDevice
->boardflags
& BFL_ENETROBO
)
1071 pDevice
->Flags
|= ROBO_SWITCH_FLAG
;
1072 pDevice
->Flags
|= rgmii
? RGMII_MODE_FLAG
: 0;
1073 if (sb_chip(sbh
) == BCM4785_CHIP_ID
&& sb_chiprev(sbh
) < 2)
1074 pDevice
->Flags
|= ONE_DMA_AT_ONCE_FLAG
;
1075 pDevice
->Flags
|= SB_CORE_FLAG
;
1076 if (sb_chip(sbh
) == BCM4785_CHIP_ID
)
1077 pDevice
->Flags
|= FLUSH_POSTED_WRITE_FLAG
;
1080 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1081 if (board_idx
< MAX_UNITS
) {
1082 bcm5700_validate_param_range(pUmDevice
, &mtu
[board_idx
], "mtu", 1500, 9000, 1500);
1083 dev
->mtu
= mtu
[board_idx
];
1087 if (attached_to_ICH4_or_older(pdev
)) {
1088 pDevice
->Flags
|= UNDI_FIX_FLAG
;
1091 #if (LINUX_VERSION_CODE >= 0x2060a)
1092 if (pci_dev_present(pci_AMD762id
)) {
1093 pDevice
->Flags
|= FLUSH_POSTED_WRITE_FLAG
;
1094 pDevice
->Flags
&= ~NIC_SEND_BD_FLAG
;
1097 if (pci_find_device(0x1022, 0x700c, NULL
)) {
1098 /* AMD762 writes I/O out of order */
1099 /* Setting bit 1 in 762's register 0x4C still doesn't work */
1101 pDevice
->Flags
|= FLUSH_POSTED_WRITE_FLAG
;
1102 pDevice
->Flags
&= ~NIC_SEND_BD_FLAG
;
1105 if (LM_GetAdapterInfo(pDevice
) != LM_STATUS_SUCCESS
) {
1110 if (pDevice
->Flags
& ROBO_SWITCH_FLAG
) {
1113 if ((robo
= bcm_robo_attach(sbh
, pDevice
, dev
->name
, NULL
,
1114 robo_miird
, robo_miiwr
)) == NULL
) {
1115 B57_ERR(("robo_setup: failed to attach robo switch \n"));
1119 if (bcm_robo_enable_device(robo
)) {
1120 B57_ERR(("robo_setup: failed to enable robo switch \n"));
1122 bcm_robo_detach(robo
);
1127 /* 5397 power mode setting */
1128 robo_set_power_mode(robo
->h
);
1130 pUmDevice
->robo
= (void *)robo
;
1133 if ((pDevice
->Flags
& JUMBO_CAPABLE_FLAG
) == 0) {
1134 if (dev
->mtu
> 1500) {
1137 "%s-%d: Jumbo mtu sizes not supported, using mtu=1500\n",
1138 bcm5700_driver
, pUmDevice
->index
);
1142 pUmDevice
->do_global_lock
= 0;
1143 if (T3_ASIC_REV(pUmDevice
->lm_dev
.ChipRevId
) == T3_ASIC_REV_5700
) {
1144 /* The 5700 chip works best without interleaved register */
1145 /* accesses on certain machines. */
1146 pUmDevice
->do_global_lock
= 1;
1149 if ((T3_ASIC_REV(pUmDevice
->lm_dev
.ChipRevId
) == T3_ASIC_REV_5701
) &&
1150 ((pDevice
->PciState
& T3_PCI_STATE_NOT_PCI_X_BUS
) == 0)) {
1152 pUmDevice
->rx_buf_align
= 0;
1154 pUmDevice
->rx_buf_align
= 2;
1156 dev
->mem_start
= pci_resource_start(pdev
, 0);
1157 dev
->mem_end
= dev
->mem_start
+ sizeof(T3_STD_MEM_MAP
);
1158 dev
->irq
= pdev
->irq
;
1164 pci_release_regions(pdev
);
1165 bcm5700_freemem(dev
);
1168 #if (LINUX_VERSION_CODE < 0x020600)
1169 unregister_netdev(dev
);
1177 static int __devinit
1178 bcm5700_print_ver(void)
1180 printk(KERN_INFO
"Broadcom Gigabit Ethernet Driver %s ",
1182 printk("ver. %s %s\n", bcm5700_version
, bcm5700_date
);
1186 static int __devinit
1187 bcm5700_init_one(struct pci_dev
*pdev
, const struct pci_device_id
*ent
)
1189 struct net_device
*dev
= NULL
;
1190 PUM_DEVICE_BLOCK pUmDevice
;
1191 PLM_DEVICE_BLOCK pDevice
;
1193 static int board_idx
= -1;
1194 static int printed_version
= 0;
1195 struct pci_dev
*pci_dev
;
1199 if (!printed_version
) {
1200 bcm5700_print_ver();
1201 printed_version
= 1;
1204 i
= bcm5700_init_board(pdev
, &dev
, board_idx
);
1213 if (atomic_read(&bcm5700_load_count
) == 0) {
1214 register_ioctl32_conversion(SIOCNICE
, bcm5700_ioctl32
);
1216 atomic_inc(&bcm5700_load_count
);
1218 dev
->open
= bcm5700_open
;
1219 dev
->hard_start_xmit
= bcm5700_start_xmit
;
1220 dev
->stop
= bcm5700_close
;
1221 dev
->get_stats
= bcm5700_get_stats
;
1222 dev
->set_multicast_list
= bcm5700_set_rx_mode
;
1223 dev
->do_ioctl
= bcm5700_ioctl
;
1224 dev
->set_mac_address
= &bcm5700_set_mac_addr
;
1225 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1226 dev
->change_mtu
= &bcm5700_change_mtu
;
1228 #if (LINUX_VERSION_CODE >= 0x20400)
1229 dev
->tx_timeout
= bcm5700_reset
;
1230 dev
->watchdog_timeo
= TX_TIMEOUT
;
1233 dev
->vlan_rx_register
= &bcm5700_vlan_rx_register
;
1234 dev
->vlan_rx_kill_vid
= &bcm5700_vlan_rx_kill_vid
;
1236 #ifdef BCM_NAPI_RXPOLL
1237 dev
->poll
= bcm5700_poll
;
1241 pUmDevice
= (PUM_DEVICE_BLOCK
) dev
->priv
;
1242 pDevice
= (PLM_DEVICE_BLOCK
) pUmDevice
;
1244 dev
->base_addr
= pci_resource_start(pdev
, 0);
1245 dev
->irq
= pdev
->irq
;
1246 #if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
1247 dev
->poll_controller
= poll_bcm5700
;
1250 #if (LINUX_VERSION_CODE >= 0x20600)
1251 if ((i
= register_netdev(dev
))) {
1252 printk(KERN_ERR
"%s: Cannot register net device\n",
1254 if (pUmDevice
->lm_dev
.pMappedMemBase
)
1255 iounmap(pUmDevice
->lm_dev
.pMappedMemBase
);
1256 pci_release_regions(pdev
);
1257 bcm5700_freemem(dev
);
1264 pci_set_drvdata(pdev
, dev
);
1266 memcpy(dev
->dev_addr
, pDevice
->NodeAddress
, 6);
1267 pUmDevice
->name
= board_info
[ent
->driver_data
].name
,
1268 printk(KERN_INFO
"%s: %s found at mem %lx, IRQ %d, ",
1269 dev
->name
, pUmDevice
->name
, dev
->base_addr
,
1271 printk("node addr ");
1272 for (i
= 0; i
< 6; i
++) {
1273 printk("%2.2x", dev
->dev_addr
[i
]);
1277 printk(KERN_INFO
"%s: ", dev
->name
);
1278 if ((pDevice
->PhyId
& PHY_ID_MASK
) == PHY_BCM5400_PHY_ID
)
1279 printk("Broadcom BCM5400 Copper ");
1280 else if ((pDevice
->PhyId
& PHY_ID_MASK
) == PHY_BCM5401_PHY_ID
)
1281 printk("Broadcom BCM5401 Copper ");
1282 else if ((pDevice
->PhyId
& PHY_ID_MASK
) == PHY_BCM5411_PHY_ID
)
1283 printk("Broadcom BCM5411 Copper ");
1284 else if ((pDevice
->PhyId
& PHY_ID_MASK
) == PHY_BCM5461_PHY_ID
)
1285 printk("Broadcom BCM5461 Copper ");
1286 else if (((pDevice
->PhyId
& PHY_ID_MASK
) == PHY_BCM5701_PHY_ID
) &&
1287 !(pDevice
->TbiFlags
& ENABLE_TBI_FLAG
)) {
1288 printk("Broadcom BCM5701 Integrated Copper ");
1290 else if ((pDevice
->PhyId
& PHY_ID_MASK
) == PHY_BCM5703_PHY_ID
) {
1291 printk("Broadcom BCM5703 Integrated ");
1292 if (pDevice
->TbiFlags
& ENABLE_TBI_FLAG
)
1297 else if ((pDevice
->PhyId
& PHY_ID_MASK
) == PHY_BCM5704_PHY_ID
) {
1298 printk("Broadcom BCM5704 Integrated ");
1299 if (pDevice
->TbiFlags
& ENABLE_TBI_FLAG
)
1304 else if (pDevice
->PhyFlags
& PHY_IS_FIBER
){
1305 if(( pDevice
->PhyId
& PHY_ID_MASK
) == PHY_BCM5780_PHY_ID
)
1306 printk("Broadcom BCM5780S Integrated Serdes ");
1309 else if ((pDevice
->PhyId
& PHY_ID_MASK
) == PHY_BCM5705_PHY_ID
)
1310 printk("Broadcom BCM5705 Integrated Copper ");
1311 else if ((pDevice
->PhyId
& PHY_ID_MASK
) == PHY_BCM5750_PHY_ID
)
1312 printk("Broadcom BCM5750 Integrated Copper ");
1314 else if ((pDevice
->PhyId
& PHY_ID_MASK
) == PHY_BCM5714_PHY_ID
)
1315 printk("Broadcom BCM5714 Integrated Copper ");
1316 else if ((pDevice
->PhyId
& PHY_ID_MASK
) == PHY_BCM5780_PHY_ID
)
1317 printk("Broadcom BCM5780 Integrated Copper ");
1319 else if ((pDevice
->PhyId
& PHY_ID_MASK
) == PHY_BCM5752_PHY_ID
)
1320 printk("Broadcom BCM5752 Integrated Copper ");
1321 else if ((pDevice
->PhyId
& PHY_ID_MASK
) == PHY_BCM8002_PHY_ID
)
1322 printk("Broadcom BCM8002 SerDes ");
1323 else if (pDevice
->TbiFlags
& ENABLE_TBI_FLAG
) {
1324 if (T3_ASIC_REV(pDevice
->ChipRevId
) == T3_ASIC_REV_5703
) {
1325 printk("Broadcom BCM5703 Integrated SerDes ");
1327 else if (T3_ASIC_REV(pDevice
->ChipRevId
) == T3_ASIC_REV_5704
) {
1328 printk("Broadcom BCM5704 Integrated SerDes ");
1331 printk("Agilent HDMP-1636 SerDes ");
1337 printk("transceiver found\n");
1339 #if (LINUX_VERSION_CODE >= 0x20400)
1340 if (scatter_gather
[board_idx
]) {
1341 dev
->features
|= NETIF_F_SG
;
1342 if (pUmDevice
->using_dac
&& !(pDevice
->Flags
& BCM5788_FLAG
))
1343 dev
->features
|= NETIF_F_HIGHDMA
;
1345 if ((pDevice
->TaskOffloadCap
& LM_TASK_OFFLOAD_TX_TCP_CHECKSUM
) &&
1346 tx_checksum
[board_idx
]) {
1348 dev
->features
|= get_csum_flag( pDevice
->ChipRevId
);
1351 dev
->features
|= NETIF_F_HW_VLAN_TX
| NETIF_F_HW_VLAN_RX
;
1354 /* On 5714/15/80 chips, Jumbo Frames and TSO cannot both be enabled at
1355 the same time. Since only one of these features can be enable at a
1356 time, we'll enable only Jumbo Frames and disable TSO when the user
1357 tries to enable both.
1359 dev
->features
&= ~NETIF_F_TSO
;
1361 if ((pDevice
->TaskToOffload
& LM_TASK_OFFLOAD_TCP_SEGMENTATION
) &&
1362 (enable_tso
[board_idx
])) {
1363 if (T3_ASIC_5714_FAMILY(pDevice
->ChipRevId
) &&
1364 (dev
->mtu
> 1500)) {
1365 printk(KERN_ALERT
"%s: Jumbo Frames and TSO cannot simultaneously be enabled. Jumbo Frames enabled. TSO disabled.\n", dev
->name
);
1367 dev
->features
|= NETIF_F_TSO
;
1371 printk(KERN_INFO
"%s: Scatter-gather %s, 64-bit DMA %s, Tx Checksum %s, ",
1373 (char *) ((dev
->features
& NETIF_F_SG
) ? "ON" : "OFF"),
1374 (char *) ((dev
->features
& NETIF_F_HIGHDMA
) ? "ON" : "OFF"),
1375 (char *) ((dev
->features
& get_csum_flag( pDevice
->ChipRevId
)) ? "ON" : "OFF"));
1377 if ((pDevice
->ChipRevId
!= T3_CHIP_ID_5700_B0
) &&
1378 rx_checksum
[board_idx
])
1379 printk("Rx Checksum ON");
1381 printk("Rx Checksum OFF");
1383 printk(", 802.1Q VLAN ON");
1386 if (dev
->features
& NETIF_F_TSO
) {
1391 #ifdef BCM_NAPI_RXPOLL
1392 printk(", NAPI ON");
1396 register_reboot_notifier(&bcm5700_reboot_notifier
);
1398 tasklet_init(&pUmDevice
->tasklet
, bcm5700_tasklet
,
1399 (unsigned long) pUmDevice
);
1401 if (T3_ASIC_REV(pDevice
->ChipRevId
) == T3_ASIC_REV_5704
) {
1402 if ((REG_RD(pDevice
, PciCfg
.DualMacCtrl
) &
1403 T3_DUAL_MAC_CH_CTRL_MASK
) == 3) {
1405 printk(KERN_WARNING
"%s: Device is configured for Hardware Based Teaming which is not supported with this operating system. Please consult the user diagnostic guide to disable Turbo Teaming.\n", dev
->name
);
1409 #if (LINUX_VERSION_CODE > 0x20605)
1411 if ((pci_dev
= pci_get_device(0x1022, 0x700c, NULL
)))
1413 if ((pci_dev
= pci_find_device(0x1022, 0x700c, NULL
)))
1418 /* Found AMD 762 North bridge */
1419 pci_read_config_dword(pci_dev
, 0x4c, &val
);
1420 if ((val
& 0x02) == 0) {
1421 pci_write_config_dword(pci_dev
, 0x4c, val
| 0x02);
1422 printk(KERN_INFO
"%s: Setting AMD762 Northbridge to enable PCI ordering compliance\n", bcm5700_driver
);
1426 #if (LINUX_VERSION_CODE > 0x20605)
1428 pci_dev_put(pci_dev
);
1430 #if defined(CONFIG_PCI_MSI) || defined(CONFIG_PCI_USE_VECTOR)
1432 if ((pci_dev
= pci_get_device(0x1066, 0x0017, NULL
))) {
1433 bcm_msi_chipset_bug
= 1;
1435 pci_dev_put(pci_dev
);
1443 static void __devexit
1444 bcm5700_remove_one (struct pci_dev
*pdev
)
1446 struct net_device
*dev
= pci_get_drvdata (pdev
);
1447 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)dev
->priv
;
1450 atomic_dec(&bcm5700_load_count
);
1451 if (atomic_read(&bcm5700_load_count
) == 0)
1452 unregister_ioctl32_conversion(SIOCNICE
);
1454 unregister_netdev(dev
);
1456 if (pUmDevice
->lm_dev
.pMappedMemBase
)
1457 iounmap(pUmDevice
->lm_dev
.pMappedMemBase
);
1459 pci_release_regions(pdev
);
1461 #if (LINUX_VERSION_CODE < 0x020600)
1467 pci_set_drvdata(pdev
, NULL
);
1471 int b57_test_intr(UM_DEVICE_BLOCK
*pUmDevice
);
1473 #ifdef BCM_WL_EMULATOR
1474 /* new transmit callback */
1475 static int bcm5700emu_start_xmit(struct sk_buff
*skb
, struct net_device
*dev
);
1476 /* keep track of the 2 gige devices */
1477 static PLM_DEVICE_BLOCK pDev1
;
1478 static PLM_DEVICE_BLOCK pDev2
;
1481 bcm5700emu_open(struct net_device
*dev
)
1483 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)dev
->priv
;
1484 PLM_DEVICE_BLOCK pDevice
= (PLM_DEVICE_BLOCK
) pUmDevice
;
1485 static int instance
= 0;
1486 static char *wlemu_if
= NULL
;
1487 char *wlemu_mode
= NULL
;
1488 //int wlemu_idx = 0;
1489 static int rx_enable
= 0;
1490 static int tx_enable
= 0;
1492 /* which interface is the emulator ? */
1494 wlemu_if
= nvram_get("wlemu_if");
1495 /* do we emulate rx, tx or both */
1496 wlemu_mode
= nvram_get("wlemu_mode");
1498 if (!strcmp(wlemu_mode
,"rx"))
1502 else if (!strcmp(wlemu_mode
,"tx"))
1508 else if (!strcmp(wlemu_mode
,"rx_tx"))
1519 /* The context is used for accessing the OSL for emulating devices */
1520 pDevice
->wlc
= NULL
;
1522 /* determines if this device is an emulator */
1523 pDevice
->wl_emulate_rx
= 0;
1524 pDevice
->wl_emulate_tx
= 0;
1526 if(wlemu_if
&& !strcmp(dev
->name
,wlemu_if
))
1528 /* create an emulator context. */
1529 pDevice
->wlc
= (void *)wlcemu_wlccreate((void *)dev
);
1530 B57_INFO(("Using %s for wl emulation \n", dev
->name
));
1533 B57_INFO(("Enabling wl RX emulation \n"));
1534 pDevice
->wl_emulate_rx
= 1;
1536 /* re-direct transmit callback to emulator */
1539 pDevice
->wl_emulate_tx
= 1;
1540 dev
->hard_start_xmit
= bcm5700emu_start_xmit
;
1541 B57_INFO(("Enabling wl TX emulation \n"));
1544 /* for debug access to configured devices only */
1547 else if (instance
== 2)
1551 /* Public API to get current emulation info */
1552 int bcm5700emu_get_info(char *buf
)
1557 /* look for an emulating device */
1560 len
+= sprintf(buf
+len
,"emulation device : eth0\n");
1562 else if (pDev2
->wlc
) {
1564 len
+= sprintf(buf
+len
,"emulation device : eth1\n");
1567 len
+= sprintf(buf
+len
,"emulation not activated\n");
1570 if(p
->wl_emulate_rx
)
1571 len
+= sprintf(buf
+len
,"RX emulation enabled\n");
1573 len
+= sprintf(buf
+len
,"RX emulation disabled\n");
1574 if(p
->wl_emulate_tx
)
1575 len
+= sprintf(buf
+len
,"TX emulation enabled\n");
1577 len
+= sprintf(buf
+len
,"TX emulation disabled\n");
1583 /* Public API to access the bcm5700_start_xmit callback */
1586 bcm5700emu_forward_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
1588 return bcm5700_start_xmit(skb
, dev
);
1592 /* hook to kernel txmit callback */
1594 bcm5700emu_start_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
1597 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)dev
->priv
;
1598 PLM_DEVICE_BLOCK pDevice
= (PLM_DEVICE_BLOCK
) pUmDevice
;
1599 return wlcemu_start_xmit(skb
,pDevice
->wlc
);
1602 #endif /* BCM_WL_EMULATOR */
1605 bcm5700_open(struct net_device
*dev
)
1607 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)dev
->priv
;
1608 PLM_DEVICE_BLOCK pDevice
= (PLM_DEVICE_BLOCK
) pUmDevice
;
1611 if (pUmDevice
->suspended
){
1615 #ifdef BCM_WL_EMULATOR
1616 bcm5700emu_open(dev
);
1619 /* delay for 6 seconds */
1620 pUmDevice
->delayed_link_ind
= (6 * HZ
) / pUmDevice
->timer_interval
;
1623 #ifndef BCM_NAPI_RXPOLL
1624 pUmDevice
->adaptive_expiry
= HZ
/ pUmDevice
->timer_interval
;
1628 #ifdef INCLUDE_TBI_SUPPORT
1629 if ((pDevice
->TbiFlags
& ENABLE_TBI_FLAG
) &&
1630 (pDevice
->TbiFlags
& TBI_POLLING_FLAGS
)) {
1631 pUmDevice
->poll_tbi_interval
= HZ
/ pUmDevice
->timer_interval
;
1632 if (T3_ASIC_REV(pDevice
->ChipRevId
) == T3_ASIC_REV_5703
) {
1633 pUmDevice
->poll_tbi_interval
/= 4;
1635 pUmDevice
->poll_tbi_expiry
= pUmDevice
->poll_tbi_interval
;
1638 /* set this timer for 2 seconds */
1639 pUmDevice
->asf_heartbeat
= (2 * HZ
) / pUmDevice
->timer_interval
;
1641 #if defined(CONFIG_PCI_MSI) || defined(CONFIG_PCI_USE_VECTOR)
1644 if ( ( (T3_ASIC_IS_575X_PLUS(pDevice
->ChipRevId
) ) &&
1645 (T3_ASIC_REV(pDevice
->ChipRevId
) != T3_ASIC_REV_5714_A0
) &&
1646 (T3_CHIP_REV(pDevice
->ChipRevId
) != T3_CHIP_REV_5750_AX
) &&
1647 (T3_CHIP_REV(pDevice
->ChipRevId
) != T3_CHIP_REV_5750_BX
) ) &&
1648 !bcm_msi_chipset_bug
){
1650 if (disable_msi
[pUmDevice
->index
]==1){
1651 /* do nothing-it's not turned on */
1653 pDevice
->Flags
|= USING_MSI_FLAG
;
1655 REG_WR(pDevice
, Msi
.Mode
, 2 );
1657 rc
= pci_enable_msi(pUmDevice
->pdev
);
1660 pDevice
->Flags
&= ~ USING_MSI_FLAG
;
1661 REG_WR(pDevice
, Msi
.Mode
, 1 );
1669 if ((rc
= request_irq(pUmDevice
->pdev
->irq
, &bcm5700_interrupt
, SA_SHIRQ
, dev
->name
, dev
)))
1672 #if defined(CONFIG_PCI_MSI) || defined(CONFIG_PCI_USE_VECTOR)
1674 if(pDevice
->Flags
& USING_MSI_FLAG
) {
1676 pci_disable_msi(pUmDevice
->pdev
);
1677 pDevice
->Flags
&= ~USING_MSI_FLAG
;
1678 REG_WR(pDevice
, Msi
.Mode
, 1 );
1685 pUmDevice
->opened
= 1;
1686 if (LM_InitializeAdapter(pDevice
) != LM_STATUS_SUCCESS
) {
1687 pUmDevice
->opened
= 0;
1688 free_irq(dev
->irq
, dev
);
1689 bcm5700_freemem(dev
);
1693 bcm5700_set_vlan_mode(pUmDevice
);
1694 bcm5700_init_counters(pUmDevice
);
1696 if (pDevice
->Flags
& UNDI_FIX_FLAG
) {
1697 printk(KERN_INFO
"%s: Using indirect register access\n", dev
->name
);
1700 if (memcmp(dev
->dev_addr
, pDevice
->NodeAddress
, 6))
1702 /* Do not use invalid eth addrs: any multicast & all zeros */
1703 if( is_valid_ether_addr(dev
->dev_addr
) ){
1704 LM_SetMacAddress(pDevice
, dev
->dev_addr
);
1708 printk(KERN_INFO
"%s: Invalid administered node address\n",dev
->name
);
1709 memcpy(dev
->dev_addr
, pDevice
->NodeAddress
, 6);
1713 if (tigon3_debug
> 1)
1714 printk(KERN_DEBUG
"%s: tigon3_open() irq %d.\n", dev
->name
, dev
->irq
);
1716 QQ_InitQueue(&pUmDevice
->rx_out_of_buf_q
.Container
,
1717 MAX_RX_PACKET_DESC_COUNT
);
1720 #if (LINUX_VERSION_CODE < 0x020300)
1724 atomic_set(&pUmDevice
->intr_sem
, 0);
1726 LM_EnableInterrupt(pDevice
);
1728 #if defined(CONFIG_PCI_MSI) || defined(CONFIG_PCI_USE_VECTOR)
1730 if (pDevice
->Flags
& USING_MSI_FLAG
){
1732 /* int test to check support on older machines */
1733 if (b57_test_intr(pUmDevice
) != 1) {
1735 LM_DisableInterrupt(pDevice
);
1736 free_irq(pUmDevice
->pdev
->irq
, dev
);
1737 pci_disable_msi(pUmDevice
->pdev
);
1738 REG_WR(pDevice
, Msi
.Mode
, 1 );
1739 pDevice
->Flags
&= ~USING_MSI_FLAG
;
1741 rc
= LM_ResetAdapter(pDevice
);
1742 printk(KERN_ALERT
" The MSI support in this system is not functional.\n");
1744 if (rc
== LM_STATUS_SUCCESS
)
1750 rc
= request_irq(pUmDevice
->pdev
->irq
, &bcm5700_interrupt
,
1751 SA_SHIRQ
, dev
->name
, dev
);
1756 bcm5700_freemem(dev
);
1757 pUmDevice
->opened
= 0;
1762 pDevice
->InitDone
= TRUE
;
1763 atomic_set(&pUmDevice
->intr_sem
, 0);
1764 LM_EnableInterrupt(pDevice
);
1769 init_timer(&pUmDevice
->timer
);
1770 pUmDevice
->timer
.expires
= RUN_AT(pUmDevice
->timer_interval
);
1771 pUmDevice
->timer
.data
= (unsigned long)dev
;
1772 pUmDevice
->timer
.function
= &bcm5700_timer
;
1773 add_timer(&pUmDevice
->timer
);
1775 if (T3_ASIC_IS_5705_BEYOND(pDevice
->ChipRevId
)) {
1776 init_timer(&pUmDevice
->statstimer
);
1777 pUmDevice
->statstimer
.expires
= RUN_AT(pUmDevice
->statstimer_interval
);
1778 pUmDevice
->statstimer
.data
= (unsigned long)dev
;
1779 pUmDevice
->statstimer
.function
= &bcm5700_stats_timer
;
1780 add_timer(&pUmDevice
->statstimer
);
1783 if(pDevice
->Flags
& USING_MSI_FLAG
)
1784 printk(KERN_INFO
"%s: Using Message Signaled Interrupt (MSI) \n", dev
->name
);
1786 printk(KERN_INFO
"%s: Using PCI INTX interrupt \n", dev
->name
);
1788 netif_start_queue(dev
);
1795 bcm5700_stats_timer(unsigned long data
)
1797 struct net_device
*dev
= (struct net_device
*)data
;
1798 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)dev
->priv
;
1799 PLM_DEVICE_BLOCK pDevice
= (PLM_DEVICE_BLOCK
) pUmDevice
;
1800 unsigned long flags
= 0;
1802 if (!pUmDevice
->opened
)
1805 if (!atomic_read(&pUmDevice
->intr_sem
) &&
1806 !pUmDevice
->suspended
&&
1807 (pDevice
->LinkStatus
== LM_STATUS_LINK_ACTIVE
)) {
1808 BCM5700_LOCK(pUmDevice
, flags
);
1809 LM_GetStats(pDevice
);
1810 BCM5700_UNLOCK(pUmDevice
, flags
);
1813 pUmDevice
->statstimer
.expires
= RUN_AT(pUmDevice
->statstimer_interval
);
1815 add_timer(&pUmDevice
->statstimer
);
1820 bcm5700_timer(unsigned long data
)
1822 struct net_device
*dev
= (struct net_device
*)data
;
1823 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)dev
->priv
;
1824 PLM_DEVICE_BLOCK pDevice
= (PLM_DEVICE_BLOCK
) pUmDevice
;
1825 unsigned long flags
= 0;
1828 if (!pUmDevice
->opened
)
1831 /* BCM4785: Flush posted writes from GbE to host memory. */
1832 if (pDevice
->Flags
& FLUSH_POSTED_WRITE_FLAG
)
1833 REG_RD(pDevice
, HostCoalesce
.Mode
);
1835 if (atomic_read(&pUmDevice
->intr_sem
) || pUmDevice
->suspended
) {
1836 pUmDevice
->timer
.expires
= RUN_AT(pUmDevice
->timer_interval
);
1837 add_timer(&pUmDevice
->timer
);
1841 #ifdef INCLUDE_TBI_SUPPORT
1842 if ((pDevice
->TbiFlags
& TBI_POLLING_FLAGS
) &&
1843 (--pUmDevice
->poll_tbi_expiry
<= 0)) {
1845 BCM5700_PHY_LOCK(pUmDevice
, flags
);
1846 value32
= REG_RD(pDevice
, MacCtrl
.Status
);
1847 if (((pDevice
->LinkStatus
== LM_STATUS_LINK_ACTIVE
) &&
1848 ((value32
& (MAC_STATUS_LINK_STATE_CHANGED
|
1849 MAC_STATUS_CFG_CHANGED
)) ||
1850 !(value32
& MAC_STATUS_PCS_SYNCED
)))
1852 ((pDevice
->LinkStatus
!= LM_STATUS_LINK_ACTIVE
) &&
1853 (value32
& (MAC_STATUS_PCS_SYNCED
|
1854 MAC_STATUS_SIGNAL_DETECTED
))))
1856 LM_SetupPhy(pDevice
);
1858 BCM5700_PHY_UNLOCK(pUmDevice
, flags
);
1859 pUmDevice
->poll_tbi_expiry
= pUmDevice
->poll_tbi_interval
;
1864 if (pUmDevice
->delayed_link_ind
> 0) {
1865 if (pUmDevice
->delayed_link_ind
== 1)
1866 MM_IndicateStatus(pDevice
, pDevice
->LinkStatus
);
1868 pUmDevice
->delayed_link_ind
--;
1871 if (pUmDevice
->crc_counter_expiry
> 0)
1872 pUmDevice
->crc_counter_expiry
--;
1874 if (!pUmDevice
->interrupt
) {
1875 if (!(pDevice
->Flags
& USE_TAGGED_STATUS_FLAG
)) {
1876 BCM5700_LOCK(pUmDevice
, flags
);
1877 if (pDevice
->pStatusBlkVirt
->Status
& STATUS_BLOCK_UPDATED
) {
1878 /* This will generate an interrupt */
1879 REG_WR(pDevice
, Grc
.LocalCtrl
,
1880 pDevice
->GrcLocalCtrl
|
1881 GRC_MISC_LOCAL_CTRL_SET_INT
);
1884 REG_WR(pDevice
, HostCoalesce
.Mode
,
1885 pDevice
->CoalesceMode
|
1886 HOST_COALESCE_ENABLE
|
1889 if (!(REG_RD(pDevice
, DmaWrite
.Mode
) &
1890 DMA_WRITE_MODE_ENABLE
)) {
1891 BCM5700_UNLOCK(pUmDevice
, flags
);
1895 BCM5700_UNLOCK(pUmDevice
, flags
);
1897 if (pUmDevice
->tx_queued
) {
1898 pUmDevice
->tx_queued
= 0;
1899 netif_wake_queue(dev
);
1902 #if (LINUX_VERSION_CODE < 0x02032b)
1903 if ((QQ_GetEntryCnt(&pDevice
->TxPacketFreeQ
.Container
) !=
1904 pDevice
->TxPacketDescCnt
) &&
1905 ((jiffies
- dev
->trans_start
) > TX_TIMEOUT
)) {
1907 printk(KERN_WARNING
"%s: Tx hung\n", dev
->name
);
1913 #ifndef BCM_NAPI_RXPOLL
1914 if (pUmDevice
->adaptive_coalesce
) {
1915 pUmDevice
->adaptive_expiry
--;
1916 if (pUmDevice
->adaptive_expiry
== 0) {
1917 pUmDevice
->adaptive_expiry
= HZ
/
1918 pUmDevice
->timer_interval
;
1919 bcm5700_adapt_coalesce(pUmDevice
);
1924 if (QQ_GetEntryCnt(&pUmDevice
->rx_out_of_buf_q
.Container
) >
1925 (unsigned int) pUmDevice
->rx_buf_repl_panic_thresh
) {
1926 /* Generate interrupt and let isr allocate buffers */
1927 REG_WR(pDevice
, HostCoalesce
.Mode
, pDevice
->CoalesceMode
|
1928 HOST_COALESCE_ENABLE
| HOST_COALESCE_NOW
);
1932 if (pDevice
->AsfFlags
& ASF_ENABLED
) {
1933 pUmDevice
->asf_heartbeat
--;
1934 if (pUmDevice
->asf_heartbeat
== 0) {
1935 if( (pDevice
->Flags
& UNDI_FIX_FLAG
) ||
1936 (pDevice
->Flags
& ENABLE_PCIX_FIX_FLAG
)) {
1937 MEM_WR_OFFSET(pDevice
, T3_CMD_MAILBOX
,
1938 T3_CMD_NICDRV_ALIVE2
);
1939 MEM_WR_OFFSET(pDevice
, T3_CMD_LENGTH_MAILBOX
,
1941 MEM_WR_OFFSET(pDevice
, T3_CMD_DATA_MAILBOX
, 5);
1944 (T3_NIC_MBUF_POOL_ADDR
+
1946 T3_CMD_NICDRV_ALIVE2
, 1);
1948 (T3_NIC_MBUF_POOL_ADDR
+
1949 T3_CMD_LENGTH_MAILBOX
),4,1);
1951 (T3_NIC_MBUF_POOL_ADDR
+
1952 T3_CMD_DATA_MAILBOX
),5,1);
1955 value32
= REG_RD(pDevice
, Grc
.RxCpuEvent
);
1956 REG_WR(pDevice
, Grc
.RxCpuEvent
, value32
| BIT_14
);
1957 pUmDevice
->asf_heartbeat
= (2 * HZ
) /
1958 pUmDevice
->timer_interval
;
1963 if (pDevice
->PhyFlags
& PHY_IS_FIBER
){
1964 BCM5700_PHY_LOCK(pUmDevice
, flags
);
1965 LM_5714_FamFiberCheckLink(pDevice
);
1966 BCM5700_PHY_UNLOCK(pUmDevice
, flags
);
1969 pUmDevice
->timer
.expires
= RUN_AT(pUmDevice
->timer_interval
);
1970 add_timer(&pUmDevice
->timer
);
1974 bcm5700_init_counters(PUM_DEVICE_BLOCK pUmDevice
)
1977 #ifndef BCM_NAPI_RXPOLL
1978 LM_DEVICE_BLOCK
*pDevice
= &pUmDevice
->lm_dev
;
1980 pUmDevice
->rx_curr_coalesce_frames
= pDevice
->RxMaxCoalescedFrames
;
1981 pUmDevice
->rx_curr_coalesce_ticks
= pDevice
->RxCoalescingTicks
;
1982 pUmDevice
->tx_curr_coalesce_frames
= pDevice
->TxMaxCoalescedFrames
;
1983 pUmDevice
->rx_last_cnt
= 0;
1984 pUmDevice
->tx_last_cnt
= 0;
1987 pUmDevice
->phy_crc_count
= 0;
1989 pUmDevice
->tx_zc_count
= 0;
1990 pUmDevice
->tx_chksum_count
= 0;
1991 pUmDevice
->tx_himem_count
= 0;
1992 pUmDevice
->rx_good_chksum_count
= 0;
1993 pUmDevice
->rx_bad_chksum_count
= 0;
1996 pUmDevice
->tso_pkt_count
= 0;
2002 #ifndef BCM_NAPI_RXPOLL
2004 bcm5700_do_adapt_coalesce(PUM_DEVICE_BLOCK pUmDevice
,
2005 int rx_frames
, int rx_ticks
, int tx_frames
, int rx_frames_intr
)
2007 unsigned long flags
= 0;
2008 LM_DEVICE_BLOCK
*pDevice
= &pUmDevice
->lm_dev
;
2010 if (pUmDevice
->do_global_lock
) {
2011 if (spin_is_locked(&pUmDevice
->global_lock
))
2013 spin_lock_irqsave(&pUmDevice
->global_lock
, flags
);
2015 pUmDevice
->rx_curr_coalesce_frames
= rx_frames
;
2016 pUmDevice
->rx_curr_coalesce_ticks
= rx_ticks
;
2017 pUmDevice
->tx_curr_coalesce_frames
= tx_frames
;
2018 pUmDevice
->rx_curr_coalesce_frames_intr
= rx_frames_intr
;
2019 REG_WR(pDevice
, HostCoalesce
.RxMaxCoalescedFrames
, rx_frames
);
2021 REG_WR(pDevice
, HostCoalesce
.RxCoalescingTicks
, rx_ticks
);
2023 REG_WR(pDevice
, HostCoalesce
.TxMaxCoalescedFrames
, tx_frames
);
2025 REG_WR(pDevice
, HostCoalesce
.RxMaxCoalescedFramesDuringInt
,
2028 BCM5700_UNLOCK(pUmDevice
, flags
);
2033 bcm5700_adapt_coalesce(PUM_DEVICE_BLOCK pUmDevice
)
2035 PLM_DEVICE_BLOCK pDevice
= &pUmDevice
->lm_dev
;
2036 uint rx_curr_cnt
, tx_curr_cnt
, rx_delta
, tx_delta
, total_delta
;
2038 rx_curr_cnt
= pDevice
->pStatsBlkVirt
->ifHCInUcastPkts
.Low
;
2039 tx_curr_cnt
= pDevice
->pStatsBlkVirt
->ifHCOutUcastPkts
.Low
;
2040 if ((rx_curr_cnt
<= pUmDevice
->rx_last_cnt
) ||
2041 (tx_curr_cnt
< pUmDevice
->tx_last_cnt
)) {
2043 /* skip if there is counter rollover */
2044 pUmDevice
->rx_last_cnt
= rx_curr_cnt
;
2045 pUmDevice
->tx_last_cnt
= tx_curr_cnt
;
2049 rx_delta
= rx_curr_cnt
- pUmDevice
->rx_last_cnt
;
2050 tx_delta
= tx_curr_cnt
- pUmDevice
->tx_last_cnt
;
2051 total_delta
= (((rx_delta
+ rx_delta
) + tx_delta
) / 3) << 1;
2053 pUmDevice
->rx_last_cnt
= rx_curr_cnt
;
2054 pUmDevice
->tx_last_cnt
= tx_curr_cnt
;
2056 if (total_delta
< ADAPTIVE_LO_PKT_THRESH
) {
2057 if (pUmDevice
->rx_curr_coalesce_frames
!=
2058 ADAPTIVE_LO_RX_MAX_COALESCED_FRAMES
) {
2060 bcm5700_do_adapt_coalesce(pUmDevice
,
2061 ADAPTIVE_LO_RX_MAX_COALESCED_FRAMES
,
2062 ADAPTIVE_LO_RX_COALESCING_TICKS
,
2063 ADAPTIVE_LO_TX_MAX_COALESCED_FRAMES
,
2064 ADAPTIVE_LO_RX_MAX_COALESCED_FRAMES_DURING_INT
);
2067 else if (total_delta
< ADAPTIVE_HI_PKT_THRESH
) {
2068 if (pUmDevice
->rx_curr_coalesce_frames
!=
2069 DEFAULT_RX_MAX_COALESCED_FRAMES
) {
2071 bcm5700_do_adapt_coalesce(pUmDevice
,
2072 DEFAULT_RX_MAX_COALESCED_FRAMES
,
2073 DEFAULT_RX_COALESCING_TICKS
,
2074 DEFAULT_TX_MAX_COALESCED_FRAMES
,
2075 DEFAULT_RX_MAX_COALESCED_FRAMES_DURING_INT
);
2079 if (pUmDevice
->rx_curr_coalesce_frames
!=
2080 ADAPTIVE_HI_RX_MAX_COALESCED_FRAMES
) {
2082 bcm5700_do_adapt_coalesce(pUmDevice
,
2083 ADAPTIVE_HI_RX_MAX_COALESCED_FRAMES
,
2084 ADAPTIVE_HI_RX_COALESCING_TICKS
,
2085 ADAPTIVE_HI_TX_MAX_COALESCED_FRAMES
,
2086 ADAPTIVE_HI_RX_MAX_COALESCED_FRAMES_DURING_INT
);
2095 bcm5700_reset(struct net_device
*dev
)
2097 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)dev
->priv
;
2098 PLM_DEVICE_BLOCK pDevice
= (PLM_DEVICE_BLOCK
) pUmDevice
;
2099 unsigned long flags
;
2103 if( (dev
->features
& NETIF_F_TSO
) &&
2104 (pUmDevice
->tx_full
) ) {
2106 dev
->features
&= ~NETIF_F_TSO
;
2110 netif_stop_queue(dev
);
2111 bcm5700_intr_off(pUmDevice
);
2112 BCM5700_PHY_LOCK(pUmDevice
, flags
);
2113 LM_ResetAdapter(pDevice
);
2114 pDevice
->InitDone
= TRUE
;
2115 bcm5700_do_rx_mode(dev
);
2116 bcm5700_set_vlan_mode(pUmDevice
);
2117 bcm5700_init_counters(pUmDevice
);
2118 if (memcmp(dev
->dev_addr
, pDevice
->NodeAddress
, 6)) {
2119 LM_SetMacAddress(pDevice
, dev
->dev_addr
);
2121 BCM5700_PHY_UNLOCK(pUmDevice
, flags
);
2122 atomic_set(&pUmDevice
->intr_sem
, 1);
2123 bcm5700_intr_on(pUmDevice
);
2124 netif_wake_queue(dev
);
2128 bcm5700_set_vlan_mode(UM_DEVICE_BLOCK
*pUmDevice
)
2130 LM_DEVICE_BLOCK
*pDevice
= &pUmDevice
->lm_dev
;
2131 LM_UINT32 ReceiveMask
= pDevice
->ReceiveMask
;
2132 int vlan_tag_mode
= pUmDevice
->vlan_tag_mode
;
2134 if (vlan_tag_mode
== VLAN_TAG_MODE_AUTO_STRIP
) {
2135 if (pDevice
->AsfFlags
& ASF_ENABLED
) {
2136 vlan_tag_mode
= VLAN_TAG_MODE_FORCED_STRIP
;
2139 vlan_tag_mode
= VLAN_TAG_MODE_NORMAL_STRIP
;
2142 if (vlan_tag_mode
== VLAN_TAG_MODE_NORMAL_STRIP
) {
2143 ReceiveMask
|= LM_KEEP_VLAN_TAG
;
2145 if (pUmDevice
->vlgrp
)
2146 ReceiveMask
&= ~LM_KEEP_VLAN_TAG
;
2149 else if (vlan_tag_mode
== VLAN_TAG_MODE_FORCED_STRIP
) {
2150 ReceiveMask
&= ~LM_KEEP_VLAN_TAG
;
2152 if (ReceiveMask
!= pDevice
->ReceiveMask
)
2154 LM_SetReceiveMask(pDevice
, ReceiveMask
);
2159 bcm5700_poll_wait(UM_DEVICE_BLOCK
*pUmDevice
)
2161 #ifdef BCM_NAPI_RXPOLL
2162 while (pUmDevice
->lm_dev
.RxPoll
) {
2163 current
->state
= TASK_INTERRUPTIBLE
;
2164 schedule_timeout(1);
2172 bcm5700_vlan_rx_register(struct net_device
*dev
, struct vlan_group
*vlgrp
)
2174 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
) dev
->priv
;
2176 bcm5700_intr_off(pUmDevice
);
2177 bcm5700_poll_wait(pUmDevice
);
2178 pUmDevice
->vlgrp
= vlgrp
;
2179 bcm5700_set_vlan_mode(pUmDevice
);
2180 bcm5700_intr_on(pUmDevice
);
2184 bcm5700_vlan_rx_kill_vid(struct net_device
*dev
, uint16_t vid
)
2186 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
) dev
->priv
;
2188 bcm5700_intr_off(pUmDevice
);
2189 bcm5700_poll_wait(pUmDevice
);
2190 if (pUmDevice
->vlgrp
) {
2191 pUmDevice
->vlgrp
->vlan_devices
[vid
] = NULL
;
2193 bcm5700_intr_on(pUmDevice
);
2198 bcm5700_start_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
2200 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)dev
->priv
;
2201 PLM_DEVICE_BLOCK pDevice
= (PLM_DEVICE_BLOCK
) pUmDevice
;
2203 PUM_PACKET pUmPacket
;
2204 unsigned long flags
= 0;
2208 uint16_t ip_tcp_len
, tcp_opt_len
, tcp_seg_flags
;
2211 if ((pDevice
->LinkStatus
== LM_STATUS_LINK_DOWN
) ||
2212 !pDevice
->InitDone
|| pUmDevice
->suspended
)
2218 #if (LINUX_VERSION_CODE < 0x02032b)
2219 if (test_and_set_bit(0, &dev
->tbusy
)) {
2224 if (pUmDevice
->do_global_lock
&& pUmDevice
->interrupt
) {
2225 netif_stop_queue(dev
);
2226 pUmDevice
->tx_queued
= 1;
2227 if (!pUmDevice
->interrupt
) {
2228 netif_wake_queue(dev
);
2229 pUmDevice
->tx_queued
= 0;
2234 pPacket
= (PLM_PACKET
)
2235 QQ_PopHead(&pDevice
->TxPacketFreeQ
.Container
);
2237 netif_stop_queue(dev
);
2238 pUmDevice
->tx_full
= 1;
2239 if (QQ_GetEntryCnt(&pDevice
->TxPacketFreeQ
.Container
)) {
2240 netif_wake_queue(dev
);
2241 pUmDevice
->tx_full
= 0;
2245 pUmPacket
= (PUM_PACKET
) pPacket
;
2246 pUmPacket
->skbuff
= skb
;
2247 pUmDevice
->stats
.tx_bytes
+= skb
->len
;
2249 if (skb
->ip_summed
== CHECKSUM_HW
) {
2250 pPacket
->Flags
= SND_BD_FLAG_TCP_UDP_CKSUM
;
2252 pUmDevice
->tx_chksum_count
++;
2259 frag_no
= skb_shinfo(skb
)->nr_frags
;
2263 if (atomic_read(&pDevice
->SendBdLeft
) < (frag_no
+ 1)) {
2264 netif_stop_queue(dev
);
2265 pUmDevice
->tx_full
= 1;
2266 QQ_PushHead(&pDevice
->TxPacketFreeQ
.Container
, pPacket
);
2267 if (atomic_read(&pDevice
->SendBdLeft
) >= (frag_no
+ 1)) {
2268 netif_wake_queue(dev
);
2269 pUmDevice
->tx_full
= 0;
2274 pPacket
->u
.Tx
.FragCount
= frag_no
+ 1;
2276 if (pPacket
->u
.Tx
.FragCount
> 1)
2277 pUmDevice
->tx_zc_count
++;
2281 if (pUmDevice
->vlgrp
&& vlan_tx_tag_present(skb
)) {
2282 pPacket
->VlanTag
= vlan_tx_tag_get(skb
);
2283 pPacket
->Flags
|= SND_BD_FLAG_VLAN_TAG
;
2288 if ((mss
= (LM_UINT32
) skb_shinfo(skb
)->tso_size
) &&
2289 (skb
->len
> pDevice
->TxMtu
)) {
2291 #if (LINUX_VERSION_CODE >= 0x02060c)
2293 if (skb_header_cloned(skb
) &&
2294 pskb_expand_head(skb
, 0, 0, GFP_ATOMIC
)) {
2300 pUmDevice
->tso_pkt_count
++;
2302 pPacket
->Flags
|= SND_BD_FLAG_CPU_PRE_DMA
|
2303 SND_BD_FLAG_CPU_POST_DMA
;
2306 if (skb
->h
.th
->doff
> 5) {
2307 tcp_opt_len
= (skb
->h
.th
->doff
- 5) << 2;
2309 ip_tcp_len
= (skb
->nh
.iph
->ihl
<< 2) + sizeof(struct tcphdr
);
2310 skb
->nh
.iph
->check
= 0;
2312 if ( T3_ASIC_IS_575X_PLUS(pDevice
->ChipRevId
) ){
2313 skb
->h
.th
->check
= 0;
2314 pPacket
->Flags
&= ~SND_BD_FLAG_TCP_UDP_CKSUM
;
2317 skb
->h
.th
->check
= ~csum_tcpudp_magic(
2318 skb
->nh
.iph
->saddr
, skb
->nh
.iph
->daddr
,
2322 skb
->nh
.iph
->tot_len
= htons(mss
+ ip_tcp_len
+ tcp_opt_len
);
2325 if (tcp_opt_len
|| (skb
->nh
.iph
->ihl
> 5)) {
2326 if ( T3_ASIC_IS_5705_BEYOND(pDevice
->ChipRevId
) ){
2328 ((skb
->nh
.iph
->ihl
- 5) +
2329 (tcp_opt_len
>> 2)) << 11;
2333 ((skb
->nh
.iph
->ihl
- 5) +
2334 (tcp_opt_len
>> 2)) << 12;
2337 pPacket
->u
.Tx
.MaxSegmentSize
= mss
| tcp_seg_flags
;
2341 pPacket
->u
.Tx
.MaxSegmentSize
= 0;
2344 BCM5700_LOCK(pUmDevice
, flags
);
2345 LM_SendPacket(pDevice
, pPacket
);
2346 BCM5700_UNLOCK(pUmDevice
, flags
);
2348 #if (LINUX_VERSION_CODE < 0x02032b)
2349 netif_wake_queue(dev
);
2351 dev
->trans_start
= jiffies
;
2357 #ifdef BCM_NAPI_RXPOLL
2359 bcm5700_poll(struct net_device
*dev
, int *budget
)
2361 int orig_budget
= *budget
;
2363 UM_DEVICE_BLOCK
*pUmDevice
= (UM_DEVICE_BLOCK
*) dev
->priv
;
2364 LM_DEVICE_BLOCK
*pDevice
= &pUmDevice
->lm_dev
;
2365 unsigned long flags
= 0;
2368 if (orig_budget
> dev
->quota
)
2369 orig_budget
= dev
->quota
;
2371 BCM5700_LOCK(pUmDevice
, flags
);
2372 /* BCM4785: Flush posted writes from GbE to host memory. */
2373 if (pDevice
->Flags
& FLUSH_POSTED_WRITE_FLAG
)
2374 REG_RD(pDevice
, HostCoalesce
.Mode
);
2375 work_done
= LM_ServiceRxPoll(pDevice
, orig_budget
);
2376 *budget
-= work_done
;
2377 dev
->quota
-= work_done
;
2379 if (QQ_GetEntryCnt(&pUmDevice
->rx_out_of_buf_q
.Container
)) {
2380 replenish_rx_buffers(pUmDevice
, 0);
2382 BCM5700_UNLOCK(pUmDevice
, flags
);
2384 MM_IndicateRxPackets(pDevice
);
2385 BCM5700_LOCK(pUmDevice
, flags
);
2386 LM_QueueRxPackets(pDevice
);
2387 BCM5700_UNLOCK(pUmDevice
, flags
);
2389 if ((work_done
< orig_budget
) || atomic_read(&pUmDevice
->intr_sem
) ||
2390 pUmDevice
->suspended
) {
2392 netif_rx_complete(dev
);
2393 BCM5700_LOCK(pUmDevice
, flags
);
2394 REG_WR(pDevice
, Grc
.Mode
, pDevice
->GrcMode
);
2395 pDevice
->RxPoll
= FALSE
;
2396 if (pDevice
->RxPoll
) {
2397 BCM5700_UNLOCK(pUmDevice
, flags
);
2400 /* Take care of possible missed rx interrupts */
2401 REG_RD_BACK(pDevice
, Grc
.Mode
); /* flush the register write */
2402 tag
= pDevice
->pStatusBlkVirt
->StatusTag
;
2403 if ((pDevice
->pStatusBlkVirt
->Status
& STATUS_BLOCK_UPDATED
) ||
2404 (pDevice
->pStatusBlkVirt
->Idx
[0].RcvProdIdx
!=
2405 pDevice
->RcvRetConIdx
)) {
2407 REG_WR(pDevice
, HostCoalesce
.Mode
,
2408 pDevice
->CoalesceMode
| HOST_COALESCE_ENABLE
|
2411 /* If a new status block is pending in the WDMA state machine */
2412 /* before the register write to enable the rx interrupt, */
2413 /* the new status block may DMA with no interrupt. In this */
2414 /* scenario, the tag read above will be older than the tag in */
2415 /* the pending status block and writing the older tag will */
2416 /* cause interrupt to be generated. */
2417 else if (pDevice
->Flags
& USE_TAGGED_STATUS_FLAG
) {
2418 MB_REG_WR(pDevice
, Mailbox
.Interrupt
[0].Low
,
2420 /* Make sure we service tx in case some tx interrupts */
2422 if (atomic_read(&pDevice
->SendBdLeft
) <
2423 (T3_SEND_RCB_ENTRY_COUNT
/ 2)) {
2424 REG_WR(pDevice
, HostCoalesce
.Mode
,
2425 pDevice
->CoalesceMode
|
2426 HOST_COALESCE_ENABLE
|
2430 BCM5700_UNLOCK(pUmDevice
, flags
);
2435 #endif /* BCM_NAPI_RXPOLL */
2438 bcm5700_interrupt(int irq
, void *dev_instance
, struct pt_regs
*regs
)
2440 struct net_device
*dev
= (struct net_device
*)dev_instance
;
2441 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)dev
->priv
;
2442 PLM_DEVICE_BLOCK pDevice
= (PLM_DEVICE_BLOCK
) pUmDevice
;
2443 LM_UINT32 oldtag
, newtag
;
2444 int i
, max_intr_loop
;
2448 unsigned int handled
= 1;
2450 if (!pDevice
->InitDone
) {
2452 return IRQ_RETVAL(handled
);
2455 bcm5700_intr_lock(pUmDevice
);
2456 if (atomic_read(&pUmDevice
->intr_sem
)) {
2457 MB_REG_WR(pDevice
, Mailbox
.Interrupt
[0].Low
, 1);
2458 bcm5700_intr_unlock(pUmDevice
);
2460 return IRQ_RETVAL(handled
);
2463 if (test_and_set_bit(0, (void*)&pUmDevice
->interrupt
)) {
2464 printk(KERN_ERR
"%s: Duplicate entry of the interrupt handler\n",
2466 bcm5700_intr_unlock(pUmDevice
);
2468 return IRQ_RETVAL(handled
);
2471 /* BCM4785: Flush posted writes from GbE to host memory. */
2472 if (pDevice
->Flags
& FLUSH_POSTED_WRITE_FLAG
)
2473 REG_RD(pDevice
, HostCoalesce
.Mode
);
2475 if ((pDevice
->Flags
& USING_MSI_FLAG
) ||
2476 (pDevice
->pStatusBlkVirt
->Status
& STATUS_BLOCK_UPDATED
) ||
2477 !(REG_RD(pDevice
,PciCfg
.PciState
) & T3_PCI_STATE_INTERRUPT_NOT_ACTIVE
) )
2480 if (pUmDevice
->intr_test
) {
2481 if (!(REG_RD(pDevice
, PciCfg
.PciState
) &
2482 T3_PCI_STATE_INTERRUPT_NOT_ACTIVE
) ||
2483 pDevice
->Flags
& USING_MSI_FLAG
) {
2484 pUmDevice
->intr_test_result
= 1;
2486 pUmDevice
->intr_test
= 0;
2489 #ifdef BCM_NAPI_RXPOLL
2494 if (pDevice
->Flags
& USE_TAGGED_STATUS_FLAG
) {
2495 MB_REG_WR(pDevice
, Mailbox
.Interrupt
[0].Low
, 1);
2496 oldtag
= pDevice
->pStatusBlkVirt
->StatusTag
;
2498 for (i
= 0; ; i
++) {
2499 pDevice
->pStatusBlkVirt
->Status
&= ~STATUS_BLOCK_UPDATED
;
2501 LM_ServiceInterrupts(pDevice
);
2502 /* BCM4785: Flush GbE posted writes to host memory. */
2503 if (pDevice
->Flags
& FLUSH_POSTED_WRITE_FLAG
)
2504 MB_REG_RD(pDevice
, Mailbox
.Interrupt
[0].Low
);
2505 newtag
= pDevice
->pStatusBlkVirt
->StatusTag
;
2506 if ((newtag
== oldtag
) || (i
> max_intr_loop
)) {
2507 MB_REG_WR(pDevice
, Mailbox
.Interrupt
[0].Low
, oldtag
<< 24);
2508 pDevice
->LastTag
= oldtag
;
2509 if (pDevice
->Flags
& UNDI_FIX_FLAG
) {
2510 REG_WR(pDevice
, Grc
.LocalCtrl
,
2511 pDevice
->GrcLocalCtrl
| 0x2);
2524 MB_REG_WR(pDevice
, Mailbox
.Interrupt
[0].Low
, 1);
2525 pDevice
->pStatusBlkVirt
->Status
&= ~STATUS_BLOCK_UPDATED
;
2526 LM_ServiceInterrupts(pDevice
);
2527 MB_REG_WR(pDevice
, Mailbox
.Interrupt
[0].Low
, 0);
2528 dummy
= MB_REG_RD(pDevice
, Mailbox
.Interrupt
[0].Low
);
2531 while ((pDevice
->pStatusBlkVirt
->Status
& STATUS_BLOCK_UPDATED
) &&
2532 (i
< max_intr_loop
));
2534 if (pDevice
->Flags
& UNDI_FIX_FLAG
) {
2535 REG_WR(pDevice
, Grc
.LocalCtrl
,
2536 pDevice
->GrcLocalCtrl
| 0x2);
2542 /* not my interrupt */
2547 repl_buf_count
= QQ_GetEntryCnt(&pUmDevice
->rx_out_of_buf_q
.Container
);
2548 if (((repl_buf_count
> pUmDevice
->rx_buf_repl_panic_thresh
) ||
2549 pDevice
->QueueAgain
) &&
2550 (!test_and_set_bit(0, &pUmDevice
->tasklet_busy
))) {
2552 replenish_rx_buffers(pUmDevice
, pUmDevice
->rx_buf_repl_isr_limit
);
2553 clear_bit(0, (void*)&pUmDevice
->tasklet_busy
);
2555 else if ((repl_buf_count
> pUmDevice
->rx_buf_repl_thresh
) &&
2556 !pUmDevice
->tasklet_pending
) {
2558 pUmDevice
->tasklet_pending
= 1;
2559 tasklet_schedule(&pUmDevice
->tasklet
);
2562 #ifdef BCM_NAPI_RXPOLL
2563 if (!pDevice
->RxPoll
&&
2564 QQ_GetEntryCnt(&pUmDevice
->rx_out_of_buf_q
.Container
)) {
2565 pDevice
->RxPoll
= 1;
2566 MM_ScheduleRxPoll(pDevice
);
2569 if (QQ_GetEntryCnt(&pUmDevice
->rx_out_of_buf_q
.Container
)) {
2570 replenish_rx_buffers(pUmDevice
, 0);
2573 if (QQ_GetEntryCnt(&pDevice
->RxPacketFreeQ
.Container
) ||
2574 pDevice
->QueueAgain
) {
2576 LM_QueueRxPackets(pDevice
);
2581 clear_bit(0, (void*)&pUmDevice
->interrupt
);
2582 bcm5700_intr_unlock(pUmDevice
);
2583 if (pUmDevice
->tx_queued
) {
2584 pUmDevice
->tx_queued
= 0;
2585 netif_wake_queue(dev
);
2587 return IRQ_RETVAL(handled
);
2593 bcm5700_tasklet(unsigned long data
)
2595 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)data
;
2596 unsigned long flags
= 0;
2598 /* RH 7.2 Beta 3 tasklets are reentrant */
2599 if (test_and_set_bit(0, &pUmDevice
->tasklet_busy
)) {
2600 pUmDevice
->tasklet_pending
= 0;
2604 pUmDevice
->tasklet_pending
= 0;
2605 if (pUmDevice
->opened
&& !pUmDevice
->suspended
) {
2606 BCM5700_LOCK(pUmDevice
, flags
);
2607 replenish_rx_buffers(pUmDevice
, 0);
2608 BCM5700_UNLOCK(pUmDevice
, flags
);
2611 clear_bit(0, &pUmDevice
->tasklet_busy
);
2616 bcm5700_close(struct net_device
*dev
)
2619 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)dev
->priv
;
2620 PLM_DEVICE_BLOCK pDevice
= (PLM_DEVICE_BLOCK
) pUmDevice
;
2622 #if (LINUX_VERSION_CODE < 0x02032b)
2625 netif_stop_queue(dev
);
2626 pUmDevice
->opened
= 0;
2629 if( !(pDevice
->AsfFlags
& ASF_ENABLED
) )
2632 if( enable_wol
[pUmDevice
->index
] == 0 )
2634 B57_INFO(("%s: %s NIC Link is DOWN\n", bcm5700_driver
, dev
->name
));
2636 if (tigon3_debug
> 1)
2637 printk(KERN_DEBUG
"%s: Shutting down Tigon3\n",
2640 LM_MulticastClear(pDevice
);
2641 bcm5700_shutdown(pUmDevice
);
2643 if (T3_ASIC_IS_5705_BEYOND(pDevice
->ChipRevId
)) {
2644 del_timer_sync(&pUmDevice
->statstimer
);
2647 del_timer_sync(&pUmDevice
->timer
);
2649 free_irq(pUmDevice
->pdev
->irq
, dev
);
2651 #if defined(CONFIG_PCI_MSI) || defined(CONFIG_PCI_USE_VECTOR)
2653 if(pDevice
->Flags
& USING_MSI_FLAG
) {
2654 pci_disable_msi(pUmDevice
->pdev
);
2655 REG_WR(pDevice
, Msi
.Mode
, 1 );
2656 pDevice
->Flags
&= ~USING_MSI_FLAG
;
2662 #if (LINUX_VERSION_CODE < 0x020300)
2666 /* BCM4785: Don't go to low-power state because it will power down the smbus block. */
2667 if (!(pDevice
->Flags
& SB_CORE_FLAG
))
2668 LM_SetPowerState(pDevice
, LM_POWER_STATE_D3
);
2671 bcm5700_freemem(dev
);
2673 QQ_InitQueue(&pDevice
->RxPacketFreeQ
.Container
,
2674 MAX_RX_PACKET_DESC_COUNT
);
2680 bcm5700_freemem(struct net_device
*dev
)
2683 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)dev
->priv
;
2684 LM_DEVICE_BLOCK
*pDevice
= &pUmDevice
->lm_dev
;
2686 for (i
= 0; i
< pUmDevice
->mem_list_num
; i
++) {
2687 if (pUmDevice
->mem_size_list
[i
] == 0) {
2688 kfree(pUmDevice
->mem_list
[i
]);
2691 pci_free_consistent(pUmDevice
->pdev
,
2692 (size_t) pUmDevice
->mem_size_list
[i
],
2693 pUmDevice
->mem_list
[i
],
2694 pUmDevice
->dma_list
[i
]);
2698 pDevice
->pStatusBlkVirt
= 0;
2699 pDevice
->pStatsBlkVirt
= 0;
2700 pUmDevice
->mem_list_num
= 0;
2706 bcm5700_crc_count(PUM_DEVICE_BLOCK pUmDevice
)
2708 PLM_DEVICE_BLOCK pDevice
= &pUmDevice
->lm_dev
;
2710 PT3_STATS_BLOCK pStats
= (PT3_STATS_BLOCK
) pDevice
->pStatsBlkVirt
;
2711 unsigned long flags
;
2713 if ((T3_ASIC_REV(pDevice
->ChipRevId
) == T3_ASIC_REV_5700
||
2714 T3_ASIC_REV(pDevice
->ChipRevId
) == T3_ASIC_REV_5701
) &&
2715 !(pDevice
->TbiFlags
& ENABLE_TBI_FLAG
)) {
2717 if (!pUmDevice
->opened
|| !pDevice
->InitDone
)
2723 /* regulate MDIO access during run time */
2724 if (pUmDevice
->crc_counter_expiry
> 0)
2725 return pUmDevice
->phy_crc_count
;
2727 pUmDevice
->crc_counter_expiry
= (5 * HZ
) /
2728 pUmDevice
->timer_interval
;
2730 BCM5700_PHY_LOCK(pUmDevice
, flags
);
2731 LM_ReadPhy(pDevice
, 0x1e, &Value32
);
2732 if ((Value32
& 0x8000) == 0)
2733 LM_WritePhy(pDevice
, 0x1e, Value32
| 0x8000);
2734 LM_ReadPhy(pDevice
, 0x14, &Value32
);
2735 BCM5700_PHY_UNLOCK(pUmDevice
, flags
);
2736 /* Sometimes data on the MDIO bus can be corrupted */
2737 if (Value32
!= 0xffff)
2738 pUmDevice
->phy_crc_count
+= Value32
;
2739 return pUmDevice
->phy_crc_count
;
2741 else if (pStats
== 0) {
2745 return (MM_GETSTATS64(pStats
->dot3StatsFCSErrors
));
2750 bcm5700_rx_err_count(UM_DEVICE_BLOCK
*pUmDevice
)
2752 LM_DEVICE_BLOCK
*pDevice
= &pUmDevice
->lm_dev
;
2753 T3_STATS_BLOCK
*pStats
= (T3_STATS_BLOCK
*) pDevice
->pStatsBlkVirt
;
2757 return (bcm5700_crc_count(pUmDevice
) +
2758 MM_GETSTATS64(pStats
->dot3StatsAlignmentErrors
) +
2759 MM_GETSTATS64(pStats
->etherStatsUndersizePkts
) +
2760 MM_GETSTATS64(pStats
->etherStatsFragments
) +
2761 MM_GETSTATS64(pStats
->dot3StatsFramesTooLong
) +
2762 MM_GETSTATS64(pStats
->etherStatsJabbers
));
2765 STATIC
struct net_device_stats
*
2766 bcm5700_get_stats(struct net_device
*dev
)
2768 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)dev
->priv
;
2769 PLM_DEVICE_BLOCK pDevice
= (PLM_DEVICE_BLOCK
) pUmDevice
;
2770 PT3_STATS_BLOCK pStats
= (PT3_STATS_BLOCK
) pDevice
->pStatsBlkVirt
;
2771 struct net_device_stats
*p_netstats
= &pUmDevice
->stats
;
2776 /* Get stats from LM */
2777 p_netstats
->rx_packets
=
2778 MM_GETSTATS(pStats
->ifHCInUcastPkts
) +
2779 MM_GETSTATS(pStats
->ifHCInMulticastPkts
) +
2780 MM_GETSTATS(pStats
->ifHCInBroadcastPkts
);
2781 p_netstats
->tx_packets
=
2782 MM_GETSTATS(pStats
->ifHCOutUcastPkts
) +
2783 MM_GETSTATS(pStats
->ifHCOutMulticastPkts
) +
2784 MM_GETSTATS(pStats
->ifHCOutBroadcastPkts
);
2785 /* There counters seem to be innacurate. Use byte number accumulation
2787 p_netstats->rx_bytes = MM_GETSTATS(pStats->ifHCInOctets);
2788 p_netstats->tx_bytes = MM_GETSTATS(pStats->ifHCOutOctets);
2790 p_netstats
->tx_errors
=
2791 MM_GETSTATS(pStats
->dot3StatsInternalMacTransmitErrors
) +
2792 MM_GETSTATS(pStats
->dot3StatsCarrierSenseErrors
) +
2793 MM_GETSTATS(pStats
->ifOutDiscards
) +
2794 MM_GETSTATS(pStats
->ifOutErrors
);
2795 p_netstats
->multicast
= MM_GETSTATS(pStats
->ifHCInMulticastPkts
);
2796 p_netstats
->collisions
= MM_GETSTATS(pStats
->etherStatsCollisions
);
2797 p_netstats
->rx_length_errors
=
2798 MM_GETSTATS(pStats
->dot3StatsFramesTooLong
) +
2799 MM_GETSTATS(pStats
->etherStatsUndersizePkts
);
2800 p_netstats
->rx_over_errors
= MM_GETSTATS(pStats
->nicNoMoreRxBDs
);
2801 p_netstats
->rx_frame_errors
=
2802 MM_GETSTATS(pStats
->dot3StatsAlignmentErrors
);
2803 p_netstats
->rx_crc_errors
= (unsigned long)
2804 bcm5700_crc_count(pUmDevice
);
2805 p_netstats
->rx_errors
= (unsigned long)
2806 bcm5700_rx_err_count(pUmDevice
);
2808 p_netstats
->tx_aborted_errors
= MM_GETSTATS(pStats
->ifOutDiscards
);
2809 p_netstats
->tx_carrier_errors
=
2810 MM_GETSTATS(pStats
->dot3StatsCarrierSenseErrors
);
2816 b57_suspend_chip(UM_DEVICE_BLOCK
*pUmDevice
)
2818 LM_DEVICE_BLOCK
*pDevice
= &pUmDevice
->lm_dev
;
2820 if (pUmDevice
->opened
) {
2821 bcm5700_intr_off(pUmDevice
);
2822 netif_carrier_off(pUmDevice
->dev
);
2823 netif_stop_queue(pUmDevice
->dev
);
2825 tasklet_kill(&pUmDevice
->tasklet
);
2827 bcm5700_poll_wait(pUmDevice
);
2829 pUmDevice
->suspended
= 1;
2830 LM_ShutdownChip(pDevice
, LM_SUSPEND_RESET
);
2834 b57_resume_chip(UM_DEVICE_BLOCK
*pUmDevice
)
2836 LM_DEVICE_BLOCK
*pDevice
= &pUmDevice
->lm_dev
;
2838 if (pUmDevice
->suspended
) {
2839 pUmDevice
->suspended
= 0;
2840 if (pUmDevice
->opened
) {
2841 bcm5700_reset(pUmDevice
->dev
);
2844 LM_ShutdownChip(pDevice
, LM_SHUTDOWN_RESET
);
2849 /* Returns 0 on failure, 1 on success */
2851 b57_test_intr(UM_DEVICE_BLOCK
*pUmDevice
)
2853 LM_DEVICE_BLOCK
*pDevice
= &pUmDevice
->lm_dev
;
2856 if (!pUmDevice
->opened
)
2858 pUmDevice
->intr_test_result
= 0;
2859 pUmDevice
->intr_test
= 1;
2861 REG_WR(pDevice
, HostCoalesce
.Mode
,
2862 pDevice
->CoalesceMode
| HOST_COALESCE_ENABLE
|
2865 for (j
= 0; j
< 10; j
++) {
2866 if (pUmDevice
->intr_test_result
){
2870 REG_WR(pDevice
, HostCoalesce
.Mode
,
2871 pDevice
->CoalesceMode
| HOST_COALESCE_ENABLE
|
2874 MM_Sleep(pDevice
, 1);
2877 return pUmDevice
->intr_test_result
;
2883 #ifdef ETHTOOL_GSTRINGS
2885 #define ETH_NUM_STATS 30
2886 #define RX_CRC_IDX 5
2887 #define RX_MAC_ERR_IDX 14
2890 char string
[ETH_GSTRING_LEN
];
2891 } bcm5700_stats_str_arr
[ETH_NUM_STATS
] = {
2892 { "rx_unicast_packets" },
2893 { "rx_multicast_packets" },
2894 { "rx_broadcast_packets" },
2897 { "rx_crc_errors" }, /* this needs to be calculated */
2898 { "rx_align_errors" },
2899 { "rx_xon_frames" },
2900 { "rx_xoff_frames" },
2901 { "rx_long_frames" },
2902 { "rx_short_frames" },
2906 { "rx_mac_errors" }, /* this needs to be calculated */
2907 { "tx_unicast_packets" },
2908 { "tx_multicast_packets" },
2909 { "tx_broadcast_packets" },
2912 { "tx_single_collisions" },
2913 { "tx_multi_collisions" },
2914 { "tx_total_collisions" },
2915 { "tx_excess_collisions" },
2916 { "tx_late_collisions" },
2917 { "tx_xon_frames" },
2918 { "tx_xoff_frames" },
2919 { "tx_internal_mac_errors" },
2920 { "tx_carrier_errors" },
2924 #define STATS_OFFSET(offset_name) ((OFFSETOF(T3_STATS_BLOCK, offset_name)) / sizeof(uint64_t))
2927 #define SWAP_DWORD_64(x) (x)
2929 #define SWAP_DWORD_64(x) ((x << 32) | (x >> 32))
2932 unsigned long bcm5700_stats_offset_arr
[ETH_NUM_STATS
] = {
2933 STATS_OFFSET(ifHCInUcastPkts
),
2934 STATS_OFFSET(ifHCInMulticastPkts
),
2935 STATS_OFFSET(ifHCInBroadcastPkts
),
2936 STATS_OFFSET(ifHCInOctets
),
2937 STATS_OFFSET(etherStatsFragments
),
2939 STATS_OFFSET(dot3StatsAlignmentErrors
),
2940 STATS_OFFSET(xonPauseFramesReceived
),
2941 STATS_OFFSET(xoffPauseFramesReceived
),
2942 STATS_OFFSET(dot3StatsFramesTooLong
),
2943 STATS_OFFSET(etherStatsUndersizePkts
),
2944 STATS_OFFSET(etherStatsJabbers
),
2945 STATS_OFFSET(ifInDiscards
),
2946 STATS_OFFSET(ifInErrors
),
2948 STATS_OFFSET(ifHCOutUcastPkts
),
2949 STATS_OFFSET(ifHCOutMulticastPkts
),
2950 STATS_OFFSET(ifHCOutBroadcastPkts
),
2951 STATS_OFFSET(ifHCOutOctets
),
2952 STATS_OFFSET(dot3StatsDeferredTransmissions
),
2953 STATS_OFFSET(dot3StatsSingleCollisionFrames
),
2954 STATS_OFFSET(dot3StatsMultipleCollisionFrames
),
2955 STATS_OFFSET(etherStatsCollisions
),
2956 STATS_OFFSET(dot3StatsExcessiveCollisions
),
2957 STATS_OFFSET(dot3StatsLateCollisions
),
2958 STATS_OFFSET(outXonSent
),
2959 STATS_OFFSET(outXoffSent
),
2960 STATS_OFFSET(dot3StatsInternalMacTransmitErrors
),
2961 STATS_OFFSET(dot3StatsCarrierSenseErrors
),
2962 STATS_OFFSET(ifOutErrors
),
2965 #endif /* ETHTOOL_GSTRINGS */
2968 #ifdef ETHTOOL_GREGS
2969 #if (LINUX_VERSION_CODE >= 0x02040f)
2971 bcm5700_get_reg_blk(UM_DEVICE_BLOCK
*pUmDevice
, u32
**buf
, u32 start
, u32 end
,
2975 LM_DEVICE_BLOCK
*pDevice
= &pUmDevice
->lm_dev
;
2978 memset(*buf
, 0, end
- start
);
2979 *buf
= *buf
+ (end
- start
)/4;
2982 for (offset
= start
; offset
< end
; offset
+=4, *buf
= *buf
+ 1) {
2983 if (T3_ASIC_IS_5705_BEYOND(pDevice
->ChipRevId
)){
2984 if (((offset
>= 0x3400) && (offset
< 0x3c00)) ||
2985 ((offset
>= 0x5400) && (offset
< 0x5800)) ||
2986 ((offset
>= 0x6400) && (offset
< 0x6800))) {
2991 **buf
= REG_RD_OFFSET(pDevice
, offset
);
2997 static int netdev_ethtool_ioctl(struct net_device
*dev
, void *useraddr
)
2999 struct ethtool_cmd ethcmd
;
3000 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)dev
->priv
;
3001 PLM_DEVICE_BLOCK pDevice
= (PLM_DEVICE_BLOCK
) pUmDevice
;
3003 if (mm_copy_from_user(ðcmd
, useraddr
, sizeof(ethcmd
)))
3006 switch (ethcmd
.cmd
) {
3007 #ifdef ETHTOOL_GDRVINFO
3008 case ETHTOOL_GDRVINFO
: {
3009 struct ethtool_drvinfo info
= {ETHTOOL_GDRVINFO
};
3011 strcpy(info
.driver
, bcm5700_driver
);
3012 #ifdef INCLUDE_5701_AX_FIX
3013 if(pDevice
->ChipRevId
== T3_CHIP_ID_5701_A0
) {
3014 extern int t3FwReleaseMajor
;
3015 extern int t3FwReleaseMinor
;
3016 extern int t3FwReleaseFix
;
3018 sprintf(info
.fw_version
, "%i.%i.%i",
3019 t3FwReleaseMajor
, t3FwReleaseMinor
,
3023 strcpy(info
.fw_version
, pDevice
->BootCodeVer
);
3024 strcpy(info
.version
, bcm5700_version
);
3025 #if (LINUX_VERSION_CODE <= 0x020422)
3026 strcpy(info
.bus_info
, pUmDevice
->pdev
->slot_name
);
3028 strcpy(info
.bus_info
, pci_name(pUmDevice
->pdev
));
3033 #ifdef ETHTOOL_GEEPROM
3034 BCM_EEDUMP_LEN(&info
, pDevice
->NvramSize
);
3036 #ifdef ETHTOOL_GREGS
3037 /* dump everything, including holes in the register space */
3038 info
.regdump_len
= 0x6c00;
3040 #ifdef ETHTOOL_GSTATS
3041 info
.n_stats
= ETH_NUM_STATS
;
3043 if (mm_copy_to_user(useraddr
, &info
, sizeof(info
)))
3048 case ETHTOOL_GSET
: {
3049 if ((pDevice
->TbiFlags
& ENABLE_TBI_FLAG
)||
3050 (pDevice
->PhyFlags
& PHY_IS_FIBER
)) {
3052 (SUPPORTED_1000baseT_Full
|
3054 ethcmd
.supported
|= SUPPORTED_FIBRE
;
3055 ethcmd
.port
= PORT_FIBRE
;
3058 (SUPPORTED_10baseT_Half
|
3059 SUPPORTED_10baseT_Full
|
3060 SUPPORTED_100baseT_Half
|
3061 SUPPORTED_100baseT_Full
|
3062 SUPPORTED_1000baseT_Half
|
3063 SUPPORTED_1000baseT_Full
|
3065 ethcmd
.supported
|= SUPPORTED_TP
;
3066 ethcmd
.port
= PORT_TP
;
3069 ethcmd
.transceiver
= XCVR_INTERNAL
;
3070 ethcmd
.phy_address
= 0;
3072 if (pDevice
->LineSpeed
== LM_LINE_SPEED_1000MBPS
)
3073 ethcmd
.speed
= SPEED_1000
;
3074 else if (pDevice
->LineSpeed
== LM_LINE_SPEED_100MBPS
)
3075 ethcmd
.speed
= SPEED_100
;
3076 else if (pDevice
->LineSpeed
== LM_LINE_SPEED_10MBPS
)
3077 ethcmd
.speed
= SPEED_10
;
3081 if (pDevice
->DuplexMode
== LM_DUPLEX_MODE_FULL
)
3082 ethcmd
.duplex
= DUPLEX_FULL
;
3084 ethcmd
.duplex
= DUPLEX_HALF
;
3086 if (pDevice
->DisableAutoNeg
== FALSE
) {
3087 ethcmd
.autoneg
= AUTONEG_ENABLE
;
3088 ethcmd
.advertising
= ADVERTISED_Autoneg
;
3089 if ((pDevice
->TbiFlags
& ENABLE_TBI_FLAG
) ||
3090 (pDevice
->PhyFlags
& PHY_IS_FIBER
)) {
3091 ethcmd
.advertising
|=
3092 ADVERTISED_1000baseT_Full
|
3096 ethcmd
.advertising
|=
3098 if (pDevice
->advertising
&
3099 PHY_AN_AD_10BASET_HALF
) {
3101 ethcmd
.advertising
|=
3102 ADVERTISED_10baseT_Half
;
3104 if (pDevice
->advertising
&
3105 PHY_AN_AD_10BASET_FULL
) {
3107 ethcmd
.advertising
|=
3108 ADVERTISED_10baseT_Full
;
3110 if (pDevice
->advertising
&
3111 PHY_AN_AD_100BASETX_HALF
) {
3113 ethcmd
.advertising
|=
3114 ADVERTISED_100baseT_Half
;
3116 if (pDevice
->advertising
&
3117 PHY_AN_AD_100BASETX_FULL
) {
3119 ethcmd
.advertising
|=
3120 ADVERTISED_100baseT_Full
;
3122 if (pDevice
->advertising1000
&
3123 BCM540X_AN_AD_1000BASET_HALF
) {
3125 ethcmd
.advertising
|=
3126 ADVERTISED_1000baseT_Half
;
3128 if (pDevice
->advertising1000
&
3129 BCM540X_AN_AD_1000BASET_FULL
) {
3131 ethcmd
.advertising
|=
3132 ADVERTISED_1000baseT_Full
;
3137 ethcmd
.autoneg
= AUTONEG_DISABLE
;
3138 ethcmd
.advertising
= 0;
3141 ethcmd
.maxtxpkt
= pDevice
->TxMaxCoalescedFrames
;
3142 ethcmd
.maxrxpkt
= pDevice
->RxMaxCoalescedFrames
;
3144 if(mm_copy_to_user(useraddr
, ðcmd
, sizeof(ethcmd
)))
3148 case ETHTOOL_SSET
: {
3149 unsigned long flags
;
3151 if(!capable(CAP_NET_ADMIN
))
3153 if (ethcmd
.autoneg
== AUTONEG_ENABLE
) {
3154 pDevice
->RequestedLineSpeed
= LM_LINE_SPEED_AUTO
;
3155 pDevice
->RequestedDuplexMode
= LM_DUPLEX_MODE_UNKNOWN
;
3156 pDevice
->DisableAutoNeg
= FALSE
;
3159 if (ethcmd
.speed
== SPEED_1000
&&
3160 pDevice
->PhyFlags
& PHY_NO_GIGABIT
)
3163 if (ethcmd
.speed
== SPEED_1000
&&
3164 (pDevice
->TbiFlags
& ENABLE_TBI_FLAG
||
3165 pDevice
->PhyFlags
& PHY_IS_FIBER
) ) {
3167 pDevice
->RequestedLineSpeed
=
3168 LM_LINE_SPEED_1000MBPS
;
3170 pDevice
->RequestedDuplexMode
=
3171 LM_DUPLEX_MODE_FULL
;
3173 else if (ethcmd
.speed
== SPEED_100
&&
3174 !(pDevice
->TbiFlags
& ENABLE_TBI_FLAG
) &&
3175 !(pDevice
->PhyFlags
& PHY_IS_FIBER
)) {
3177 pDevice
->RequestedLineSpeed
=
3178 LM_LINE_SPEED_100MBPS
;
3180 else if (ethcmd
.speed
== SPEED_10
&&
3181 !(pDevice
->TbiFlags
& ENABLE_TBI_FLAG
) &&
3182 !(pDevice
->PhyFlags
& PHY_IS_FIBER
)) {
3184 pDevice
->RequestedLineSpeed
=
3185 LM_LINE_SPEED_10MBPS
;
3191 pDevice
->DisableAutoNeg
= TRUE
;
3192 if (ethcmd
.duplex
== DUPLEX_FULL
) {
3193 pDevice
->RequestedDuplexMode
=
3194 LM_DUPLEX_MODE_FULL
;
3197 if (!(pDevice
->TbiFlags
& ENABLE_TBI_FLAG
) &&
3198 !(pDevice
->PhyFlags
& PHY_IS_FIBER
) ) {
3200 pDevice
->RequestedDuplexMode
=
3201 LM_DUPLEX_MODE_HALF
;
3205 if (netif_running(dev
)) {
3206 BCM5700_PHY_LOCK(pUmDevice
, flags
);
3207 LM_SetupPhy(pDevice
);
3208 BCM5700_PHY_UNLOCK(pUmDevice
, flags
);
3214 case ETHTOOL_GWOL
: {
3215 struct ethtool_wolinfo wol
= {ETHTOOL_GWOL
};
3217 if (((pDevice
->TbiFlags
& ENABLE_TBI_FLAG
) &&
3218 !(pDevice
->Flags
& FIBER_WOL_CAPABLE_FLAG
)) ||
3219 (pDevice
->Flags
& DISABLE_D3HOT_FLAG
)) {
3224 wol
.supported
= WAKE_MAGIC
;
3225 if (pDevice
->WakeUpMode
== LM_WAKE_UP_MODE_MAGIC_PACKET
)
3227 wol
.wolopts
= WAKE_MAGIC
;
3233 if (mm_copy_to_user(useraddr
, &wol
, sizeof(wol
)))
3237 case ETHTOOL_SWOL
: {
3238 struct ethtool_wolinfo wol
;
3240 if(!capable(CAP_NET_ADMIN
))
3242 if (mm_copy_from_user(&wol
, useraddr
, sizeof(wol
)))
3244 if ((((pDevice
->TbiFlags
& ENABLE_TBI_FLAG
) &&
3245 !(pDevice
->Flags
& FIBER_WOL_CAPABLE_FLAG
)) ||
3246 (pDevice
->Flags
& DISABLE_D3HOT_FLAG
)) &&
3251 if ((wol
.wolopts
& ~WAKE_MAGIC
) != 0) {
3254 if (wol
.wolopts
& WAKE_MAGIC
) {
3255 pDevice
->WakeUpModeCap
= LM_WAKE_UP_MODE_MAGIC_PACKET
;
3256 pDevice
->WakeUpMode
= LM_WAKE_UP_MODE_MAGIC_PACKET
;
3259 pDevice
->WakeUpModeCap
= LM_WAKE_UP_MODE_NONE
;
3260 pDevice
->WakeUpMode
= LM_WAKE_UP_MODE_NONE
;
3266 #ifdef ETHTOOL_GLINK
3267 case ETHTOOL_GLINK
: {
3268 struct ethtool_value edata
= {ETHTOOL_GLINK
};
3270 /* ifup only waits for 5 seconds for link up */
3271 /* NIC may take more than 5 seconds to establish link */
3272 if ((pUmDevice
->delayed_link_ind
> 0) &&
3273 delay_link
[pUmDevice
->index
])
3276 if (pDevice
->LinkStatus
== LM_STATUS_LINK_ACTIVE
) {
3282 if (mm_copy_to_user(useraddr
, &edata
, sizeof(edata
)))
3287 #ifdef ETHTOOL_NWAY_RST
3288 case ETHTOOL_NWAY_RST
: {
3290 unsigned long flags
;
3292 if(!capable(CAP_NET_ADMIN
))
3294 if (pDevice
->DisableAutoNeg
) {
3297 if (!netif_running(dev
))
3299 BCM5700_PHY_LOCK(pUmDevice
, flags
);
3300 if (pDevice
->TbiFlags
& ENABLE_TBI_FLAG
) {
3301 pDevice
->RequestedLineSpeed
= LM_LINE_SPEED_1000MBPS
;
3302 pDevice
->DisableAutoNeg
= TRUE
;
3303 LM_SetupPhy(pDevice
);
3305 pDevice
->RequestedLineSpeed
= LM_LINE_SPEED_AUTO
;
3306 pDevice
->DisableAutoNeg
= FALSE
;
3307 LM_SetupPhy(pDevice
);
3310 if ((T3_ASIC_REV(pDevice
->ChipRevId
) ==
3311 T3_ASIC_REV_5703
) ||
3312 (T3_ASIC_REV(pDevice
->ChipRevId
) ==
3313 T3_ASIC_REV_5704
) ||
3314 (T3_ASIC_REV(pDevice
->ChipRevId
) ==
3317 LM_ResetPhy(pDevice
);
3318 LM_SetupPhy(pDevice
);
3320 pDevice
->PhyFlags
&= ~PHY_FIBER_FALLBACK
;
3321 LM_ReadPhy(pDevice
, PHY_CTRL_REG
, &phyctrl
);
3322 LM_WritePhy(pDevice
, PHY_CTRL_REG
, phyctrl
|
3323 PHY_CTRL_AUTO_NEG_ENABLE
|
3324 PHY_CTRL_RESTART_AUTO_NEG
);
3326 BCM5700_PHY_UNLOCK(pUmDevice
, flags
);
3330 #ifdef ETHTOOL_GEEPROM
3331 case ETHTOOL_GEEPROM
: {
3332 struct ethtool_eeprom eeprom
;
3334 LM_UINT32 buf1
[64/4];
3335 int i
, j
, offset
, len
;
3337 if (mm_copy_from_user(&eeprom
, useraddr
, sizeof(eeprom
)))
3340 if (eeprom
.offset
>= pDevice
->NvramSize
)
3343 /* maximum data limited */
3344 /* to read more, call again with a different offset */
3345 if (eeprom
.len
> 0x800) {
3347 if (mm_copy_to_user(useraddr
, &eeprom
, sizeof(eeprom
)))
3351 if (eeprom
.len
> 64) {
3352 buf
= kmalloc(eeprom
.len
, GFP_KERNEL
);
3359 useraddr
+= offsetof(struct ethtool_eeprom
, data
);
3361 offset
= eeprom
.offset
;
3364 offset
&= 0xfffffffc;
3365 len
+= (offset
& 3);
3367 len
= (len
+ 3) & 0xfffffffc;
3368 for (i
= 0, j
= 0; j
< len
; i
++, j
+= 4) {
3369 if (LM_NvramRead(pDevice
, offset
+ j
, buf
+ i
) !=
3370 LM_STATUS_SUCCESS
) {
3375 buf
+= (eeprom
.offset
& 3);
3376 i
= mm_copy_to_user(useraddr
, buf
, eeprom
.len
);
3378 if (eeprom
.len
> 64) {
3385 case ETHTOOL_SEEPROM
: {
3386 struct ethtool_eeprom eeprom
;
3387 LM_UINT32 buf
[64/4];
3390 if(!capable(CAP_NET_ADMIN
))
3392 if (mm_copy_from_user(&eeprom
, useraddr
, sizeof(eeprom
)))
3395 if ((eeprom
.offset
& 3) || (eeprom
.len
& 3) ||
3396 (eeprom
.offset
>= pDevice
->NvramSize
)) {
3400 if ((eeprom
.offset
+ eeprom
.len
) >= pDevice
->NvramSize
) {
3401 eeprom
.len
= pDevice
->NvramSize
- eeprom
.offset
;
3404 useraddr
+= offsetof(struct ethtool_eeprom
, data
);
3407 offset
= eeprom
.offset
;
3413 if (mm_copy_from_user(&buf
, useraddr
, i
))
3416 bcm5700_intr_off(pUmDevice
);
3417 /* Prevent race condition on Grc.Mode register */
3418 bcm5700_poll_wait(pUmDevice
);
3420 if (LM_NvramWriteBlock(pDevice
, offset
, buf
, i
/4) !=
3421 LM_STATUS_SUCCESS
) {
3422 bcm5700_intr_on(pUmDevice
);
3425 bcm5700_intr_on(pUmDevice
);
3433 #ifdef ETHTOOL_GREGS
3434 #if (LINUX_VERSION_CODE >= 0x02040f)
3435 case ETHTOOL_GREGS
: {
3436 struct ethtool_regs eregs
;
3437 LM_UINT32
*buf
, *buf1
;
3440 if(!capable(CAP_NET_ADMIN
))
3442 if (pDevice
->Flags
& UNDI_FIX_FLAG
)
3444 if (mm_copy_from_user(&eregs
, useraddr
, sizeof(eregs
)))
3446 if (eregs
.len
> 0x6c00)
3448 eregs
.version
= 0x0;
3449 if (mm_copy_to_user(useraddr
, &eregs
, sizeof(eregs
)))
3451 buf
= buf1
= kmalloc(eregs
.len
, GFP_KERNEL
);
3454 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0, 0xb0, 0);
3455 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0xb0, 0x200, 1);
3456 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x200, 0x8f0, 0);
3457 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x8f0, 0xc00, 1);
3458 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0xc00, 0xce0, 0);
3459 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0xce0, 0x1000, 1);
3460 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x1000, 0x1004, 0);
3461 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x1004, 0x1400, 1);
3462 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x1400, 0x1480, 0);
3463 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x1480, 0x1800, 1);
3464 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x1800, 0x1848, 0);
3465 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x1848, 0x1c00, 1);
3466 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x1c00, 0x1c04, 0);
3467 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x1c04, 0x2000, 1);
3468 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x2000, 0x225c, 0);
3469 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x225c, 0x2400, 1);
3470 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x2400, 0x24c4, 0);
3471 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x24c4, 0x2800, 1);
3472 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x2800, 0x2804, 0);
3473 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x2804, 0x2c00, 1);
3474 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x2c00, 0x2c20, 0);
3475 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x2c20, 0x3000, 1);
3476 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x3000, 0x3014, 0);
3477 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x3014, 0x3400, 1);
3478 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x3400, 0x3408, 0);
3479 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x3408, 0x3800, 1);
3480 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x3800, 0x3808, 0);
3481 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x3808, 0x3c00, 1);
3482 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x3c00, 0x3d00, 0);
3483 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x3d00, 0x4000, 1);
3484 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x4000, 0x4010, 0);
3485 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x4010, 0x4400, 1);
3486 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x4400, 0x4458, 0);
3487 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x4458, 0x4800, 1);
3488 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x4800, 0x4808, 0);
3489 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x4808, 0x4c00, 1);
3490 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x4c00, 0x4c08, 0);
3491 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x4c08, 0x5000, 1);
3492 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x5000, 0x5050, 0);
3493 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x5050, 0x5400, 1);
3494 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x5400, 0x5450, 0);
3495 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x5450, 0x5800, 1);
3496 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x5800, 0x5a10, 0);
3497 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x5a10, 0x6000, 1);
3498 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x6000, 0x600c, 0);
3499 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x600c, 0x6400, 1);
3500 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x6400, 0x6404, 0);
3501 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x6404, 0x6800, 1);
3502 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x6800, 0x6848, 0);
3503 bcm5700_get_reg_blk(pUmDevice
, &buf
, 0x6848, 0x6c00, 1);
3505 i
= mm_copy_to_user(useraddr
+ sizeof(eregs
), buf1
, eregs
.len
);
3513 #ifdef ETHTOOL_GPAUSEPARAM
3514 case ETHTOOL_GPAUSEPARAM
: {
3515 struct ethtool_pauseparam epause
= { ETHTOOL_GPAUSEPARAM
};
3517 if (!pDevice
->DisableAutoNeg
) {
3518 epause
.autoneg
= (pDevice
->FlowControlCap
&
3519 LM_FLOW_CONTROL_AUTO_PAUSE
) != 0;
3525 (pDevice
->FlowControl
&
3526 LM_FLOW_CONTROL_RECEIVE_PAUSE
) != 0;
3528 (pDevice
->FlowControl
&
3529 LM_FLOW_CONTROL_TRANSMIT_PAUSE
) != 0;
3530 if (mm_copy_to_user(useraddr
, &epause
, sizeof(epause
)))
3535 case ETHTOOL_SPAUSEPARAM
: {
3536 struct ethtool_pauseparam epause
;
3537 unsigned long flags
;
3539 if(!capable(CAP_NET_ADMIN
))
3541 if (mm_copy_from_user(&epause
, useraddr
, sizeof(epause
)))
3543 pDevice
->FlowControlCap
= 0;
3544 if (epause
.autoneg
&& !pDevice
->DisableAutoNeg
) {
3545 pDevice
->FlowControlCap
|= LM_FLOW_CONTROL_AUTO_PAUSE
;
3547 if (epause
.rx_pause
) {
3548 pDevice
->FlowControlCap
|=
3549 LM_FLOW_CONTROL_RECEIVE_PAUSE
;
3551 if (epause
.tx_pause
) {
3552 pDevice
->FlowControlCap
|=
3553 LM_FLOW_CONTROL_TRANSMIT_PAUSE
;
3555 if (netif_running(dev
)) {
3556 BCM5700_PHY_LOCK(pUmDevice
, flags
);
3557 LM_SetupPhy(pDevice
);
3558 BCM5700_PHY_UNLOCK(pUmDevice
, flags
);
3564 #ifdef ETHTOOL_GRXCSUM
3565 case ETHTOOL_GRXCSUM
: {
3566 struct ethtool_value edata
= { ETHTOOL_GRXCSUM
};
3569 (pDevice
->TaskToOffload
&
3570 LM_TASK_OFFLOAD_RX_TCP_CHECKSUM
) != 0;
3571 if (mm_copy_to_user(useraddr
, &edata
, sizeof(edata
)))
3576 case ETHTOOL_SRXCSUM
: {
3577 struct ethtool_value edata
;
3579 if(!capable(CAP_NET_ADMIN
))
3581 if (mm_copy_from_user(&edata
, useraddr
, sizeof(edata
)))
3584 if (!(pDevice
->TaskOffloadCap
&
3585 LM_TASK_OFFLOAD_TX_TCP_CHECKSUM
)) {
3589 pDevice
->TaskToOffload
|=
3590 LM_TASK_OFFLOAD_RX_TCP_CHECKSUM
|
3591 LM_TASK_OFFLOAD_RX_UDP_CHECKSUM
;
3594 pDevice
->TaskToOffload
&=
3595 ~(LM_TASK_OFFLOAD_RX_TCP_CHECKSUM
|
3596 LM_TASK_OFFLOAD_RX_UDP_CHECKSUM
);
3600 case ETHTOOL_GTXCSUM
: {
3601 struct ethtool_value edata
= { ETHTOOL_GTXCSUM
};
3604 (dev
->features
& get_csum_flag( pDevice
->ChipRevId
)) != 0;
3605 if (mm_copy_to_user(useraddr
, &edata
, sizeof(edata
)))
3610 case ETHTOOL_STXCSUM
: {
3611 struct ethtool_value edata
;
3613 if(!capable(CAP_NET_ADMIN
))
3615 if (mm_copy_from_user(&edata
, useraddr
, sizeof(edata
)))
3618 if (!(pDevice
->TaskOffloadCap
&
3619 LM_TASK_OFFLOAD_TX_TCP_CHECKSUM
)) {
3623 dev
->features
|= get_csum_flag( pDevice
->ChipRevId
);
3624 pDevice
->TaskToOffload
|=
3625 LM_TASK_OFFLOAD_TX_TCP_CHECKSUM
|
3626 LM_TASK_OFFLOAD_TX_UDP_CHECKSUM
;
3629 dev
->features
&= ~get_csum_flag( pDevice
->ChipRevId
);
3630 pDevice
->TaskToOffload
&=
3631 ~(LM_TASK_OFFLOAD_TX_TCP_CHECKSUM
|
3632 LM_TASK_OFFLOAD_TX_UDP_CHECKSUM
);
3637 struct ethtool_value edata
= { ETHTOOL_GSG
};
3640 (dev
->features
& NETIF_F_SG
) != 0;
3641 if (mm_copy_to_user(useraddr
, &edata
, sizeof(edata
)))
3646 struct ethtool_value edata
;
3648 if(!capable(CAP_NET_ADMIN
))
3650 if (mm_copy_from_user(&edata
, useraddr
, sizeof(edata
)))
3653 dev
->features
|= NETIF_F_SG
;
3656 dev
->features
&= ~NETIF_F_SG
;
3661 #ifdef ETHTOOL_GRINGPARAM
3662 case ETHTOOL_GRINGPARAM
: {
3663 struct ethtool_ringparam ering
= { ETHTOOL_GRINGPARAM
};
3665 ering
.rx_max_pending
= T3_STD_RCV_RCB_ENTRY_COUNT
- 1;
3666 ering
.rx_pending
= pDevice
->RxStdDescCnt
;
3667 ering
.rx_mini_max_pending
= 0;
3668 ering
.rx_mini_pending
= 0;
3669 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
3670 ering
.rx_jumbo_max_pending
= T3_JUMBO_RCV_RCB_ENTRY_COUNT
- 1;
3671 ering
.rx_jumbo_pending
= pDevice
->RxJumboDescCnt
;
3673 ering
.rx_jumbo_max_pending
= 0;
3674 ering
.rx_jumbo_pending
= 0;
3676 ering
.tx_max_pending
= MAX_TX_PACKET_DESC_COUNT
- 1;
3677 ering
.tx_pending
= pDevice
->TxPacketDescCnt
;
3678 if (mm_copy_to_user(useraddr
, &ering
, sizeof(ering
)))
3683 #ifdef ETHTOOL_PHYS_ID
3684 case ETHTOOL_PHYS_ID
: {
3685 struct ethtool_value edata
;
3687 if(!capable(CAP_NET_ADMIN
))
3689 if (mm_copy_from_user(&edata
, useraddr
, sizeof(edata
)))
3691 if (LM_BlinkLED(pDevice
, edata
.data
) == LM_STATUS_SUCCESS
)
3696 #ifdef ETHTOOL_GSTRINGS
3697 case ETHTOOL_GSTRINGS
: {
3698 struct ethtool_gstrings egstr
= { ETHTOOL_GSTRINGS
};
3700 if (mm_copy_from_user(&egstr
, useraddr
, sizeof(egstr
)))
3702 switch(egstr
.string_set
) {
3703 #ifdef ETHTOOL_GSTATS
3705 egstr
.len
= ETH_NUM_STATS
;
3706 if (mm_copy_to_user(useraddr
, &egstr
, sizeof(egstr
)))
3708 if (mm_copy_to_user(useraddr
+ sizeof(egstr
),
3709 bcm5700_stats_str_arr
,
3710 sizeof(bcm5700_stats_str_arr
)))
3719 #ifdef ETHTOOL_GSTATS
3720 case ETHTOOL_GSTATS
: {
3721 struct ethtool_stats estats
= { ETHTOOL_GSTATS
};
3722 uint64_t stats
[ETH_NUM_STATS
];
3725 (uint64_t *) pDevice
->pStatsBlkVirt
;
3727 estats
.n_stats
= ETH_NUM_STATS
;
3729 memset(stats
, 0, sizeof(stats
));
3733 for (i
= 0; i
< ETH_NUM_STATS
; i
++) {
3734 if (bcm5700_stats_offset_arr
[i
] != 0) {
3735 stats
[i
] = SWAP_DWORD_64(*(pStats
+
3736 bcm5700_stats_offset_arr
[i
]));
3738 else if (i
== RX_CRC_IDX
) {
3740 bcm5700_crc_count(pUmDevice
);
3742 else if (i
== RX_MAC_ERR_IDX
) {
3744 bcm5700_rx_err_count(pUmDevice
);
3748 if (mm_copy_to_user(useraddr
, &estats
, sizeof(estats
))) {
3751 if (mm_copy_to_user(useraddr
+ sizeof(estats
), &stats
,
3759 case ETHTOOL_GTSO
: {
3760 struct ethtool_value edata
= { ETHTOOL_GTSO
};
3764 (dev
->features
& NETIF_F_TSO
) != 0;
3768 if (mm_copy_to_user(useraddr
, &edata
, sizeof(edata
)))
3774 case ETHTOOL_STSO
: {
3776 struct ethtool_value edata
;
3778 if (!capable(CAP_NET_ADMIN
))
3781 if (mm_copy_from_user(&edata
, useraddr
, sizeof(edata
)))
3784 if (!(pDevice
->TaskToOffload
&
3785 LM_TASK_OFFLOAD_TCP_SEGMENTATION
)) {
3789 dev
->features
&= ~NETIF_F_TSO
;
3792 if (T3_ASIC_5714_FAMILY(pDevice
->ChipRevId
) &&
3793 (dev
->mtu
> 1500)) {
3794 printk(KERN_ALERT
"%s: Jumbo Frames and TSO cannot simultaneously be enabled. Jumbo Frames enabled. TSO disabled.\n", dev
->name
);
3797 dev
->features
|= NETIF_F_TSO
;
3810 #endif /* #ifdef SIOCETHTOOL */
3812 #if (LINUX_VERSION_CODE >= 0x20400) && (LINUX_VERSION_CODE < 0x20600)
3813 #include <linux/iobuf.h>
3816 /* Provide ioctl() calls to examine the MII xcvr state. */
3817 STATIC
int bcm5700_ioctl(struct net_device
*dev
, struct ifreq
*rq
, int cmd
)
3819 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)dev
->priv
;
3820 PLM_DEVICE_BLOCK pDevice
= (PLM_DEVICE_BLOCK
) pUmDevice
;
3821 u16
*data
= (u16
*)&rq
->ifr_data
;
3823 u16 page_num
=0, addr_num
=0, len
=0;
3824 unsigned long flags
;
3827 case SIOCGREG_STATUS
: //Get register
3829 struct reg_ioctl_data
*rdata
=(struct reg_ioctl_data
*)rq
->ifr_data
;
3830 robo_info_t
*robo
= (robo_info_t
*)pUmDevice
->robo
;
3831 page_num
= rdata
->page_num
;
3832 addr_num
= rdata
->addr_num
;
3834 printk("b57um SIOCGREG_STATUS cmd page[0x%x]addr[0x%x]len[%d].\n",page_num
,addr_num
,len
);
3837 ReadDataFromRegister(robo
,page_num
,addr_num
,len
,(void *)&rdata
->val_out
);
3838 printk("val[0x%04x-0x%04x-0x%04x].\n",rdata
->val_out
[0],rdata
->val_out
[1],rdata
->val_out
[2]);
3842 ReadDataFromRegister(robo
,page_num
,addr_num
,len
,(void *)&rdata
->val_out
);
3843 printk("val[0x%04x%04x-0x%04x%04x].\n",rdata
->val_out
[0],rdata
->val_out
[1],
3844 rdata
->val_out
[2],rdata
->val_out
[3]);
3848 ReadDataFromRegister(robo
,page_num
,addr_num
,len
,(void *)&rdata
->val_out
);
3849 printk("val[0x%04x%04x].\n",rdata
->val_out
[0],rdata
->val_out
[1]);
3853 ReadDataFromRegister(robo
,page_num
,addr_num
,len
,(void *)&rdata
->val_out
);
3854 printk("val[0x%04x].\n",rdata
->val_out
[0]);
3857 if (mm_copy_to_user(rq
->ifr_data
, rdata
, sizeof(struct reg_ioctl_data
)))
3859 printk("Fail mm_copy_to_user.\n");
3865 case SIOCSREG_STATUS
://Set register
3867 struct reg_ioctl_data
* wdata
=(struct reg_ioctl_data
*)rq
->ifr_data
;
3869 page_num
= wdata
->page_num
;
3870 addr_num
= wdata
->addr_num
;
3871 robo_info_t
*robo
= (robo_info_t
*)pUmDevice
->robo
;
3874 WriteDataToRegister(robo
,page_num
,addr_num
,len
,(void *)&wdata
->val_in
);
3875 //printk("val[0x%04x-0x%04x-0x%04x].\n",val48[0],val48[1],val48[2]);
3879 WriteDataToRegister(robo
,page_num
,addr_num
,len
,(void *)&wdata
->val_in
);
3880 //printk("val[0x%04x-0x%04x-0x%04x-0x%04x].\n",val64[0],val64[1],val64[2],val64[3]);
3884 WriteDataToRegister(robo
,page_num
,addr_num
,len
,(void *)&wdata
->val_in
);
3885 //printk("val[0x%08x].\n",value);
3889 WriteDataToRegister(robo
,page_num
,addr_num
,len
,(void *)&wdata
->val_in
);
3890 //printk("len[%d] val[0x%04x].\n",len,val16);
3897 case SIOCGMIIPHY
: /* Get the address of the PHY in use. */
3899 data
[0] = pDevice
->PhyAddr
;
3904 case SIOCGMIIREG
: /* Read the specified MII register. */
3906 uint32 savephyaddr
= 0;
3908 if (pDevice
->TbiFlags
& ENABLE_TBI_FLAG
)
3911 /* ifup only waits for 5 seconds for link up */
3912 /* NIC may take more than 5 seconds to establish link */
3913 if ((pUmDevice
->delayed_link_ind
> 0) &&
3914 delay_link
[pUmDevice
->index
]) {
3918 BCM5700_PHY_LOCK(pUmDevice
, flags
);
3919 if (data
[0] != 0xffff) {
3920 savephyaddr
= pDevice
->PhyAddr
;
3921 pDevice
->PhyAddr
= data
[0];
3923 LM_ReadPhy(pDevice
, data
[1] & 0x1f, (LM_UINT32
*)&value
);
3924 if (data
[0] != 0xffff)
3925 pDevice
->PhyAddr
= savephyaddr
;
3926 BCM5700_PHY_UNLOCK(pUmDevice
, flags
);
3927 data
[3] = value
& 0xffff;
3933 case SIOCSMIIREG
: /* Write the specified MII register */
3935 uint32 savephyaddr
= 0;
3937 if (!capable(CAP_NET_ADMIN
))
3940 if (pDevice
->TbiFlags
& ENABLE_TBI_FLAG
)
3943 BCM5700_PHY_LOCK(pUmDevice
, flags
);
3944 if (data
[0] != 0xffff) {
3945 savephyaddr
= pDevice
->PhyAddr
;
3946 pDevice
->PhyAddr
= data
[0];
3948 LM_WritePhy(pDevice
, data
[1] & 0x1f, data
[2]);
3949 if (data
[0] != 0xffff)
3950 pDevice
->PhyAddr
= savephyaddr
;
3951 BCM5700_PHY_UNLOCK(pUmDevice
, flags
);
3959 return netdev_ethtool_ioctl(dev
, (void *) rq
->ifr_data
);
3967 STATIC
void bcm5700_do_rx_mode(struct net_device
*dev
)
3969 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)dev
->priv
;
3970 PLM_DEVICE_BLOCK pDevice
= (PLM_DEVICE_BLOCK
) pUmDevice
;
3972 struct dev_mc_list
*mclist
;
3974 LM_MulticastClear(pDevice
);
3975 for (i
= 0, mclist
= dev
->mc_list
; mclist
&& i
< dev
->mc_count
;
3976 i
++, mclist
= mclist
->next
) {
3977 LM_MulticastAdd(pDevice
, (PLM_UINT8
) &mclist
->dmi_addr
);
3979 if (dev
->flags
& IFF_ALLMULTI
) {
3980 if (!(pDevice
->ReceiveMask
& LM_ACCEPT_ALL_MULTICAST
)) {
3981 LM_SetReceiveMask(pDevice
,
3982 pDevice
->ReceiveMask
| LM_ACCEPT_ALL_MULTICAST
);
3985 else if (pDevice
->ReceiveMask
& LM_ACCEPT_ALL_MULTICAST
) {
3986 LM_SetReceiveMask(pDevice
,
3987 pDevice
->ReceiveMask
& ~LM_ACCEPT_ALL_MULTICAST
);
3989 if (dev
->flags
& IFF_PROMISC
) {
3990 if (!(pDevice
->ReceiveMask
& LM_PROMISCUOUS_MODE
)) {
3991 LM_SetReceiveMask(pDevice
,
3992 pDevice
->ReceiveMask
| LM_PROMISCUOUS_MODE
);
3995 else if (pDevice
->ReceiveMask
& LM_PROMISCUOUS_MODE
) {
3996 LM_SetReceiveMask(pDevice
,
3997 pDevice
->ReceiveMask
& ~LM_PROMISCUOUS_MODE
);
4002 STATIC
void bcm5700_set_rx_mode(struct net_device
*dev
)
4004 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)dev
->priv
;
4005 PLM_DEVICE_BLOCK pDevice
= (PLM_DEVICE_BLOCK
) pUmDevice
;
4007 struct dev_mc_list
*mclist
;
4008 unsigned long flags
;
4010 BCM5700_PHY_LOCK(pUmDevice
, flags
);
4012 LM_MulticastClear(pDevice
);
4013 for (i
= 0, mclist
= dev
->mc_list
; mclist
&& i
< dev
->mc_count
;
4014 i
++, mclist
= mclist
->next
) {
4015 LM_MulticastAdd(pDevice
, (PLM_UINT8
) &mclist
->dmi_addr
);
4017 if (dev
->flags
& IFF_ALLMULTI
) {
4018 if (!(pDevice
->ReceiveMask
& LM_ACCEPT_ALL_MULTICAST
)) {
4019 LM_SetReceiveMask(pDevice
,
4020 pDevice
->ReceiveMask
| LM_ACCEPT_ALL_MULTICAST
);
4023 else if (pDevice
->ReceiveMask
& LM_ACCEPT_ALL_MULTICAST
) {
4024 LM_SetReceiveMask(pDevice
,
4025 pDevice
->ReceiveMask
& ~LM_ACCEPT_ALL_MULTICAST
);
4027 if (dev
->flags
& IFF_PROMISC
) {
4028 if (!(pDevice
->ReceiveMask
& LM_PROMISCUOUS_MODE
)) {
4029 LM_SetReceiveMask(pDevice
,
4030 pDevice
->ReceiveMask
| LM_PROMISCUOUS_MODE
);
4033 else if (pDevice
->ReceiveMask
& LM_PROMISCUOUS_MODE
) {
4034 LM_SetReceiveMask(pDevice
,
4035 pDevice
->ReceiveMask
& ~LM_PROMISCUOUS_MODE
);
4038 BCM5700_PHY_UNLOCK(pUmDevice
, flags
);
4042 * Set the hardware MAC address.
4044 STATIC
int bcm5700_set_mac_addr(struct net_device
*dev
, void *p
)
4046 struct sockaddr
*addr
=p
;
4047 PLM_DEVICE_BLOCK pDevice
= (PLM_DEVICE_BLOCK
) dev
->priv
;
4048 UM_DEVICE_BLOCK
*pUmDevice
= (UM_DEVICE_BLOCK
*) pDevice
;
4050 if(is_valid_ether_addr(addr
->sa_data
)){
4052 memcpy(dev
->dev_addr
, addr
->sa_data
,dev
->addr_len
);
4053 if (pUmDevice
->opened
)
4054 LM_SetMacAddress(pDevice
, dev
->dev_addr
);
4055 bcm_robo_set_macaddr(pUmDevice
->robo
, dev
->dev_addr
);
4061 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
4062 STATIC
int bcm5700_change_mtu(struct net_device
*dev
, int new_mtu
)
4064 int pkt_size
= new_mtu
+ ETHERNET_PACKET_HEADER_SIZE
;
4065 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
)dev
->priv
;
4066 PLM_DEVICE_BLOCK pDevice
= &pUmDevice
->lm_dev
;
4067 unsigned long flags
;
4070 if ((pkt_size
< MIN_ETHERNET_PACKET_SIZE_NO_CRC
) ||
4071 (pkt_size
> MAX_ETHERNET_JUMBO_PACKET_SIZE_NO_CRC
)) {
4075 if ( !(pDevice
->Flags
& JUMBO_CAPABLE_FLAG
) &&
4076 (pkt_size
> MAX_ETHERNET_PACKET_SIZE_NO_CRC
) ) {
4080 if (pUmDevice
->suspended
)
4083 if (pUmDevice
->opened
&& (new_mtu
!= dev
->mtu
) &&
4084 (pDevice
->Flags
& JUMBO_CAPABLE_FLAG
)) {
4088 BCM5700_PHY_LOCK(pUmDevice
, flags
);
4090 netif_stop_queue(dev
);
4091 bcm5700_shutdown(pUmDevice
);
4092 bcm5700_freemem(dev
);
4096 if (pkt_size
< MAX_ETHERNET_PACKET_SIZE_NO_CRC
) {
4097 pDevice
->RxMtu
= pDevice
->TxMtu
=
4098 MAX_ETHERNET_PACKET_SIZE_NO_CRC
;
4101 pDevice
->RxMtu
= pDevice
->TxMtu
= pkt_size
;
4104 if (dev
->mtu
<= 1514) {
4105 pDevice
->RxJumboDescCnt
= 0;
4107 else if (pDevice
->Flags
& JUMBO_CAPABLE_FLAG
){
4108 pDevice
->RxJumboDescCnt
=
4109 rx_jumbo_desc_cnt
[pUmDevice
->index
];
4111 pDevice
->RxPacketDescCnt
= pDevice
->RxJumboDescCnt
+
4112 pDevice
->RxStdDescCnt
;
4114 pDevice
->RxJumboBufferSize
= (pDevice
->RxMtu
+ 8 /* CRC + VLAN */ +
4115 COMMON_CACHE_LINE_SIZE
-1) & ~COMMON_CACHE_LINE_MASK
;
4118 if (T3_ASIC_5714_FAMILY(pDevice
->ChipRevId
) &&
4119 (dev
->mtu
> 1514) ) {
4120 if (dev
->features
& NETIF_F_TSO
) {
4121 dev
->features
&= ~NETIF_F_TSO
;
4122 printk(KERN_ALERT
"%s: TSO previously enabled. Jumbo Frames and TSO cannot simultaneously be enabled. Jumbo Frames enabled. TSO disabled.\n", dev
->name
);
4128 LM_InitializeAdapter(pDevice
);
4129 bcm5700_do_rx_mode(dev
);
4130 bcm5700_set_vlan_mode(pUmDevice
);
4131 bcm5700_init_counters(pUmDevice
);
4132 if (memcmp(dev
->dev_addr
, pDevice
->NodeAddress
, 6)) {
4133 LM_SetMacAddress(pDevice
, dev
->dev_addr
);
4135 netif_start_queue(dev
);
4136 bcm5700_intr_on(pUmDevice
);
4138 BCM5700_PHY_UNLOCK(pUmDevice
, flags
);
4145 #if (LINUX_VERSION_CODE < 0x020300)
4147 bcm5700_probe(struct net_device
*dev
)
4149 int cards_found
= 0;
4150 struct pci_dev
*pdev
= NULL
;
4151 struct pci_device_id
*pci_tbl
;
4154 if ( ! pci_present())
4157 pci_tbl
= bcm5700_pci_tbl
;
4158 while ((pdev
= pci_find_class(PCI_CLASS_NETWORK_ETHERNET
<< 8, pdev
))) {
4161 pci_read_config_word(pdev
, PCI_SUBSYSTEM_VENDOR_ID
, &ssvid
);
4162 pci_read_config_word(pdev
, PCI_SUBSYSTEM_ID
, &ssid
);
4163 for (idx
= 0; pci_tbl
[idx
].vendor
; idx
++) {
4164 if ((pci_tbl
[idx
].vendor
== PCI_ANY_ID
||
4165 pci_tbl
[idx
].vendor
== pdev
->vendor
) &&
4166 (pci_tbl
[idx
].device
== PCI_ANY_ID
||
4167 pci_tbl
[idx
].device
== pdev
->device
) &&
4168 (pci_tbl
[idx
].subvendor
== PCI_ANY_ID
||
4169 pci_tbl
[idx
].subvendor
== ssvid
) &&
4170 (pci_tbl
[idx
].subdevice
== PCI_ANY_ID
||
4171 pci_tbl
[idx
].subdevice
== ssid
))
4177 if (pci_tbl
[idx
].vendor
== 0)
4181 if (bcm5700_init_one(pdev
, &pci_tbl
[idx
]) == 0)
4185 return cards_found
? 0 : -ENODEV
;
4189 int init_module(void)
4191 return bcm5700_probe(NULL
);
4194 void cleanup_module(void)
4196 struct net_device
*next_dev
;
4197 PUM_DEVICE_BLOCK pUmDevice
;
4199 /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
4200 while (root_tigon3_dev
) {
4201 pUmDevice
= (PUM_DEVICE_BLOCK
)root_tigon3_dev
->priv
;
4202 next_dev
= pUmDevice
->next_module
;
4203 unregister_netdev(root_tigon3_dev
);
4204 if (pUmDevice
->lm_dev
.pMappedMemBase
)
4205 iounmap(pUmDevice
->lm_dev
.pMappedMemBase
);
4206 #if (LINUX_VERSION_CODE < 0x020600)
4207 kfree(root_tigon3_dev
);
4209 free_netdev(root_tigon3_dev
);
4211 root_tigon3_dev
= next_dev
;
4214 unregister_ioctl32_conversion(SIOCNICE
);
4219 #else /* LINUX_VERSION_CODE < 0x020300 */
4221 #if (LINUX_VERSION_CODE >= 0x020406)
4222 static int bcm5700_suspend (struct pci_dev
*pdev
, u32 state
)
4224 static void bcm5700_suspend (struct pci_dev
*pdev
)
4227 struct net_device
*dev
= (struct net_device
*) pci_get_drvdata(pdev
);
4228 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
) dev
->priv
;
4229 PLM_DEVICE_BLOCK pDevice
= &pUmDevice
->lm_dev
;
4231 if (!netif_running(dev
))
4232 #if (LINUX_VERSION_CODE >= 0x020406)
4238 netif_device_detach (dev
);
4239 bcm5700_shutdown(pUmDevice
);
4241 LM_SetPowerState(pDevice
, LM_POWER_STATE_D3
);
4243 /* pci_power_off(pdev, -1);*/
4244 #if (LINUX_VERSION_CODE >= 0x020406)
4250 #if (LINUX_VERSION_CODE >= 0x020406)
4251 static int bcm5700_resume(struct pci_dev
*pdev
)
4253 static void bcm5700_resume(struct pci_dev
*pdev
)
4256 struct net_device
*dev
= (struct net_device
*) pci_get_drvdata(pdev
);
4257 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
) dev
->priv
;
4258 PLM_DEVICE_BLOCK pDevice
= &pUmDevice
->lm_dev
;
4260 if (!netif_running(dev
))
4261 #if (LINUX_VERSION_CODE >= 0x020406)
4266 /* pci_power_on(pdev);*/
4267 netif_device_attach(dev
);
4268 LM_SetPowerState(pDevice
, LM_POWER_STATE_D0
);
4269 MM_InitializeUmPackets(pDevice
);
4271 #if (LINUX_VERSION_CODE >= 0x020406)
4277 static struct pci_driver bcm5700_pci_driver
= {
4278 name
: bcm5700_driver
,
4279 id_table
: bcm5700_pci_tbl
,
4280 probe
: bcm5700_init_one
,
4281 remove
: __devexit_p(bcm5700_remove_one
),
4282 suspend
: bcm5700_suspend
,
4283 resume
: bcm5700_resume
,
4287 bcm5700_notify_reboot(struct notifier_block
*this, unsigned long event
, void *unused
)
4298 B57_INFO(("bcm5700 reboot notification\n"));
4299 pci_unregister_driver(&bcm5700_pci_driver
);
4303 static int __init
bcm5700_init_module (void)
4307 if (nvram_match("disabled_5397", "1") || (activate_gpio
!= -1)) {
4308 if ( activate_gpio
!= -1 ) pin
= activate_gpio
;
4309 printk("5397 switch GPIO-Reset (pin %d)\n", pin
);
4311 if (!(gpio_sbh
= sb_kattach(SB_OSH
))) return -ENODEV
;
4312 sb_gpiosetcore(gpio_sbh
);
4313 // sb_gpioreserve(gpio_sbh, 0x4, GPIO_HI_PRIORITY);
4314 sb_gpioouten(gpio_sbh
, 0x4, 0x4, GPIO_HI_PRIORITY
);
4315 sb_gpioout(gpio_sbh
, 0x4, 0x4, GPIO_HI_PRIORITY
);
4316 sb_detach(gpio_sbh
);
4319 if (msglevel
!= 0xdeadbeef) {
4320 b57_msg_level
= msglevel
;
4321 printf("%s: msglevel set to 0x%x\n", __FUNCTION__
, b57_msg_level
);
4323 b57_msg_level
= B57_ERR_VAL
;
4325 return pci_module_init(&bcm5700_pci_driver
);
4328 static void __exit
bcm5700_cleanup_module (void)
4330 unregister_reboot_notifier(&bcm5700_reboot_notifier
);
4331 pci_unregister_driver(&bcm5700_pci_driver
);
4334 module_init(bcm5700_init_module
);
4335 module_exit(bcm5700_cleanup_module
);
4344 #ifdef BCM_NAPI_RXPOLL
4346 MM_ScheduleRxPoll(LM_DEVICE_BLOCK
*pDevice
)
4348 struct net_device
*dev
= ((UM_DEVICE_BLOCK
*) pDevice
)->dev
;
4350 if (netif_rx_schedule_prep(dev
)) {
4351 __netif_rx_schedule(dev
);
4352 return LM_STATUS_SUCCESS
;
4354 return LM_STATUS_FAILURE
;
4359 MM_ReadConfig16(PLM_DEVICE_BLOCK pDevice
, LM_UINT32 Offset
,
4360 LM_UINT16
*pValue16
)
4362 UM_DEVICE_BLOCK
*pUmDevice
;
4364 pUmDevice
= (UM_DEVICE_BLOCK
*) pDevice
;
4365 pci_read_config_word(pUmDevice
->pdev
, Offset
, (u16
*) pValue16
);
4366 return LM_STATUS_SUCCESS
;
4370 MM_ReadConfig32(PLM_DEVICE_BLOCK pDevice
, LM_UINT32 Offset
,
4371 LM_UINT32
*pValue32
)
4373 UM_DEVICE_BLOCK
*pUmDevice
;
4375 pUmDevice
= (UM_DEVICE_BLOCK
*) pDevice
;
4376 pci_read_config_dword(pUmDevice
->pdev
, Offset
, (u32
*) pValue32
);
4377 return LM_STATUS_SUCCESS
;
4381 MM_WriteConfig16(PLM_DEVICE_BLOCK pDevice
, LM_UINT32 Offset
,
4384 UM_DEVICE_BLOCK
*pUmDevice
;
4386 pUmDevice
= (UM_DEVICE_BLOCK
*) pDevice
;
4387 pci_write_config_word(pUmDevice
->pdev
, Offset
, Value16
);
4388 return LM_STATUS_SUCCESS
;
4392 MM_WriteConfig32(PLM_DEVICE_BLOCK pDevice
, LM_UINT32 Offset
,
4395 UM_DEVICE_BLOCK
*pUmDevice
;
4397 pUmDevice
= (UM_DEVICE_BLOCK
*) pDevice
;
4398 pci_write_config_dword(pUmDevice
->pdev
, Offset
, Value32
);
4399 return LM_STATUS_SUCCESS
;
4403 MM_AllocateSharedMemory(PLM_DEVICE_BLOCK pDevice
, LM_UINT32 BlockSize
,
4404 PLM_VOID
*pMemoryBlockVirt
, PLM_PHYSICAL_ADDRESS pMemoryBlockPhy
,
4408 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
) pDevice
;
4411 pvirt
= pci_alloc_consistent(pUmDevice
->pdev
, BlockSize
,
4414 return LM_STATUS_FAILURE
;
4416 pUmDevice
->mem_list
[pUmDevice
->mem_list_num
] = pvirt
;
4417 pUmDevice
->dma_list
[pUmDevice
->mem_list_num
] = mapping
;
4418 pUmDevice
->mem_size_list
[pUmDevice
->mem_list_num
++] = BlockSize
;
4419 memset(pvirt
, 0, BlockSize
);
4420 *pMemoryBlockVirt
= (PLM_VOID
) pvirt
;
4421 MM_SetAddr(pMemoryBlockPhy
, mapping
);
4422 return LM_STATUS_SUCCESS
;
4426 MM_AllocateMemory(PLM_DEVICE_BLOCK pDevice
, LM_UINT32 BlockSize
,
4427 PLM_VOID
*pMemoryBlockVirt
)
4430 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
) pDevice
;
4433 /* Maximum in slab.c */
4434 if (BlockSize
> 131072) {
4435 goto MM_Alloc_error
;
4438 pvirt
= kmalloc(BlockSize
, GFP_ATOMIC
);
4440 goto MM_Alloc_error
;
4442 pUmDevice
->mem_list
[pUmDevice
->mem_list_num
] = pvirt
;
4443 pUmDevice
->dma_list
[pUmDevice
->mem_list_num
] = 0;
4444 pUmDevice
->mem_size_list
[pUmDevice
->mem_list_num
++] = 0;
4445 /* mem_size_list[i] == 0 indicates that the memory should be freed */
4447 memset(pvirt
, 0, BlockSize
);
4448 *pMemoryBlockVirt
= pvirt
;
4449 return LM_STATUS_SUCCESS
;
4452 printk(KERN_WARNING
"%s: Memory allocation failed - buffer parameters may be set too high\n", pUmDevice
->dev
->name
);
4453 return LM_STATUS_FAILURE
;
4457 MM_MapMemBase(PLM_DEVICE_BLOCK pDevice
)
4459 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
) pDevice
;
4461 pDevice
->pMappedMemBase
= ioremap_nocache(
4462 pci_resource_start(pUmDevice
->pdev
, 0), sizeof(T3_STD_MEM_MAP
));
4463 if (pDevice
->pMappedMemBase
== 0)
4464 return LM_STATUS_FAILURE
;
4466 return LM_STATUS_SUCCESS
;
4470 MM_InitializeUmPackets(PLM_DEVICE_BLOCK pDevice
)
4473 struct sk_buff
*skb
;
4474 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
) pDevice
;
4475 PUM_PACKET pUmPacket
;
4478 for (i
= 0; i
< pDevice
->RxPacketDescCnt
; i
++) {
4479 pPacket
= QQ_PopHead(&pDevice
->RxPacketFreeQ
.Container
);
4480 pUmPacket
= (PUM_PACKET
) pPacket
;
4482 printk(KERN_DEBUG
"Bad RxPacketFreeQ\n");
4484 if (pUmPacket
->skbuff
== 0) {
4485 #ifdef BCM_WL_EMULATOR
4486 skb
= (struct sk_buff
*)wlcemu_pktget(pDevice
->wlc
,pPacket
->u
.Rx
.RxBufferSize
+ 2);
4488 skb
= dev_alloc_skb(pPacket
->u
.Rx
.RxBufferSize
+ 2 + EXTRA_HDR
);
4491 pUmPacket
->skbuff
= 0;
4493 &pUmDevice
->rx_out_of_buf_q
.Container
,
4497 pUmPacket
->skbuff
= skb
;
4498 skb
->dev
= pUmDevice
->dev
;
4499 #ifndef BCM_WL_EMULATOR
4500 skb_reserve(skb
, EXTRA_HDR
- pUmDevice
->rx_buf_align
);
4503 QQ_PushTail(&pDevice
->RxPacketFreeQ
.Container
, pPacket
);
4505 if (T3_ASIC_REV(pUmDevice
->lm_dev
.ChipRevId
) == T3_ASIC_REV_5700
) {
4506 /* reallocate buffers in the ISR */
4507 pUmDevice
->rx_buf_repl_thresh
= 0;
4508 pUmDevice
->rx_buf_repl_panic_thresh
= 0;
4509 pUmDevice
->rx_buf_repl_isr_limit
= 0;
4512 pUmDevice
->rx_buf_repl_thresh
= pDevice
->RxPacketDescCnt
/ 8;
4513 pUmDevice
->rx_buf_repl_panic_thresh
=
4514 pDevice
->RxPacketDescCnt
* 7 / 8;
4516 /* This limits the time spent in the ISR when the receiver */
4517 /* is in a steady state of being overrun. */
4518 pUmDevice
->rx_buf_repl_isr_limit
= pDevice
->RxPacketDescCnt
/ 8;
4520 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
4521 if (pDevice
->RxJumboDescCnt
!= 0) {
4522 if (pUmDevice
->rx_buf_repl_thresh
>=
4523 pDevice
->RxJumboDescCnt
) {
4525 pUmDevice
->rx_buf_repl_thresh
=
4526 pUmDevice
->rx_buf_repl_panic_thresh
=
4527 pDevice
->RxJumboDescCnt
- 1;
4529 if (pUmDevice
->rx_buf_repl_thresh
>=
4530 pDevice
->RxStdDescCnt
) {
4532 pUmDevice
->rx_buf_repl_thresh
=
4533 pUmDevice
->rx_buf_repl_panic_thresh
=
4534 pDevice
->RxStdDescCnt
- 1;
4539 return LM_STATUS_SUCCESS
;
4543 MM_GetConfig(PLM_DEVICE_BLOCK pDevice
)
4545 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
) pDevice
;
4546 int index
= pUmDevice
->index
;
4547 struct net_device
*dev
= pUmDevice
->dev
;
4549 if (index
>= MAX_UNITS
)
4550 return LM_STATUS_SUCCESS
;
4552 #if LINUX_KERNEL_VERSION < 0x0020609
4554 bcm5700_validate_param_range(pUmDevice
, &auto_speed
[index
], "auto_speed",
4556 if (auto_speed
[index
] == 0)
4557 pDevice
->DisableAutoNeg
= TRUE
;
4559 pDevice
->DisableAutoNeg
= FALSE
;
4561 if (line_speed
[index
] == 0) {
4562 pDevice
->RequestedLineSpeed
= LM_LINE_SPEED_AUTO
;
4563 pDevice
->DisableAutoNeg
= FALSE
;
4566 bcm5700_validate_param_range(pUmDevice
, &full_duplex
[index
],
4567 "full_duplex", 0, 1, 1);
4568 if (full_duplex
[index
]) {
4569 pDevice
->RequestedDuplexMode
= LM_DUPLEX_MODE_FULL
;
4572 pDevice
->RequestedDuplexMode
= LM_DUPLEX_MODE_HALF
;
4575 if (line_speed
[index
] == 1000) {
4576 pDevice
->RequestedLineSpeed
= LM_LINE_SPEED_1000MBPS
;
4577 if (pDevice
->PhyFlags
& PHY_NO_GIGABIT
) {
4578 pDevice
->RequestedLineSpeed
=
4579 LM_LINE_SPEED_100MBPS
;
4580 printk(KERN_WARNING
"%s-%d: Invalid line_speed parameter (1000), using 100\n", bcm5700_driver
, index
);
4583 if ((pDevice
->TbiFlags
& ENABLE_TBI_FLAG
) &&
4584 !full_duplex
[index
]) {
4585 printk(KERN_WARNING
"%s-%d: Invalid full_duplex parameter (0) for fiber, using 1\n", bcm5700_driver
, index
);
4586 pDevice
->RequestedDuplexMode
=
4587 LM_DUPLEX_MODE_FULL
;
4590 if (!(pDevice
->TbiFlags
& ENABLE_TBI_FLAG
) &&
4591 !auto_speed
[index
] && !(pDevice
->PhyFlags
& PHY_IS_FIBER
) ) {
4592 printk(KERN_WARNING
"%s-%d: Invalid auto_speed parameter (0) for copper, using 1\n", bcm5700_driver
, index
);
4593 pDevice
->DisableAutoNeg
= FALSE
;
4597 else if ((pDevice
->TbiFlags
& ENABLE_TBI_FLAG
) ||
4598 (pDevice
->PhyFlags
& PHY_IS_FIBER
)){
4599 pDevice
->RequestedLineSpeed
= LM_LINE_SPEED_AUTO
;
4600 pDevice
->RequestedDuplexMode
= LM_DUPLEX_MODE_FULL
;
4601 pDevice
->DisableAutoNeg
= FALSE
;
4602 printk(KERN_WARNING
"%s-%d: Invalid line_speed parameter (%d), using auto\n", bcm5700_driver
, index
, line_speed
[index
]);
4604 else if (line_speed
[index
] == 100) {
4606 pDevice
->RequestedLineSpeed
= LM_LINE_SPEED_100MBPS
;
4608 else if (line_speed
[index
] == 10) {
4610 pDevice
->RequestedLineSpeed
= LM_LINE_SPEED_10MBPS
;
4613 pDevice
->RequestedLineSpeed
= LM_LINE_SPEED_AUTO
;
4614 pDevice
->DisableAutoNeg
= FALSE
;
4615 printk(KERN_WARNING
"%s-%d: Invalid line_speed parameter (%d), using 0\n", bcm5700_driver
, index
, line_speed
[index
]);
4620 #endif /* LINUX_KERNEL_VERSION */
4622 /* This is an unmanageable switch nic and will have link problems if
4625 if(pDevice
->SubsystemVendorId
==0x103c && pDevice
->SubsystemId
==0x3226)
4627 if(pDevice
->RequestedLineSpeed
!= LM_LINE_SPEED_AUTO
)
4629 printk(KERN_WARNING
"%s-%d: Invalid line_speed parameter (%d), using 0\n",
4630 bcm5700_driver
, index
, line_speed
[index
]);
4632 pDevice
->RequestedLineSpeed
= LM_LINE_SPEED_AUTO
;
4633 pDevice
->DisableAutoNeg
= FALSE
;
4636 #if LINUX_KERNEL_VERSION < 0x0020609
4638 pDevice
->FlowControlCap
= 0;
4639 bcm5700_validate_param_range(pUmDevice
, &rx_flow_control
[index
],
4640 "rx_flow_control", 0, 1, 0);
4641 if (rx_flow_control
[index
] != 0) {
4642 pDevice
->FlowControlCap
|= LM_FLOW_CONTROL_RECEIVE_PAUSE
;
4644 bcm5700_validate_param_range(pUmDevice
, &tx_flow_control
[index
],
4645 "tx_flow_control", 0, 1, 0);
4646 if (tx_flow_control
[index
] != 0) {
4647 pDevice
->FlowControlCap
|= LM_FLOW_CONTROL_TRANSMIT_PAUSE
;
4649 bcm5700_validate_param_range(pUmDevice
, &auto_flow_control
[index
],
4650 "auto_flow_control", 0, 1, 0);
4651 if (auto_flow_control
[index
] != 0) {
4652 if (pDevice
->DisableAutoNeg
== FALSE
) {
4654 pDevice
->FlowControlCap
|= LM_FLOW_CONTROL_AUTO_PAUSE
;
4655 if ((tx_flow_control
[index
] == 0) &&
4656 (rx_flow_control
[index
] == 0)) {
4658 pDevice
->FlowControlCap
|=
4659 LM_FLOW_CONTROL_TRANSMIT_PAUSE
|
4660 LM_FLOW_CONTROL_RECEIVE_PAUSE
;
4665 if (dev
->mtu
> 1500) {
4667 if (T3_ASIC_5714_FAMILY(pDevice
->ChipRevId
) &&
4668 (dev
->features
& NETIF_F_TSO
)) {
4669 dev
->features
&= ~NETIF_F_TSO
;
4670 printk(KERN_ALERT
"%s: TSO previously enabled. Jumbo Frames and TSO cannot simultaneously be enabled. Jumbo Frames enabled. TSO disabled.\n", dev
->name
);
4673 pDevice
->RxMtu
= dev
->mtu
+ 14;
4676 if ((T3_ASIC_REV(pDevice
->ChipRevId
) != T3_ASIC_REV_5700
) &&
4677 !(pDevice
->Flags
& BCM5788_FLAG
)) {
4678 pDevice
->Flags
|= USE_TAGGED_STATUS_FLAG
;
4679 pUmDevice
->timer_interval
= HZ
;
4680 if ((T3_ASIC_REV(pDevice
->ChipRevId
) == T3_ASIC_REV_5703
) &&
4681 (pDevice
->TbiFlags
& ENABLE_TBI_FLAG
)) {
4682 pUmDevice
->timer_interval
= HZ
/4;
4686 pUmDevice
->timer_interval
= HZ
/10;
4689 bcm5700_validate_param_range(pUmDevice
, &tx_pkt_desc_cnt
[index
],
4690 "tx_pkt_desc_cnt", 1, MAX_TX_PACKET_DESC_COUNT
-1, TX_DESC_CNT
);
4691 pDevice
->TxPacketDescCnt
= tx_pkt_desc_cnt
[index
];
4692 bcm5700_validate_param_range(pUmDevice
, &rx_std_desc_cnt
[index
],
4693 "rx_std_desc_cnt", 1, T3_STD_RCV_RCB_ENTRY_COUNT
-1,
4695 pDevice
->RxStdDescCnt
= rx_std_desc_cnt
[index
];
4697 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
4698 bcm5700_validate_param_range(pUmDevice
, &rx_jumbo_desc_cnt
[index
],
4699 "rx_jumbo_desc_cnt", 1, T3_JUMBO_RCV_RCB_ENTRY_COUNT
-1,
4702 if (mtu
[index
] <= 1514)
4703 pDevice
->RxJumboDescCnt
= 0;
4704 else if(!T3_ASIC_IS_5705_BEYOND(pDevice
->ChipRevId
)){
4705 pDevice
->RxJumboDescCnt
= rx_jumbo_desc_cnt
[index
];
4710 bcm5700_validate_param_range(pUmDevice
, &adaptive_coalesce
[index
],
4711 "adaptive_coalesce", 0, 1, 1);
4712 #ifdef BCM_NAPI_RXPOLL
4713 if (adaptive_coalesce
[index
]) {
4714 printk(KERN_WARNING
"%s-%d: adaptive_coalesce not used in NAPI mode\n", bcm5700_driver
, index
);
4715 adaptive_coalesce
[index
] = 0;
4719 pUmDevice
->adaptive_coalesce
= adaptive_coalesce
[index
];
4720 if (!pUmDevice
->adaptive_coalesce
) {
4721 bcm5700_validate_param_range(pUmDevice
,
4722 &rx_coalesce_ticks
[index
], "rx_coalesce_ticks", 0,
4723 MAX_RX_COALESCING_TICKS
, RX_COAL_TK
);
4724 if ((rx_coalesce_ticks
[index
] == 0) &&
4725 (rx_max_coalesce_frames
[index
] == 0)) {
4727 printk(KERN_WARNING
"%s-%d: Conflicting rx_coalesce_ticks (0) and rx_max_coalesce_frames (0) parameters, using %d and %d respectively\n",
4728 bcm5700_driver
, index
, RX_COAL_TK
, RX_COAL_FM
);
4730 rx_coalesce_ticks
[index
] = RX_COAL_TK
;
4731 rx_max_coalesce_frames
[index
] = RX_COAL_FM
;
4733 pDevice
->RxCoalescingTicks
= pUmDevice
->rx_curr_coalesce_ticks
=
4734 rx_coalesce_ticks
[index
];
4735 #ifdef BCM_NAPI_RXPOLL
4736 pDevice
->RxCoalescingTicksDuringInt
= rx_coalesce_ticks
[index
];
4739 bcm5700_validate_param_range(pUmDevice
,
4740 &rx_max_coalesce_frames
[index
],
4741 "rx_max_coalesce_frames", 0,
4742 MAX_RX_MAX_COALESCED_FRAMES
, RX_COAL_FM
);
4744 pDevice
->RxMaxCoalescedFrames
=
4745 pUmDevice
->rx_curr_coalesce_frames
=
4746 rx_max_coalesce_frames
[index
];
4747 #ifdef BCM_NAPI_RXPOLL
4748 pDevice
->RxMaxCoalescedFramesDuringInt
=
4749 rx_max_coalesce_frames
[index
];
4752 bcm5700_validate_param_range(pUmDevice
,
4753 &tx_coalesce_ticks
[index
], "tx_coalesce_ticks", 0,
4754 MAX_TX_COALESCING_TICKS
, TX_COAL_TK
);
4755 if ((tx_coalesce_ticks
[index
] == 0) &&
4756 (tx_max_coalesce_frames
[index
] == 0)) {
4758 printk(KERN_WARNING
"%s-%d: Conflicting tx_coalesce_ticks (0) and tx_max_coalesce_frames (0) parameters, using %d and %d respectively\n",
4759 bcm5700_driver
, index
, TX_COAL_TK
, TX_COAL_FM
);
4761 tx_coalesce_ticks
[index
] = TX_COAL_TK
;
4762 tx_max_coalesce_frames
[index
] = TX_COAL_FM
;
4764 pDevice
->TxCoalescingTicks
= tx_coalesce_ticks
[index
];
4765 bcm5700_validate_param_range(pUmDevice
,
4766 &tx_max_coalesce_frames
[index
],
4767 "tx_max_coalesce_frames", 0,
4768 MAX_TX_MAX_COALESCED_FRAMES
, TX_COAL_FM
);
4769 pDevice
->TxMaxCoalescedFrames
= tx_max_coalesce_frames
[index
];
4770 pUmDevice
->tx_curr_coalesce_frames
=
4771 pDevice
->TxMaxCoalescedFrames
;
4773 bcm5700_validate_param_range(pUmDevice
,
4774 &stats_coalesce_ticks
[index
], "stats_coalesce_ticks",
4775 0, MAX_STATS_COALESCING_TICKS
, ST_COAL_TK
);
4776 if (adaptive_coalesce
[index
]) {
4777 printk(KERN_WARNING
"%s-%d: Invalid stats_coalesce_ticks parameter set with with adaptive_coalesce parameter. Using adaptive_coalesce.\n", bcm5700_driver
, index
);
4779 if ((stats_coalesce_ticks
[index
] > 0) &&
4780 (stats_coalesce_ticks
[index
] < 100)) {
4781 printk(KERN_WARNING
"%s-%d: Invalid stats_coalesce_ticks parameter (%u), using 100\n", bcm5700_driver
, index
, (unsigned int) stats_coalesce_ticks
[index
]);
4782 stats_coalesce_ticks
[index
] = 100;
4783 pDevice
->StatsCoalescingTicks
= stats_coalesce_ticks
[index
];
4784 pDevice
->StatsCoalescingTicks
= stats_coalesce_ticks
[index
];
4789 pUmDevice
->rx_curr_coalesce_frames
= RX_COAL_FM
;
4790 pUmDevice
->rx_curr_coalesce_ticks
= RX_COAL_TK
;
4791 pUmDevice
->tx_curr_coalesce_frames
= TX_COAL_FM
;
4795 if (T3_ASIC_IS_5705_BEYOND(pDevice
->ChipRevId
)) {
4796 unsigned int tmpvar
;
4798 tmpvar
= pDevice
->StatsCoalescingTicks
/ BCM_TIMER_GRANULARITY
;
4801 * If the result is zero, the request is too demanding.
4807 pDevice
->StatsCoalescingTicks
= tmpvar
* BCM_TIMER_GRANULARITY
;
4809 pUmDevice
->statstimer_interval
= tmpvar
;
4813 bcm5700_validate_param_range(pUmDevice
, &enable_wol
[index
],
4814 "enable_wol", 0, 1, 0);
4815 if (enable_wol
[index
]) {
4816 pDevice
->WakeUpModeCap
= LM_WAKE_UP_MODE_MAGIC_PACKET
;
4817 pDevice
->WakeUpMode
= LM_WAKE_UP_MODE_MAGIC_PACKET
;
4820 #ifdef INCLUDE_TBI_SUPPORT
4821 if (pDevice
->TbiFlags
& ENABLE_TBI_FLAG
) {
4822 if ((T3_ASIC_REV(pDevice
->ChipRevId
) == T3_ASIC_REV_5704
) ||
4823 (T3_ASIC_REV(pDevice
->ChipRevId
) == T3_ASIC_REV_5703
)) {
4824 /* just poll since we have hardware autoneg. in 5704 */
4825 pDevice
->TbiFlags
|= TBI_PURE_POLLING_FLAG
;
4828 pDevice
->TbiFlags
|= TBI_POLLING_INTR_FLAG
;
4832 bcm5700_validate_param_range(pUmDevice
, &scatter_gather
[index
],
4833 "scatter_gather", 0, 1, 1);
4834 bcm5700_validate_param_range(pUmDevice
, &tx_checksum
[index
],
4835 "tx_checksum", 0, 1, 1);
4836 bcm5700_validate_param_range(pUmDevice
, &rx_checksum
[index
],
4837 "rx_checksum", 0, 1, 1);
4838 if (!(pDevice
->TaskOffloadCap
& LM_TASK_OFFLOAD_TX_TCP_CHECKSUM
)) {
4839 if (tx_checksum
[index
] || rx_checksum
[index
]) {
4841 pDevice
->TaskToOffload
= LM_TASK_OFFLOAD_NONE
;
4842 printk(KERN_WARNING
"%s-%d: Checksum offload not available on this NIC\n", bcm5700_driver
, index
);
4846 if (rx_checksum
[index
]) {
4847 pDevice
->TaskToOffload
|=
4848 LM_TASK_OFFLOAD_RX_TCP_CHECKSUM
|
4849 LM_TASK_OFFLOAD_RX_UDP_CHECKSUM
;
4851 if (tx_checksum
[index
]) {
4852 pDevice
->TaskToOffload
|=
4853 LM_TASK_OFFLOAD_TX_TCP_CHECKSUM
|
4854 LM_TASK_OFFLOAD_TX_UDP_CHECKSUM
;
4855 pDevice
->Flags
|= NO_TX_PSEUDO_HDR_CSUM_FLAG
;
4859 bcm5700_validate_param_range(pUmDevice
, &enable_tso
[index
],
4860 "enable_tso", 0, 1, 1);
4862 /* Always enable TSO firmware if supported */
4863 /* This way we can turn it on or off on the fly */
4864 if (pDevice
->TaskOffloadCap
& LM_TASK_OFFLOAD_TCP_SEGMENTATION
)
4866 pDevice
->TaskToOffload
|=
4867 LM_TASK_OFFLOAD_TCP_SEGMENTATION
;
4869 if (enable_tso
[index
] &&
4870 !(pDevice
->TaskToOffload
& LM_TASK_OFFLOAD_TCP_SEGMENTATION
))
4872 printk(KERN_WARNING
"%s-%d: TSO not available on this NIC\n", bcm5700_driver
, index
);
4876 bcm5700_validate_param_range(pUmDevice
, &vlan_tag_mode
[index
],
4877 "vlan_strip_mode", 0, 2, 0);
4878 pUmDevice
->vlan_tag_mode
= vlan_tag_mode
[index
];
4880 pUmDevice
->vlan_tag_mode
= VLAN_TAG_MODE_NORMAL_STRIP
;
4883 #endif /* LINUX_KERNEL_VERSION */
4885 #ifdef BCM_NIC_SEND_BD
4886 bcm5700_validate_param_range(pUmDevice
, &nic_tx_bd
[index
], "nic_tx_bd",
4888 if (nic_tx_bd
[index
])
4889 pDevice
->Flags
|= NIC_SEND_BD_FLAG
;
4890 if ((pDevice
->Flags
& ENABLE_PCIX_FIX_FLAG
) ||
4891 (T3_ASIC_REV(pDevice
->ChipRevId
) == T3_ASIC_REV_5705
)) {
4892 if (pDevice
->Flags
& NIC_SEND_BD_FLAG
) {
4893 pDevice
->Flags
&= ~NIC_SEND_BD_FLAG
;
4894 printk(KERN_WARNING
"%s-%d: Nic Send BDs not available on this NIC or not possible on this system\n", bcm5700_driver
, index
);
4898 #if defined(CONFIG_PCI_MSI) || defined(CONFIG_PCI_USE_VECTOR)
4899 bcm5700_validate_param_range(pUmDevice
, &disable_msi
[pUmDevice
->index
],
4900 "disable_msi", 0, 1, 0);
4903 bcm5700_validate_param_range(pUmDevice
, &delay_link
[index
],
4904 "delay_link", 0, 1, 0);
4906 bcm5700_validate_param_range(pUmDevice
, &disable_d3hot
[index
],
4907 "disable_d3hot", 0, 1, 0);
4908 if (disable_d3hot
[index
]) {
4911 if (enable_wol
[index
]) {
4912 pDevice
->WakeUpModeCap
= LM_WAKE_UP_MODE_NONE
;
4913 pDevice
->WakeUpMode
= LM_WAKE_UP_MODE_NONE
;
4914 printk(KERN_WARNING
"%s-%d: Wake-On-Lan disabled because D3Hot is disabled\n", bcm5700_driver
, index
);
4917 pDevice
->Flags
|= DISABLE_D3HOT_FLAG
;
4920 return LM_STATUS_SUCCESS
;
4923 /* From include/proto/ethernet.h */
4924 #define ETHER_TYPE_8021Q 0x8100 /* 802.1Q */
4926 /* From include/proto/vlan.h */
4927 #define VLAN_PRI_MASK 7 /* 3 bits of priority */
4928 #define VLAN_PRI_SHIFT 13
4930 /* Replace the priority in a vlan tag */
4931 #define UPD_VLANTAG_PRIO(tag, prio) do { \
4932 tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT); \
4933 tag |= prio << VLAN_PRI_SHIFT; \
4936 /* Takes an Ethernet frame and sets out-of-bound PKTPRIO.
4937 * Also updates the inplace vlan tag if requested.
4938 * For debugging, it returns an indication of what it did.
4940 #define PKTPRIO_VDSCP 0x100 /* DSCP prio found after VLAN tag */
4941 #define PKTPRIO_VLAN 0x200 /* VLAN prio found */
4942 #define PKTPRIO_UPD 0x400 /* DSCP used to update VLAN prio */
4943 #define PKTPRIO_DSCP 0x800 /* DSCP prio found */
4944 #define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x))
4946 pktsetprio(void *pkt
, bool update_vtag
)
4948 struct ether_header
*eh
;
4949 struct ethervlan_header
*evh
;
4954 pktdata
= (uint8
*) PKTDATA(NULL
, pkt
);
4955 ASSERT(ISALIGNED((uintptr
)pktdata
, sizeof(uint16
)));
4957 eh
= (struct ether_header
*) pktdata
;
4959 if (ntoh16(eh
->ether_type
) == ETHER_TYPE_8021Q
) {
4961 int vlan_prio
, dscp_prio
= 0;
4963 evh
= (struct ethervlan_header
*)eh
;
4965 vlan_tag
= ntoh16(evh
->vlan_tag
);
4966 vlan_prio
= (int) (vlan_tag
>> VLAN_PRI_SHIFT
) & VLAN_PRI_MASK
;
4968 if (ntoh16(evh
->ether_type
) == ETHER_TYPE_IP
) {
4969 uint8
*ip_body
= pktdata
+ sizeof(struct ethervlan_header
);
4970 uint8 tos_tc
= IP_TOS(ip_body
);
4971 dscp_prio
= (int)(tos_tc
>> IPV4_TOS_PREC_SHIFT
);
4972 if ((IP_VER(ip_body
) == IP_VER_4
) && (IPV4_PROT(ip_body
) == IP_PROT_TCP
)) {
4978 ip_len
= IPV4_PAYLOAD_LEN(ip_body
);
4979 tcp_hdr
= IPV4_NO_OPTIONS_PAYLOAD(ip_body
);
4980 src_port
= TCP_SRC_PORT(tcp_hdr
);
4981 src_port_exc
= (src_port
== 10110) || (src_port
== 10120) ||
4982 (src_port
== 10130) || (src_port
== 10140);
4984 if ((ip_len
== 40) && src_port_exc
&& TCP_IS_ACK(tcp_hdr
)) {
4990 /* DSCP priority gets precedence over 802.1P (vlan tag) */
4991 if (dscp_prio
!= 0) {
4992 priority
= dscp_prio
;
4993 rc
|= PKTPRIO_VDSCP
;
4995 priority
= vlan_prio
;
4999 * If the DSCP priority is not the same as the VLAN priority,
5000 * then overwrite the priority field in the vlan tag, with the
5001 * DSCP priority value. This is required for Linux APs because
5002 * the VLAN driver on Linux, overwrites the skb->priority field
5003 * with the priority value in the vlan tag
5005 if (update_vtag
&& (priority
!= vlan_prio
)) {
5006 vlan_tag
&= ~(VLAN_PRI_MASK
<< VLAN_PRI_SHIFT
);
5007 vlan_tag
|= (uint16
)priority
<< VLAN_PRI_SHIFT
;
5008 evh
->vlan_tag
= hton16(vlan_tag
);
5011 } else if (ntoh16(eh
->ether_type
) == ETHER_TYPE_IP
) {
5012 uint8
*ip_body
= pktdata
+ sizeof(struct ether_header
);
5013 uint8 tos_tc
= IP_TOS(ip_body
);
5014 priority
= (int)(tos_tc
>> IPV4_TOS_PREC_SHIFT
);
5016 if ((IP_VER(ip_body
) == IP_VER_4
) && (IPV4_PROT(ip_body
) == IP_PROT_TCP
)) {
5022 ip_len
= IPV4_PAYLOAD_LEN(ip_body
);
5023 tcp_hdr
= IPV4_NO_OPTIONS_PAYLOAD(ip_body
);
5024 src_port
= TCP_SRC_PORT(tcp_hdr
);
5025 src_port_exc
= (src_port
== 10110) || (src_port
== 10120) ||
5026 (src_port
== 10130) || (src_port
== 10140);
5028 if ((ip_len
== 40) && src_port_exc
&& TCP_IS_ACK(tcp_hdr
)) {
5034 ASSERT(priority
>= 0 && priority
<= MAXPRIO
);
5035 PKTSETPRIO(pkt
, priority
);
5036 return (rc
| priority
);
5040 MM_IndicateRxPackets(PLM_DEVICE_BLOCK pDevice
)
5042 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
) pDevice
;
5044 PUM_PACKET pUmPacket
;
5045 struct sk_buff
*skb
;
5047 int vlan_tag_size
= 0;
5050 if (pDevice
->ReceiveMask
& LM_KEEP_VLAN_TAG
)
5054 pPacket
= (PLM_PACKET
)
5055 QQ_PopHead(&pDevice
->RxPacketReceivedQ
.Container
);
5058 pUmPacket
= (PUM_PACKET
) pPacket
;
5059 #if !defined(NO_PCI_UNMAP)
5060 pci_unmap_single(pUmDevice
->pdev
,
5061 pci_unmap_addr(pUmPacket
, map
[0]),
5062 pPacket
->u
.Rx
.RxBufferSize
,
5063 PCI_DMA_FROMDEVICE
);
5065 if ((pPacket
->PacketStatus
!= LM_STATUS_SUCCESS
) ||
5066 ((size
= pPacket
->PacketSize
) >
5067 (pDevice
->RxMtu
+ vlan_tag_size
))) {
5071 QQ_PushTail(&pUmDevice
->rx_out_of_buf_q
.Container
, pPacket
);
5073 QQ_PushTail(&pDevice
->RxPacketFreeQ
.Container
, pPacket
);
5075 pUmDevice
->rx_misc_errors
++;
5078 skb
= pUmPacket
->skbuff
;
5081 /* Extract priority from payload and put it in skb->priority */
5083 if (pUmDevice
->qos
) {
5086 rc
= pktsetprio(skb
, TRUE
);
5087 if (rc
& (PKTPRIO_VDSCP
| PKTPRIO_DSCP
))
5088 dscp_prio
= rc
& VLAN_PRI_MASK
;
5090 B57_INFO(("pktsetprio returned 0x%x, skb->priority: %d\n",
5091 rc
, skb
->priority
));
5093 skb
->protocol
= eth_type_trans(skb
, skb
->dev
);
5094 if (size
> pDevice
->RxMtu
) {
5095 /* Make sure we have a valid VLAN tag */
5096 if (htons(skb
->protocol
) != ETHER_TYPE_8021Q
) {
5097 dev_kfree_skb_irq(skb
);
5098 pUmDevice
->rx_misc_errors
++;
5103 pUmDevice
->stats
.rx_bytes
+= skb
->len
;
5105 if ((pPacket
->Flags
& RCV_BD_FLAG_TCP_UDP_CHKSUM_FIELD
) &&
5106 (pDevice
->TaskToOffload
&
5107 LM_TASK_OFFLOAD_RX_TCP_CHECKSUM
)) {
5108 if (pPacket
->u
.Rx
.TcpUdpChecksum
== 0xffff) {
5110 skb
->ip_summed
= CHECKSUM_UNNECESSARY
;
5112 pUmDevice
->rx_good_chksum_count
++;
5116 skb
->ip_summed
= CHECKSUM_NONE
;
5117 pUmDevice
->rx_bad_chksum_count
++;
5121 skb
->ip_summed
= CHECKSUM_NONE
;
5125 if (pUmDevice
->vlgrp
&&
5126 (pPacket
->Flags
& RCV_BD_FLAG_VLAN_TAG
)) {
5127 /* Override vlan priority with dscp priority */
5129 UPD_VLANTAG_PRIO(pPacket
->VlanTag
, dscp_prio
);
5130 #ifdef BCM_NAPI_RXPOLL
5131 vlan_hwaccel_receive_skb(skb
, pUmDevice
->vlgrp
,
5134 vlan_hwaccel_rx(skb
, pUmDevice
->vlgrp
,
5140 #ifdef BCM_WL_EMULATOR
5141 if(pDevice
->wl_emulate_rx
) {
5142 /* bcmstats("emu recv %d %d"); */
5143 wlcemu_receive_skb(pDevice
->wlc
, skb
);
5144 /* bcmstats("emu recv end %d %d"); */
5147 #endif /* BCM_WL_EMULATOR */
5149 #ifdef BCM_NAPI_RXPOLL
5150 netif_receive_skb(skb
);
5157 pUmDevice
->dev
->last_rx
= jiffies
;
5161 pUmPacket
->skbuff
= 0;
5162 QQ_PushTail(&pUmDevice
->rx_out_of_buf_q
.Container
, pPacket
);
5164 #ifdef BCM_WL_EMULATOR
5165 skb
= (struct sk_buff
*)wlcemu_pktget(pDevice
->wlc
,pPacket
->u
.Rx
.RxBufferSize
+ 2);
5167 skb
= dev_alloc_skb(pPacket
->u
.Rx
.RxBufferSize
+ 2 + EXTRA_HDR
);
5168 #endif /* BCM_WL_EMULATOR */
5170 pUmPacket
->skbuff
= 0;
5171 QQ_PushTail(&pUmDevice
->rx_out_of_buf_q
.Container
, pPacket
);
5174 pUmPacket
->skbuff
= skb
;
5175 skb
->dev
= pUmDevice
->dev
;
5176 #ifndef BCM_WL_EMULATOR
5177 skb_reserve(skb
, EXTRA_HDR
- pUmDevice
->rx_buf_align
);
5179 QQ_PushTail(&pDevice
->RxPacketFreeQ
.Container
, pPacket
);
5183 return LM_STATUS_SUCCESS
;
5187 MM_CoalesceTxBuffer(PLM_DEVICE_BLOCK pDevice
, PLM_PACKET pPacket
)
5189 PUM_PACKET pUmPacket
= (PUM_PACKET
) pPacket
;
5190 struct sk_buff
*skb
= pUmPacket
->skbuff
;
5191 struct sk_buff
*nskb
;
5192 #if !defined(NO_PCI_UNMAP)
5193 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
) pDevice
;
5195 pci_unmap_single(pUmDevice
->pdev
,
5196 pci_unmap_addr(pUmPacket
, map
[0]),
5197 pci_unmap_len(pUmPacket
, map_len
[0]),
5203 for (i
= 0; i
< skb_shinfo(skb
)->nr_frags
; i
++) {
5204 pci_unmap_page(pUmDevice
->pdev
,
5205 pci_unmap_addr(pUmPacket
, map
[i
+ 1]),
5206 pci_unmap_len(pUmPacket
, map_len
[i
+ 1]),
5212 if ((nskb
= skb_copy(skb
, GFP_ATOMIC
))) {
5213 pUmPacket
->lm_packet
.u
.Tx
.FragCount
= 1;
5215 pUmPacket
->skbuff
= nskb
;
5216 return LM_STATUS_SUCCESS
;
5219 pUmPacket
->skbuff
= 0;
5220 return LM_STATUS_FAILURE
;
5223 /* Returns 1 if not all buffers are allocated */
5225 replenish_rx_buffers(PUM_DEVICE_BLOCK pUmDevice
, int max
)
5228 PUM_PACKET pUmPacket
;
5229 PLM_DEVICE_BLOCK pDevice
= (PLM_DEVICE_BLOCK
) pUmDevice
;
5230 struct sk_buff
*skb
;
5235 while ((pUmPacket
= (PUM_PACKET
)
5236 QQ_PopHead(&pUmDevice
->rx_out_of_buf_q
.Container
)) != 0) {
5237 pPacket
= (PLM_PACKET
) pUmPacket
;
5238 if (pUmPacket
->skbuff
) {
5239 /* reuse an old skb */
5240 QQ_PushTail(&pDevice
->RxPacketFreeQ
.Container
, pPacket
);
5244 #ifdef BCM_WL_EMULATOR
5245 if ((skb
= (struct sk_buff
*)wlcemu_pktget(pDevice
->wlc
,pPacket
->u
.Rx
.RxBufferSize
+ 2)) == 0)
5247 if ((skb
= dev_alloc_skb(pPacket
->u
.Rx
.RxBufferSize
+ 2 + EXTRA_HDR
)) == 0)
5248 #endif /* BCM_WL_EMULATOR */
5250 QQ_PushHead(&pUmDevice
->rx_out_of_buf_q
.Container
,
5255 pUmPacket
->skbuff
= skb
;
5256 skb
->dev
= pUmDevice
->dev
;
5257 #ifndef BCM_WL_EMULATOR
5258 skb_reserve(skb
, EXTRA_HDR
- pUmDevice
->rx_buf_align
);
5260 QQ_PushTail(&pDevice
->RxPacketFreeQ
.Container
, pPacket
);
5264 if (alloc_cnt
>= max
)
5268 if (queue_rx
|| pDevice
->QueueAgain
) {
5269 LM_QueueRxPackets(pDevice
);
5275 MM_IndicateTxPackets(PLM_DEVICE_BLOCK pDevice
)
5277 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
) pDevice
;
5279 PUM_PACKET pUmPacket
;
5280 struct sk_buff
*skb
;
5281 #if !defined(NO_PCI_UNMAP) && MAX_SKB_FRAGS
5286 pPacket
= (PLM_PACKET
)
5287 QQ_PopHead(&pDevice
->TxPacketXmittedQ
.Container
);
5290 pUmPacket
= (PUM_PACKET
) pPacket
;
5291 skb
= pUmPacket
->skbuff
;
5292 #if !defined(NO_PCI_UNMAP)
5293 pci_unmap_single(pUmDevice
->pdev
,
5294 pci_unmap_addr(pUmPacket
, map
[0]),
5295 pci_unmap_len(pUmPacket
, map_len
[0]),
5298 for (i
= 0; i
< skb_shinfo(skb
)->nr_frags
; i
++) {
5299 pci_unmap_page(pUmDevice
->pdev
,
5300 pci_unmap_addr(pUmPacket
, map
[i
+ 1]),
5301 pci_unmap_len(pUmPacket
, map_len
[i
+ 1]),
5306 dev_kfree_skb_irq(skb
);
5307 pUmPacket
->skbuff
= 0;
5308 QQ_PushTail(&pDevice
->TxPacketFreeQ
.Container
, pPacket
);
5310 if (pUmDevice
->tx_full
) {
5311 if (QQ_GetEntryCnt(&pDevice
->TxPacketFreeQ
.Container
) >=
5312 (pDevice
->TxPacketDescCnt
>> 1)) {
5314 pUmDevice
->tx_full
= 0;
5315 netif_wake_queue(pUmDevice
->dev
);
5318 return LM_STATUS_SUCCESS
;
5322 MM_IndicateStatus(PLM_DEVICE_BLOCK pDevice
, LM_STATUS Status
)
5324 PUM_DEVICE_BLOCK pUmDevice
= (PUM_DEVICE_BLOCK
) pDevice
;
5325 struct net_device
*dev
= pUmDevice
->dev
;
5326 LM_FLOW_CONTROL flow_control
;
5329 if (!pUmDevice
->opened
)
5330 return LM_STATUS_SUCCESS
;
5332 if (!pUmDevice
->suspended
) {
5333 if (Status
== LM_STATUS_LINK_DOWN
) {
5334 netif_carrier_off(dev
);
5336 else if (Status
== LM_STATUS_LINK_ACTIVE
) {
5337 netif_carrier_on(dev
);
5341 if (pUmDevice
->delayed_link_ind
> 0) {
5342 pUmDevice
->delayed_link_ind
= 0;
5343 if (Status
== LM_STATUS_LINK_DOWN
) {
5344 B57_INFO(("%s: %s NIC Link is DOWN\n", bcm5700_driver
, dev
->name
));
5346 else if (Status
== LM_STATUS_LINK_ACTIVE
) {
5347 B57_INFO(("%s: %s NIC Link is UP, ", bcm5700_driver
, dev
->name
));
5351 if (Status
== LM_STATUS_LINK_DOWN
) {
5352 B57_INFO(("%s: %s NIC Link is Down\n", bcm5700_driver
, dev
->name
));
5354 else if (Status
== LM_STATUS_LINK_ACTIVE
) {
5355 B57_INFO(("%s: %s NIC Link is Up, ", bcm5700_driver
, dev
->name
));
5359 if (Status
== LM_STATUS_LINK_ACTIVE
) {
5360 if (pDevice
->LineSpeed
== LM_LINE_SPEED_1000MBPS
)
5362 else if (pDevice
->LineSpeed
== LM_LINE_SPEED_100MBPS
)
5364 else if (pDevice
->LineSpeed
== LM_LINE_SPEED_10MBPS
)
5367 B57_INFO(("%d Mbps ", speed
));
5369 if (pDevice
->DuplexMode
== LM_DUPLEX_MODE_FULL
)
5370 B57_INFO(("full duplex"));
5372 B57_INFO(("half duplex"));
5374 flow_control
= pDevice
->FlowControl
&
5375 (LM_FLOW_CONTROL_RECEIVE_PAUSE
|
5376 LM_FLOW_CONTROL_TRANSMIT_PAUSE
);
5378 if (flow_control
& LM_FLOW_CONTROL_RECEIVE_PAUSE
) {
5379 B57_INFO((", receive "));
5380 if (flow_control
& LM_FLOW_CONTROL_TRANSMIT_PAUSE
)
5381 B57_INFO(("& transmit "));
5384 B57_INFO((", transmit "));
5386 B57_INFO(("flow control ON"));
5390 return LM_STATUS_SUCCESS
;
5394 MM_UnmapRxDma(LM_DEVICE_BLOCK
*pDevice
, LM_PACKET
*pPacket
)
5396 #if !defined(NO_PCI_UNMAP)
5397 UM_DEVICE_BLOCK
*pUmDevice
= (UM_DEVICE_BLOCK
*) pDevice
;
5398 UM_PACKET
*pUmPacket
= (UM_PACKET
*) pPacket
;
5400 if (!pUmPacket
->skbuff
)
5403 pci_unmap_single(pUmDevice
->pdev
,
5404 pci_unmap_addr(pUmPacket
, map
[0]),
5405 pPacket
->u
.Rx
.RxBufferSize
,
5406 PCI_DMA_FROMDEVICE
);
5411 MM_FreeRxBuffer(PLM_DEVICE_BLOCK pDevice
, PLM_PACKET pPacket
)
5413 PUM_PACKET pUmPacket
;
5414 struct sk_buff
*skb
;
5417 return LM_STATUS_SUCCESS
;
5418 pUmPacket
= (PUM_PACKET
) pPacket
;
5419 if ((skb
= pUmPacket
->skbuff
)) {
5420 /* DMA address already unmapped */
5423 pUmPacket
->skbuff
= 0;
5424 return LM_STATUS_SUCCESS
;
5428 MM_Sleep(LM_DEVICE_BLOCK
*pDevice
, LM_UINT32 msec
)
5430 current
->state
= TASK_INTERRUPTIBLE
;
5431 if (schedule_timeout(HZ
* msec
/ 1000) != 0) {
5432 return LM_STATUS_FAILURE
;
5434 if (signal_pending(current
))
5435 return LM_STATUS_FAILURE
;
5437 return LM_STATUS_SUCCESS
;
5441 bcm5700_shutdown(UM_DEVICE_BLOCK
*pUmDevice
)
5443 LM_DEVICE_BLOCK
*pDevice
= (LM_DEVICE_BLOCK
*) pUmDevice
;
5445 bcm5700_intr_off(pUmDevice
);
5446 netif_carrier_off(pUmDevice
->dev
);
5448 tasklet_kill(&pUmDevice
->tasklet
);
5450 bcm5700_poll_wait(pUmDevice
);
5454 pDevice
->InitDone
= 0;
5455 bcm5700_free_remaining_rx_bufs(pUmDevice
);
5459 bcm5700_free_remaining_rx_bufs(UM_DEVICE_BLOCK
*pUmDevice
)
5461 LM_DEVICE_BLOCK
*pDevice
= &pUmDevice
->lm_dev
;
5462 UM_PACKET
*pUmPacket
;
5465 cnt
= QQ_GetEntryCnt(&pUmDevice
->rx_out_of_buf_q
.Container
);
5466 for (i
= 0; i
< cnt
; i
++) {
5468 QQ_PopHead(&pUmDevice
->rx_out_of_buf_q
.Container
))
5471 MM_UnmapRxDma(pDevice
, (LM_PACKET
*) pUmPacket
);
5472 MM_FreeRxBuffer(pDevice
, &pUmPacket
->lm_packet
);
5473 QQ_PushTail(&pDevice
->RxPacketFreeQ
.Container
,
5480 bcm5700_validate_param_range(UM_DEVICE_BLOCK
*pUmDevice
, int *param
,
5481 char *param_name
, int min
, int max
, int deflt
)
5483 if (((unsigned int) *param
< (unsigned int) min
) ||
5484 ((unsigned int) *param
> (unsigned int) max
)) {
5486 printk(KERN_WARNING
"%s-%d: Invalid %s parameter (%u), using %u\n", bcm5700_driver
, pUmDevice
->index
, param_name
, (unsigned int) *param
, (unsigned int) deflt
);
5492 bcm5700_find_peer(struct net_device
*dev
)
5494 struct net_device
*tmp_dev
;
5495 UM_DEVICE_BLOCK
*pUmDevice
, *pUmTmp
;
5496 LM_DEVICE_BLOCK
*pDevice
;
5499 pUmDevice
= (UM_DEVICE_BLOCK
*) dev
->priv
;
5500 pDevice
= &pUmDevice
->lm_dev
;
5501 if (T3_ASIC_REV(pDevice
->ChipRevId
) == T3_ASIC_REV_5704
) {
5502 tmp_dev
= root_tigon3_dev
;
5504 pUmTmp
= (PUM_DEVICE_BLOCK
) tmp_dev
->priv
;
5505 if ((tmp_dev
!= dev
) &&
5506 (pUmDevice
->pdev
->bus
->number
==
5507 pUmTmp
->pdev
->bus
->number
) &&
5508 PCI_SLOT(pUmDevice
->pdev
->devfn
) ==
5509 PCI_SLOT(pUmTmp
->pdev
->devfn
)) {
5513 tmp_dev
= pUmTmp
->next_module
;
5520 MM_FindPeerDev(LM_DEVICE_BLOCK
*pDevice
)
5522 UM_DEVICE_BLOCK
*pUmDevice
= (UM_DEVICE_BLOCK
*) pDevice
;
5523 struct net_device
*dev
= pUmDevice
->dev
;
5524 struct net_device
*peer_dev
;
5526 peer_dev
= bcm5700_find_peer(dev
);
5529 return ((LM_DEVICE_BLOCK
*) peer_dev
->priv
);
5532 int MM_FindCapability(LM_DEVICE_BLOCK
*pDevice
, int capability
)
5534 UM_DEVICE_BLOCK
*pUmDevice
= (UM_DEVICE_BLOCK
*) pDevice
;
5535 return (pci_find_capability(pUmDevice
->pdev
, capability
));
5538 #if defined(HAVE_POLL_CONTROLLER)||defined(CONFIG_NET_POLL_CONTROLLER)
5540 poll_bcm5700(struct net_device
*dev
)
5542 UM_DEVICE_BLOCK
*pUmDevice
= dev
->priv
;
5544 #if defined(RED_HAT_LINUX_KERNEL) && (LINUX_VERSION_CODE < 0x020605)
5546 bcm5700_interrupt(pUmDevice
->pdev
->irq
, dev
, NULL
);
5547 #ifdef BCM_NAPI_RXPOLL
5548 if (dev
->poll_list
.prev
) {
5551 bcm5700_poll(dev
, &budget
);
5558 disable_irq(pUmDevice
->pdev
->irq
);
5559 bcm5700_interrupt(pUmDevice
->pdev
->irq
, dev
, NULL
);
5560 enable_irq(pUmDevice
->pdev
->irq
);