2006-10-21 23:33:03 +04:00
/*
* Copyright ( C ) 2003 - 2006 NetXen , Inc .
* All rights reserved .
2006-12-04 20:18:00 +03:00
*
2006-10-21 23:33:03 +04:00
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
2006-11-29 20:00:10 +03:00
*
2006-10-21 23:33:03 +04:00
* This program is distributed in the hope that it will be useful , but
* WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2006-11-29 20:00:10 +03:00
*
2006-10-21 23:33:03 +04:00
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place - Suite 330 , Boston ,
* MA 02111 - 1307 , USA .
2006-12-04 20:18:00 +03:00
*
2006-10-21 23:33:03 +04:00
* The full GNU General Public License is included in this distribution
* in the file called LICENSE .
2006-12-04 20:18:00 +03:00
*
2006-10-21 23:33:03 +04:00
* Contact Information :
* info @ netxen . com
* NetXen ,
* 3965 Freedom Circle , Fourth floor ,
* Santa Clara , CA 95054
*
*
* Source file for NIC routines to access the Phantom hardware
*
*/
# include "netxen_nic.h"
# include "netxen_nic_hw.h"
# include "netxen_nic_phan_reg.h"
2007-04-20 18:52:37 +04:00
2007-03-13 02:09:15 +03:00
# include <net/ip.h>
2007-04-20 18:52:37 +04:00
struct netxen_recv_crb recv_crb_registers [ ] = {
/*
* Instance 0.
*/
{
/* rcv_desc_crb: */
{
{
/* crb_rcv_producer_offset: */
NETXEN_NIC_REG ( 0x100 ) ,
/* crb_rcv_consumer_offset: */
NETXEN_NIC_REG ( 0x104 ) ,
/* crb_gloablrcv_ring: */
NETXEN_NIC_REG ( 0x108 ) ,
/* crb_rcv_ring_size */
NETXEN_NIC_REG ( 0x10c ) ,
} ,
/* Jumbo frames */
{
/* crb_rcv_producer_offset: */
NETXEN_NIC_REG ( 0x110 ) ,
/* crb_rcv_consumer_offset: */
NETXEN_NIC_REG ( 0x114 ) ,
/* crb_gloablrcv_ring: */
NETXEN_NIC_REG ( 0x118 ) ,
/* crb_rcv_ring_size */
NETXEN_NIC_REG ( 0x11c ) ,
} ,
/* LRO */
{
/* crb_rcv_producer_offset: */
NETXEN_NIC_REG ( 0x120 ) ,
/* crb_rcv_consumer_offset: */
NETXEN_NIC_REG ( 0x124 ) ,
/* crb_gloablrcv_ring: */
NETXEN_NIC_REG ( 0x128 ) ,
/* crb_rcv_ring_size */
NETXEN_NIC_REG ( 0x12c ) ,
}
} ,
/* crb_rcvstatus_ring: */
NETXEN_NIC_REG ( 0x130 ) ,
/* crb_rcv_status_producer: */
NETXEN_NIC_REG ( 0x134 ) ,
/* crb_rcv_status_consumer: */
NETXEN_NIC_REG ( 0x138 ) ,
/* crb_rcvpeg_state: */
NETXEN_NIC_REG ( 0x13c ) ,
/* crb_status_ring_size */
NETXEN_NIC_REG ( 0x140 ) ,
} ,
/*
* Instance 1 ,
*/
{
/* rcv_desc_crb: */
{
{
/* crb_rcv_producer_offset: */
NETXEN_NIC_REG ( 0x144 ) ,
/* crb_rcv_consumer_offset: */
NETXEN_NIC_REG ( 0x148 ) ,
/* crb_globalrcv_ring: */
NETXEN_NIC_REG ( 0x14c ) ,
/* crb_rcv_ring_size */
NETXEN_NIC_REG ( 0x150 ) ,
} ,
/* Jumbo frames */
{
/* crb_rcv_producer_offset: */
NETXEN_NIC_REG ( 0x154 ) ,
/* crb_rcv_consumer_offset: */
NETXEN_NIC_REG ( 0x158 ) ,
/* crb_globalrcv_ring: */
NETXEN_NIC_REG ( 0x15c ) ,
/* crb_rcv_ring_size */
NETXEN_NIC_REG ( 0x160 ) ,
} ,
/* LRO */
{
/* crb_rcv_producer_offset: */
NETXEN_NIC_REG ( 0x164 ) ,
/* crb_rcv_consumer_offset: */
NETXEN_NIC_REG ( 0x168 ) ,
/* crb_globalrcv_ring: */
NETXEN_NIC_REG ( 0x16c ) ,
/* crb_rcv_ring_size */
NETXEN_NIC_REG ( 0x170 ) ,
}
} ,
/* crb_rcvstatus_ring: */
NETXEN_NIC_REG ( 0x174 ) ,
/* crb_rcv_status_producer: */
NETXEN_NIC_REG ( 0x178 ) ,
/* crb_rcv_status_consumer: */
NETXEN_NIC_REG ( 0x17c ) ,
/* crb_rcvpeg_state: */
NETXEN_NIC_REG ( 0x180 ) ,
/* crb_status_ring_size */
NETXEN_NIC_REG ( 0x184 ) ,
} ,
2007-04-20 18:53:52 +04:00
/*
2007-04-20 18:55:26 +04:00
* Instance 2 ,
2007-04-20 18:53:52 +04:00
*/
{
{
{
/* crb_rcv_producer_offset: */
NETXEN_NIC_REG ( 0x1d8 ) ,
/* crb_rcv_consumer_offset: */
NETXEN_NIC_REG ( 0x1dc ) ,
/* crb_gloablrcv_ring: */
NETXEN_NIC_REG ( 0x1f0 ) ,
/* crb_rcv_ring_size */
NETXEN_NIC_REG ( 0x1f4 ) ,
} ,
/* Jumbo frames */
{
2007-11-24 05:23:36 +03:00
/* crb_rcv_producer_offset: */
2007-04-20 18:53:52 +04:00
NETXEN_NIC_REG ( 0x1f8 ) ,
/* crb_rcv_consumer_offset: */
NETXEN_NIC_REG ( 0x1fc ) ,
/* crb_gloablrcv_ring: */
NETXEN_NIC_REG ( 0x200 ) ,
/* crb_rcv_ring_size */
NETXEN_NIC_REG ( 0x204 ) ,
} ,
/* LRO */
{
/* crb_rcv_producer_offset: */
NETXEN_NIC_REG ( 0x208 ) ,
/* crb_rcv_consumer_offset: */
NETXEN_NIC_REG ( 0x20c ) ,
/* crb_gloablrcv_ring: */
NETXEN_NIC_REG ( 0x210 ) ,
/* crb_rcv_ring_size */
NETXEN_NIC_REG ( 0x214 ) ,
}
} ,
/* crb_rcvstatus_ring: */
NETXEN_NIC_REG ( 0x218 ) ,
/* crb_rcv_status_producer: */
NETXEN_NIC_REG ( 0x21c ) ,
/* crb_rcv_status_consumer: */
NETXEN_NIC_REG ( 0x220 ) ,
/* crb_rcvpeg_state: */
NETXEN_NIC_REG ( 0x224 ) ,
/* crb_status_ring_size */
NETXEN_NIC_REG ( 0x228 ) ,
} ,
/*
2007-04-20 18:55:26 +04:00
* Instance 3 ,
2007-04-20 18:53:52 +04:00
*/
{
{
{
/* crb_rcv_producer_offset: */
NETXEN_NIC_REG ( 0x22c ) ,
/* crb_rcv_consumer_offset: */
NETXEN_NIC_REG ( 0x230 ) ,
/* crb_gloablrcv_ring: */
NETXEN_NIC_REG ( 0x234 ) ,
/* crb_rcv_ring_size */
NETXEN_NIC_REG ( 0x238 ) ,
} ,
/* Jumbo frames */
{
2007-11-24 05:23:36 +03:00
/* crb_rcv_producer_offset: */
2007-04-20 18:53:52 +04:00
NETXEN_NIC_REG ( 0x23c ) ,
/* crb_rcv_consumer_offset: */
NETXEN_NIC_REG ( 0x240 ) ,
/* crb_gloablrcv_ring: */
NETXEN_NIC_REG ( 0x244 ) ,
/* crb_rcv_ring_size */
NETXEN_NIC_REG ( 0x248 ) ,
} ,
/* LRO */
{
/* crb_rcv_producer_offset: */
NETXEN_NIC_REG ( 0x24c ) ,
/* crb_rcv_consumer_offset: */
NETXEN_NIC_REG ( 0x250 ) ,
/* crb_gloablrcv_ring: */
NETXEN_NIC_REG ( 0x254 ) ,
/* crb_rcv_ring_size */
NETXEN_NIC_REG ( 0x258 ) ,
}
} ,
/* crb_rcvstatus_ring: */
NETXEN_NIC_REG ( 0x25c ) ,
/* crb_rcv_status_producer: */
NETXEN_NIC_REG ( 0x260 ) ,
/* crb_rcv_status_consumer: */
NETXEN_NIC_REG ( 0x264 ) ,
/* crb_rcvpeg_state: */
NETXEN_NIC_REG ( 0x268 ) ,
/* crb_status_ring_size */
NETXEN_NIC_REG ( 0x26c ) ,
} ,
2007-04-20 18:52:37 +04:00
} ;
2007-11-05 20:07:31 +03:00
static u64 ctx_addr_sig_regs [ ] [ 3 ] = {
2007-04-20 18:52:37 +04:00
{ NETXEN_NIC_REG ( 0x188 ) , NETXEN_NIC_REG ( 0x18c ) , NETXEN_NIC_REG ( 0x1c0 ) } ,
{ NETXEN_NIC_REG ( 0x190 ) , NETXEN_NIC_REG ( 0x194 ) , NETXEN_NIC_REG ( 0x1c4 ) } ,
{ NETXEN_NIC_REG ( 0x198 ) , NETXEN_NIC_REG ( 0x19c ) , NETXEN_NIC_REG ( 0x1c8 ) } ,
{ NETXEN_NIC_REG ( 0x1a0 ) , NETXEN_NIC_REG ( 0x1a4 ) , NETXEN_NIC_REG ( 0x1cc ) }
} ;
2007-11-05 20:07:31 +03:00
# define CRB_CTX_ADDR_REG_LO(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][0])
# define CRB_CTX_ADDR_REG_HI(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][2])
# define CRB_CTX_SIGNATURE_REG(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][1])
2007-04-20 18:52:37 +04:00
2006-10-21 23:33:03 +04:00
/* PCI Windowing for DDR regions. */
# define ADDR_IN_RANGE(addr, low, high) \
( ( ( addr ) < = ( high ) ) & & ( ( addr ) > = ( low ) ) )
2007-06-07 15:36:36 +04:00
# define NETXEN_FLASH_BASE (NETXEN_BOOTLD_START)
2006-10-21 23:33:03 +04:00
# define NETXEN_PHANTOM_MEM_BASE (NETXEN_FLASH_BASE)
2006-12-04 20:23:25 +03:00
# define NETXEN_MAX_MTU 8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE
2006-11-29 20:00:10 +03:00
# define NETXEN_MIN_MTU 64
2006-10-21 23:33:03 +04:00
# define NETXEN_ETH_FCS_SIZE 4
# define NETXEN_ENET_HEADER_SIZE 14
2006-11-29 20:00:10 +03:00
# define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */
2006-10-21 23:33:03 +04:00
# define NETXEN_FIRMWARE_LEN ((16 * 1024) / 4)
# define NETXEN_NIU_HDRSIZE (0x1 << 6)
# define NETXEN_NIU_TLRSIZE (0x1 << 5)
2006-11-29 20:00:10 +03:00
# define lower32(x) ((u32)((x) & 0xffffffff))
# define upper32(x) \
( ( u32 ) ( ( ( unsigned long long ) ( x ) > > 32 ) & 0xffffffff ) )
# define NETXEN_NIC_ZERO_PAUSE_ADDR 0ULL
# define NETXEN_NIC_UNIT_PAUSE_ADDR 0x200ULL
# define NETXEN_NIC_EPG_PAUSE_ADDR1 0x2200010000c28001ULL
# define NETXEN_NIC_EPG_PAUSE_ADDR2 0x0100088866554433ULL
# define NETXEN_NIC_WINDOW_MARGIN 0x100000
2007-11-05 20:07:31 +03:00
static unsigned long netxen_nic_pci_set_window ( struct netxen_adapter * adapter ,
unsigned long long addr ) ;
2006-10-21 23:33:03 +04:00
void netxen_free_hw_resources ( struct netxen_adapter * adapter ) ;
int netxen_nic_set_mac ( struct net_device * netdev , void * p )
{
2007-04-20 18:52:37 +04:00
struct netxen_adapter * adapter = netdev_priv ( netdev ) ;
2006-10-21 23:33:03 +04:00
struct sockaddr * addr = p ;
if ( netif_running ( netdev ) )
return - EBUSY ;
if ( ! is_valid_ether_addr ( addr - > sa_data ) )
return - EADDRNOTAVAIL ;
DPRINTK ( INFO , " valid ether addr \n " ) ;
memcpy ( netdev - > dev_addr , addr - > sa_data , netdev - > addr_len ) ;
2006-12-04 20:18:00 +03:00
if ( adapter - > macaddr_set )
2007-04-20 18:52:37 +04:00
adapter - > macaddr_set ( adapter , addr - > sa_data ) ;
2006-10-21 23:33:03 +04:00
return 0 ;
}
/*
* netxen_nic_set_multi - Multicast
*/
void netxen_nic_set_multi ( struct net_device * netdev )
{
2007-04-20 18:52:37 +04:00
struct netxen_adapter * adapter = netdev_priv ( netdev ) ;
2006-10-21 23:33:03 +04:00
struct dev_mc_list * mc_ptr ;
mc_ptr = netdev - > mc_list ;
if ( netdev - > flags & IFF_PROMISC ) {
2006-12-04 20:18:00 +03:00
if ( adapter - > set_promisc )
adapter - > set_promisc ( adapter ,
NETXEN_NIU_PROMISC_MODE ) ;
2006-10-21 23:33:03 +04:00
} else {
2007-04-20 18:55:26 +04:00
if ( adapter - > unset_promisc )
2006-12-04 20:18:00 +03:00
adapter - > unset_promisc ( adapter ,
NETXEN_NIU_NON_PROMISC_MODE ) ;
2006-10-21 23:33:03 +04:00
}
}
/*
* netxen_nic_change_mtu - Change the Maximum Transfer Unit
* @ returns 0 on success , negative on failure
*/
int netxen_nic_change_mtu ( struct net_device * netdev , int mtu )
{
2007-04-20 18:52:37 +04:00
struct netxen_adapter * adapter = netdev_priv ( netdev ) ;
2006-10-21 23:33:03 +04:00
int eff_mtu = mtu + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE ;
if ( ( eff_mtu > NETXEN_MAX_MTU ) | | ( eff_mtu < NETXEN_MIN_MTU ) ) {
printk ( KERN_ERR " %s: %s %d is not supported. \n " ,
netxen_nic_driver_name , netdev - > name , mtu ) ;
return - EINVAL ;
}
2006-12-04 20:18:00 +03:00
if ( adapter - > set_mtu )
2007-04-20 18:52:37 +04:00
adapter - > set_mtu ( adapter , mtu ) ;
2006-10-21 23:33:03 +04:00
netdev - > mtu = mtu ;
return 0 ;
}
/*
* check if the firmware has been downloaded and ready to run and
* setup the address for the descriptors in the adapter
*/
int netxen_nic_hw_resources ( struct netxen_adapter * adapter )
{
struct netxen_hardware_context * hw = & adapter - > ahw ;
u32 state = 0 ;
void * addr ;
int loops = 0 , err = 0 ;
int ctx , ring ;
struct netxen_recv_context * recv_ctx ;
struct netxen_rcv_desc_ctx * rcv_desc ;
2007-04-20 18:53:52 +04:00
int func_id = adapter - > portnum ;
2006-10-21 23:33:03 +04:00
2006-12-04 20:18:00 +03:00
DPRINTK ( INFO , " crb_base: %lx %x " , NETXEN_PCI_CRBSPACE ,
2006-11-29 20:00:10 +03:00
PCI_OFFSET_SECOND_RANGE ( adapter , NETXEN_PCI_CRBSPACE ) ) ;
2006-12-04 20:18:00 +03:00
DPRINTK ( INFO , " cam base: %lx %x " , NETXEN_CRB_CAM ,
2006-11-29 20:00:10 +03:00
pci_base_offset ( adapter , NETXEN_CRB_CAM ) ) ;
2006-12-04 20:18:00 +03:00
DPRINTK ( INFO , " cam RAM: %lx %x " , NETXEN_CAM_RAM_BASE ,
2006-11-29 20:00:10 +03:00
pci_base_offset ( adapter , NETXEN_CAM_RAM_BASE ) ) ;
2006-10-21 23:33:03 +04:00
for ( ctx = 0 ; ctx < MAX_RCV_CTX ; + + ctx ) {
DPRINTK ( INFO , " Command Peg ready..waiting for rcv peg \n " ) ;
loops = 0 ;
state = 0 ;
/* Window 1 call */
state = readl ( NETXEN_CRB_NORMALIZE ( adapter ,
recv_crb_registers [ ctx ] .
crb_rcvpeg_state ) ) ;
while ( state ! = PHAN_PEG_RCV_INITIALIZED & & loops < 20 ) {
2007-07-02 08:07:57 +04:00
msleep ( 1 ) ;
2006-10-21 23:33:03 +04:00
/* Window 1 call */
state = readl ( NETXEN_CRB_NORMALIZE ( adapter ,
recv_crb_registers
[ ctx ] .
crb_rcvpeg_state ) ) ;
loops + + ;
}
if ( loops > = 20 ) {
printk ( KERN_ERR " Rcv Peg initialization not complete: "
" %x. \n " , state ) ;
err = - EIO ;
return err ;
}
}
2007-07-01 22:56:00 +04:00
adapter - > intr_scheme = readl (
NETXEN_CRB_NORMALIZE ( adapter , CRB_NIC_CAPABILITIES_FW ) ) ;
2007-07-02 08:07:57 +04:00
printk ( KERN_NOTICE " %s: FW capabilities:0x%x \n " , netxen_nic_driver_name ,
2007-07-01 22:56:00 +04:00
adapter - > intr_scheme ) ;
DPRINTK ( INFO , " Receive Peg ready too. starting stuff \n " ) ;
2006-10-21 23:33:03 +04:00
2006-11-29 20:00:10 +03:00
addr = netxen_alloc ( adapter - > ahw . pdev ,
2006-12-04 20:23:25 +03:00
sizeof ( struct netxen_ring_ctx ) +
sizeof ( uint32_t ) ,
( dma_addr_t * ) & adapter - > ctx_desc_phys_addr ,
& adapter - > ctx_desc_pdev ) ;
2006-11-29 20:00:10 +03:00
2007-04-20 18:52:37 +04:00
printk ( KERN_INFO " ctx_desc_phys_addr: 0x%llx \n " ,
2007-03-06 23:35:37 +03:00
( unsigned long long ) adapter - > ctx_desc_phys_addr ) ;
2006-10-21 23:33:03 +04:00
if ( addr = = NULL ) {
DPRINTK ( ERR , " bad return from pci_alloc_consistent \n " ) ;
2006-12-04 20:23:25 +03:00
err = - ENOMEM ;
return err ;
2006-11-29 20:00:10 +03:00
}
2006-12-04 20:23:25 +03:00
memset ( addr , 0 , sizeof ( struct netxen_ring_ctx ) ) ;
adapter - > ctx_desc = ( struct netxen_ring_ctx * ) addr ;
2007-04-20 18:55:26 +04:00
adapter - > ctx_desc - > ctx_id = cpu_to_le32 ( adapter - > portnum ) ;
2007-01-02 13:39:10 +03:00
adapter - > ctx_desc - > cmd_consumer_offset =
cpu_to_le64 ( adapter - > ctx_desc_phys_addr +
sizeof ( struct netxen_ring_ctx ) ) ;
2006-12-04 20:23:25 +03:00
adapter - > cmd_consumer = ( uint32_t * ) ( ( ( char * ) addr ) +
sizeof ( struct netxen_ring_ctx ) ) ;
2007-02-21 17:37:06 +03:00
addr = netxen_alloc ( adapter - > ahw . pdev ,
sizeof ( struct cmd_desc_type0 ) *
adapter - > max_tx_desc_count ,
( dma_addr_t * ) & hw - > cmd_desc_phys_addr ,
& adapter - > ahw . cmd_desc_pdev ) ;
2007-04-20 18:52:37 +04:00
printk ( KERN_INFO " cmd_desc_phys_addr: 0x%llx \n " ,
2007-03-06 23:35:37 +03:00
( unsigned long long ) hw - > cmd_desc_phys_addr ) ;
2006-11-29 20:00:10 +03:00
2006-12-04 20:23:25 +03:00
if ( addr = = NULL ) {
DPRINTK ( ERR , " bad return from pci_alloc_consistent \n " ) ;
netxen_free_hw_resources ( adapter ) ;
2006-11-29 20:00:10 +03:00
return - ENOMEM ;
2006-10-21 23:33:03 +04:00
}
2007-01-02 13:39:10 +03:00
adapter - > ctx_desc - > cmd_ring_addr =
cpu_to_le64 ( hw - > cmd_desc_phys_addr ) ;
adapter - > ctx_desc - > cmd_ring_size =
cpu_to_le32 ( adapter - > max_tx_desc_count ) ;
2006-10-21 23:33:03 +04:00
hw - > cmd_desc_head = ( struct cmd_desc_type0 * ) addr ;
for ( ctx = 0 ; ctx < MAX_RCV_CTX ; + + ctx ) {
recv_ctx = & adapter - > recv_ctx [ ctx ] ;
for ( ring = 0 ; ring < NUM_RCV_DESC_RINGS ; ring + + ) {
rcv_desc = & recv_ctx - > rcv_desc [ ring ] ;
2006-11-29 20:00:10 +03:00
addr = netxen_alloc ( adapter - > ahw . pdev ,
RCV_DESC_RINGSIZE ,
& rcv_desc - > phys_addr ,
& rcv_desc - > phys_pdev ) ;
2006-10-21 23:33:03 +04:00
if ( addr = = NULL ) {
DPRINTK ( ERR , " bad return from "
" pci_alloc_consistent \n " ) ;
netxen_free_hw_resources ( adapter ) ;
err = - ENOMEM ;
return err ;
}
rcv_desc - > desc_head = ( struct rcv_desc * ) addr ;
2007-01-02 13:39:10 +03:00
adapter - > ctx_desc - > rcv_ctx [ ring ] . rcv_ring_addr =
cpu_to_le64 ( rcv_desc - > phys_addr ) ;
2006-12-04 20:23:25 +03:00
adapter - > ctx_desc - > rcv_ctx [ ring ] . rcv_ring_size =
2007-01-02 13:39:10 +03:00
cpu_to_le32 ( rcv_desc - > max_rx_desc_count ) ;
2006-10-21 23:33:03 +04:00
}
2006-12-01 16:36:22 +03:00
addr = netxen_alloc ( adapter - > ahw . pdev , STATUS_DESC_RINGSIZE ,
& recv_ctx - > rcv_status_desc_phys_addr ,
2006-11-29 20:00:10 +03:00
& recv_ctx - > rcv_status_desc_pdev ) ;
2006-10-21 23:33:03 +04:00
if ( addr = = NULL ) {
DPRINTK ( ERR , " bad return from "
" pci_alloc_consistent \n " ) ;
netxen_free_hw_resources ( adapter ) ;
err = - ENOMEM ;
return err ;
}
recv_ctx - > rcv_status_desc_head = ( struct status_desc * ) addr ;
2007-01-02 13:39:10 +03:00
adapter - > ctx_desc - > sts_ring_addr =
cpu_to_le64 ( recv_ctx - > rcv_status_desc_phys_addr ) ;
adapter - > ctx_desc - > sts_ring_size =
cpu_to_le32 ( adapter - > max_rx_desc_count ) ;
2006-10-21 23:33:03 +04:00
}
/* Window = 1 */
2006-12-04 20:23:25 +03:00
writel ( lower32 ( adapter - > ctx_desc_phys_addr ) ,
2007-04-20 18:53:52 +04:00
NETXEN_CRB_NORMALIZE ( adapter , CRB_CTX_ADDR_REG_LO ( func_id ) ) ) ;
2006-12-04 20:23:25 +03:00
writel ( upper32 ( adapter - > ctx_desc_phys_addr ) ,
2007-04-20 18:53:52 +04:00
NETXEN_CRB_NORMALIZE ( adapter , CRB_CTX_ADDR_REG_HI ( func_id ) ) ) ;
writel ( NETXEN_CTX_SIGNATURE | func_id ,
NETXEN_CRB_NORMALIZE ( adapter , CRB_CTX_SIGNATURE_REG ( func_id ) ) ) ;
2006-10-21 23:33:03 +04:00
return err ;
}
void netxen_free_hw_resources ( struct netxen_adapter * adapter )
{
struct netxen_recv_context * recv_ctx ;
struct netxen_rcv_desc_ctx * rcv_desc ;
int ctx , ring ;
2006-12-04 20:23:25 +03:00
if ( adapter - > ctx_desc ! = NULL ) {
pci_free_consistent ( adapter - > ctx_desc_pdev ,
sizeof ( struct netxen_ring_ctx ) +
sizeof ( uint32_t ) ,
adapter - > ctx_desc ,
adapter - > ctx_desc_phys_addr ) ;
adapter - > ctx_desc = NULL ;
}
2006-10-21 23:33:03 +04:00
if ( adapter - > ahw . cmd_desc_head ! = NULL ) {
2006-11-29 20:00:10 +03:00
pci_free_consistent ( adapter - > ahw . cmd_desc_pdev ,
2006-10-21 23:33:03 +04:00
sizeof ( struct cmd_desc_type0 ) *
adapter - > max_tx_desc_count ,
adapter - > ahw . cmd_desc_head ,
adapter - > ahw . cmd_desc_phys_addr ) ;
adapter - > ahw . cmd_desc_head = NULL ;
}
for ( ctx = 0 ; ctx < MAX_RCV_CTX ; + + ctx ) {
recv_ctx = & adapter - > recv_ctx [ ctx ] ;
for ( ring = 0 ; ring < NUM_RCV_DESC_RINGS ; ring + + ) {
rcv_desc = & recv_ctx - > rcv_desc [ ring ] ;
if ( rcv_desc - > desc_head ! = NULL ) {
2006-11-29 20:00:10 +03:00
pci_free_consistent ( rcv_desc - > phys_pdev ,
2006-10-21 23:33:03 +04:00
RCV_DESC_RINGSIZE ,
rcv_desc - > desc_head ,
rcv_desc - > phys_addr ) ;
rcv_desc - > desc_head = NULL ;
}
}
if ( recv_ctx - > rcv_status_desc_head ! = NULL ) {
2006-11-29 20:00:10 +03:00
pci_free_consistent ( recv_ctx - > rcv_status_desc_pdev ,
2006-10-21 23:33:03 +04:00
STATUS_DESC_RINGSIZE ,
recv_ctx - > rcv_status_desc_head ,
recv_ctx - >
rcv_status_desc_phys_addr ) ;
recv_ctx - > rcv_status_desc_head = NULL ;
}
}
}
void netxen_tso_check ( struct netxen_adapter * adapter ,
struct cmd_desc_type0 * desc , struct sk_buff * skb )
{
if ( desc - > mss ) {
2007-03-13 02:09:15 +03:00
desc - > total_hdr_length = ( sizeof ( struct ethhdr ) +
2007-03-19 03:43:48 +03:00
ip_hdrlen ( skb ) + tcp_hdrlen ( skb ) ) ;
2006-12-04 20:23:25 +03:00
netxen_set_cmd_desc_opcode ( desc , TX_TCP_LSO ) ;
2006-12-18 16:51:58 +03:00
} else if ( skb - > ip_summed = = CHECKSUM_PARTIAL ) {
2007-04-21 09:47:35 +04:00
if ( ip_hdr ( skb ) - > protocol = = IPPROTO_TCP ) {
2006-12-04 20:23:25 +03:00
netxen_set_cmd_desc_opcode ( desc , TX_TCP_PKT ) ;
2007-04-21 09:47:35 +04:00
} else if ( ip_hdr ( skb ) - > protocol = = IPPROTO_UDP ) {
2006-12-04 20:23:25 +03:00
netxen_set_cmd_desc_opcode ( desc , TX_UDP_PKT ) ;
2006-10-21 23:33:03 +04:00
} else {
return ;
}
}
2007-04-26 04:55:53 +04:00
desc - > tcp_hdr_offset = skb_transport_offset ( skb ) ;
2007-03-11 04:16:10 +03:00
desc - > ip_hdr_offset = skb_network_offset ( skb ) ;
2006-10-21 23:33:03 +04:00
}
int netxen_is_flash_supported ( struct netxen_adapter * adapter )
{
const int locs [ ] = { 0 , 0x4 , 0x100 , 0x4000 , 0x4128 } ;
int addr , val01 , val02 , i , j ;
/* if the flash size less than 4Mb, make huge war cry and die */
for ( j = 1 ; j < 4 ; j + + ) {
2006-11-29 20:00:10 +03:00
addr = j * NETXEN_NIC_WINDOW_MARGIN ;
2007-09-02 14:30:18 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( locs ) ; i + + ) {
2006-10-21 23:33:03 +04:00
if ( netxen_rom_fast_read ( adapter , locs [ i ] , & val01 ) = = 0
& & netxen_rom_fast_read ( adapter , ( addr + locs [ i ] ) ,
& val02 ) = = 0 ) {
if ( val01 = = val02 )
return - 1 ;
} else
return - 1 ;
}
}
return 0 ;
}
static int netxen_get_flash_block ( struct netxen_adapter * adapter , int base ,
int size , u32 * buf )
{
int i , addr ;
u32 * ptr32 ;
addr = base ;
ptr32 = buf ;
for ( i = 0 ; i < size / sizeof ( u32 ) ; i + + ) {
if ( netxen_rom_fast_read ( adapter , addr , ptr32 ) = = - 1 )
return - 1 ;
2007-02-09 16:45:18 +03:00
* ptr32 = cpu_to_le32 ( * ptr32 ) ;
2006-10-21 23:33:03 +04:00
ptr32 + + ;
addr + = sizeof ( u32 ) ;
}
if ( ( char * ) buf + size > ( char * ) ptr32 ) {
u32 local ;
if ( netxen_rom_fast_read ( adapter , addr , & local ) = = - 1 )
return - 1 ;
2007-02-09 16:45:18 +03:00
local = cpu_to_le32 ( local ) ;
2006-10-21 23:33:03 +04:00
memcpy ( ptr32 , & local , ( char * ) buf + size - ( char * ) ptr32 ) ;
}
return 0 ;
}
int netxen_get_flash_mac_addr ( struct netxen_adapter * adapter , u64 mac [ ] )
{
u32 * pmac = ( u32 * ) & mac [ 0 ] ;
if ( netxen_get_flash_block ( adapter ,
2007-06-07 15:36:36 +04:00
NETXEN_USER_START +
2006-10-21 23:33:03 +04:00
offsetof ( struct netxen_new_user_info ,
mac_addr ) ,
FLASH_NUM_PORTS * sizeof ( u64 ) , pmac ) = = - 1 ) {
return - 1 ;
}
if ( * mac = = ~ 0ULL ) {
if ( netxen_get_flash_block ( adapter ,
2007-06-07 15:36:36 +04:00
NETXEN_USER_START_OLD +
2006-10-21 23:33:03 +04:00
offsetof ( struct netxen_user_old_info ,
mac_addr ) ,
FLASH_NUM_PORTS * sizeof ( u64 ) ,
pmac ) = = - 1 )
return - 1 ;
if ( * mac = = ~ 0ULL )
return - 1 ;
}
return 0 ;
}
/*
* Changes the CRB window to the specified window .
*/
void netxen_nic_pci_change_crbwindow ( struct netxen_adapter * adapter , u32 wndw )
{
void __iomem * offset ;
u32 tmp ;
int count = 0 ;
if ( adapter - > curr_window = = wndw )
return ;
2007-04-20 18:53:05 +04:00
switch ( adapter - > ahw . pci_func ) {
2007-04-20 18:52:37 +04:00
case 0 :
offset = PCI_OFFSET_SECOND_RANGE ( adapter ,
NETXEN_PCIX_PH_REG ( PCIX_CRB_WINDOW ) ) ;
break ;
case 1 :
offset = PCI_OFFSET_SECOND_RANGE ( adapter ,
NETXEN_PCIX_PH_REG ( PCIX_CRB_WINDOW_F1 ) ) ;
break ;
case 2 :
offset = PCI_OFFSET_SECOND_RANGE ( adapter ,
NETXEN_PCIX_PH_REG ( PCIX_CRB_WINDOW_F2 ) ) ;
break ;
case 3 :
offset = PCI_OFFSET_SECOND_RANGE ( adapter ,
NETXEN_PCIX_PH_REG ( PCIX_CRB_WINDOW_F3 ) ) ;
break ;
default :
2007-11-20 04:48:24 +03:00
printk ( KERN_INFO " Changing the window for PCI function "
2007-04-20 18:53:05 +04:00
" %d \n " , adapter - > ahw . pci_func ) ;
2007-04-20 18:52:37 +04:00
offset = PCI_OFFSET_SECOND_RANGE ( adapter ,
NETXEN_PCIX_PH_REG ( PCIX_CRB_WINDOW ) ) ;
break ;
}
2006-10-21 23:33:03 +04:00
/*
* Move the CRB window .
* We need to write to the " direct access " region of PCI
* to avoid a race condition where the window register has
* not been successfully written across CRB before the target
* register address is received by PCI . The direct region bypasses
* the CRB bus .
*/
if ( wndw & 0x1 )
wndw = NETXEN_WINDOW_ONE ;
writel ( wndw , offset ) ;
/* MUST make sure window is set before we forge on... */
while ( ( tmp = readl ( offset ) ) ! = wndw ) {
printk ( KERN_WARNING " %s: %s WARNING: CRB window value not "
" registered properly: 0x%08x. \n " ,
netxen_nic_driver_name , __FUNCTION__ , tmp ) ;
mdelay ( 1 ) ;
if ( count > = 10 )
break ;
count + + ;
}
2007-04-20 18:55:26 +04:00
if ( wndw = = NETXEN_WINDOW_ONE )
adapter - > curr_window = 1 ;
else
adapter - > curr_window = 0 ;
2006-10-21 23:33:03 +04:00
}
2007-07-02 08:07:57 +04:00
int netxen_load_firmware ( struct netxen_adapter * adapter )
2006-10-21 23:33:03 +04:00
{
int i ;
2007-02-28 16:16:40 +03:00
u32 data , size = 0 ;
u32 flashaddr = NETXEN_FLASH_BASE , memaddr = NETXEN_PHANTOM_MEM_BASE ;
2006-10-21 23:33:03 +04:00
u64 off ;
void __iomem * addr ;
size = NETXEN_FIRMWARE_LEN ;
writel ( 1 , NETXEN_CRB_NORMALIZE ( adapter , NETXEN_ROMUSB_GLB_CAS_RST ) ) ;
for ( i = 0 ; i < size ; i + + ) {
2007-07-02 08:07:57 +04:00
int retries = 10 ;
if ( netxen_rom_fast_read ( adapter , flashaddr , ( int * ) & data ) ! = 0 )
return - EIO ;
2006-11-29 20:00:10 +03:00
off = netxen_nic_pci_set_window ( adapter , memaddr ) ;
addr = pci_base_offset ( adapter , off ) ;
2006-10-21 23:33:03 +04:00
writel ( data , addr ) ;
2007-07-02 08:07:57 +04:00
do {
if ( readl ( addr ) = = data )
break ;
msleep ( 100 ) ;
writel ( data , addr ) ;
} while ( - - retries ) ;
if ( ! retries ) {
printk ( KERN_ERR " %s: firmware load aborted, write failed at 0x%x \n " ,
netxen_nic_driver_name , memaddr ) ;
return - EIO ;
}
2006-10-21 23:33:03 +04:00
flashaddr + = 4 ;
memaddr + = 4 ;
}
udelay ( 100 ) ;
/* make sure Casper is powered on */
writel ( 0x3fff ,
NETXEN_CRB_NORMALIZE ( adapter , NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL ) ) ;
writel ( 0 , NETXEN_CRB_NORMALIZE ( adapter , NETXEN_ROMUSB_GLB_CAS_RST ) ) ;
2007-07-02 08:07:57 +04:00
return 0 ;
2006-10-21 23:33:03 +04:00
}
int
netxen_nic_hw_write_wx ( struct netxen_adapter * adapter , u64 off , void * data ,
int len )
{
void __iomem * addr ;
if ( ADDR_IN_WINDOW1 ( off ) ) {
addr = NETXEN_CRB_NORMALIZE ( adapter , off ) ;
} else { /* Window 0 */
2006-11-29 20:00:10 +03:00
addr = pci_base_offset ( adapter , off ) ;
2006-10-21 23:33:03 +04:00
netxen_nic_pci_change_crbwindow ( adapter , 0 ) ;
}
DPRINTK ( INFO , " writing to base %lx offset %llx addr %p "
" data %llx len %d \n " ,
2006-11-29 20:00:10 +03:00
pci_base ( adapter , off ) , off , addr ,
2006-10-21 23:33:03 +04:00
* ( unsigned long long * ) data , len ) ;
2006-11-29 20:00:10 +03:00
if ( ! addr ) {
netxen_nic_pci_change_crbwindow ( adapter , 1 ) ;
return 1 ;
}
2006-10-21 23:33:03 +04:00
switch ( len ) {
case 1 :
writeb ( * ( u8 * ) data , addr ) ;
break ;
case 2 :
writew ( * ( u16 * ) data , addr ) ;
break ;
case 4 :
writel ( * ( u32 * ) data , addr ) ;
break ;
case 8 :
writeq ( * ( u64 * ) data , addr ) ;
break ;
default :
DPRINTK ( INFO ,
" writing data %lx to offset %llx, num words=%d \n " ,
* ( unsigned long * ) data , off , ( len > > 3 ) ) ;
netxen_nic_hw_block_write64 ( ( u64 __iomem * ) data , addr ,
( len > > 3 ) ) ;
break ;
}
if ( ! ADDR_IN_WINDOW1 ( off ) )
netxen_nic_pci_change_crbwindow ( adapter , 1 ) ;
return 0 ;
}
int
netxen_nic_hw_read_wx ( struct netxen_adapter * adapter , u64 off , void * data ,
int len )
{
void __iomem * addr ;
if ( ADDR_IN_WINDOW1 ( off ) ) { /* Window 1 */
addr = NETXEN_CRB_NORMALIZE ( adapter , off ) ;
} else { /* Window 0 */
2006-11-29 20:00:10 +03:00
addr = pci_base_offset ( adapter , off ) ;
2006-10-21 23:33:03 +04:00
netxen_nic_pci_change_crbwindow ( adapter , 0 ) ;
}
DPRINTK ( INFO , " reading from base %lx offset %llx addr %p \n " ,
2006-11-29 20:00:10 +03:00
pci_base ( adapter , off ) , off , addr ) ;
if ( ! addr ) {
netxen_nic_pci_change_crbwindow ( adapter , 1 ) ;
return 1 ;
}
2006-10-21 23:33:03 +04:00
switch ( len ) {
case 1 :
* ( u8 * ) data = readb ( addr ) ;
break ;
case 2 :
* ( u16 * ) data = readw ( addr ) ;
break ;
case 4 :
* ( u32 * ) data = readl ( addr ) ;
break ;
case 8 :
* ( u64 * ) data = readq ( addr ) ;
break ;
default :
netxen_nic_hw_block_read64 ( ( u64 __iomem * ) data , addr ,
( len > > 3 ) ) ;
break ;
}
DPRINTK ( INFO , " read %lx \n " , * ( unsigned long * ) data ) ;
if ( ! ADDR_IN_WINDOW1 ( off ) )
netxen_nic_pci_change_crbwindow ( adapter , 1 ) ;
return 0 ;
}
void netxen_nic_reg_write ( struct netxen_adapter * adapter , u64 off , u32 val )
{ /* Only for window 1 */
void __iomem * addr ;
addr = NETXEN_CRB_NORMALIZE ( adapter , off ) ;
DPRINTK ( INFO , " writing to base %lx offset %llx addr %p data %x \n " ,
2006-12-04 20:18:00 +03:00
pci_base ( adapter , off ) , off , addr , val ) ;
2006-10-21 23:33:03 +04:00
writel ( val , addr ) ;
}
int netxen_nic_reg_read ( struct netxen_adapter * adapter , u64 off )
{ /* Only for window 1 */
void __iomem * addr ;
int val ;
addr = NETXEN_CRB_NORMALIZE ( adapter , off ) ;
DPRINTK ( INFO , " reading from base %lx offset %llx addr %p \n " ,
2006-12-04 20:18:00 +03:00
pci_base ( adapter , off ) , off , addr ) ;
2006-10-21 23:33:03 +04:00
val = readl ( addr ) ;
writel ( val , addr ) ;
return val ;
}
/* Change the window to 0, write and change back to window 1. */
void netxen_nic_write_w0 ( struct netxen_adapter * adapter , u32 index , u32 value )
{
void __iomem * addr ;
netxen_nic_pci_change_crbwindow ( adapter , 0 ) ;
2006-12-01 16:36:22 +03:00
addr = pci_base_offset ( adapter , index ) ;
2006-10-21 23:33:03 +04:00
writel ( value , addr ) ;
netxen_nic_pci_change_crbwindow ( adapter , 1 ) ;
}
/* Change the window to 0, read and change back to window 1. */
void netxen_nic_read_w0 ( struct netxen_adapter * adapter , u32 index , u32 * value )
{
void __iomem * addr ;
2006-12-01 16:36:22 +03:00
addr = pci_base_offset ( adapter , index ) ;
2006-10-21 23:33:03 +04:00
netxen_nic_pci_change_crbwindow ( adapter , 0 ) ;
* value = readl ( addr ) ;
netxen_nic_pci_change_crbwindow ( adapter , 1 ) ;
}
2007-11-24 05:23:36 +03:00
static int netxen_pci_set_window_warning_count ;
2006-10-21 23:33:03 +04:00
2007-11-05 20:07:31 +03:00
static unsigned long netxen_nic_pci_set_window ( struct netxen_adapter * adapter ,
unsigned long long addr )
2006-10-21 23:33:03 +04:00
{
static int ddr_mn_window = - 1 ;
static int qdr_sn_window = - 1 ;
int window ;
if ( ADDR_IN_RANGE ( addr , NETXEN_ADDR_DDR_NET , NETXEN_ADDR_DDR_NET_MAX ) ) {
/* DDR network side */
addr - = NETXEN_ADDR_DDR_NET ;
window = ( addr > > 25 ) & 0x3ff ;
if ( ddr_mn_window ! = window ) {
ddr_mn_window = window ;
2006-11-29 20:00:10 +03:00
writel ( window , PCI_OFFSET_SECOND_RANGE ( adapter ,
NETXEN_PCIX_PH_REG
2007-08-28 15:53:26 +04:00
( PCIX_MN_WINDOW ( adapter - > ahw . pci_func ) ) ) ) ;
2006-10-21 23:33:03 +04:00
/* MUST make sure window is set before we forge on... */
2006-11-29 20:00:10 +03:00
readl ( PCI_OFFSET_SECOND_RANGE ( adapter ,
NETXEN_PCIX_PH_REG
2007-08-28 15:53:26 +04:00
( PCIX_MN_WINDOW ( adapter - > ahw . pci_func ) ) ) ) ;
2006-10-21 23:33:03 +04:00
}
2006-11-29 20:00:10 +03:00
addr - = ( window * NETXEN_WINDOW_ONE ) ;
2006-10-21 23:33:03 +04:00
addr + = NETXEN_PCI_DDR_NET ;
} else if ( ADDR_IN_RANGE ( addr , NETXEN_ADDR_OCM0 , NETXEN_ADDR_OCM0_MAX ) ) {
addr - = NETXEN_ADDR_OCM0 ;
addr + = NETXEN_PCI_OCM0 ;
} else if ( ADDR_IN_RANGE ( addr , NETXEN_ADDR_OCM1 , NETXEN_ADDR_OCM1_MAX ) ) {
addr - = NETXEN_ADDR_OCM1 ;
addr + = NETXEN_PCI_OCM1 ;
} else
if ( ADDR_IN_RANGE
( addr , NETXEN_ADDR_QDR_NET , NETXEN_ADDR_QDR_NET_MAX ) ) {
/* QDR network side */
addr - = NETXEN_ADDR_QDR_NET ;
window = ( addr > > 22 ) & 0x3f ;
if ( qdr_sn_window ! = window ) {
qdr_sn_window = window ;
2006-11-29 20:00:10 +03:00
writel ( ( window < < 22 ) ,
PCI_OFFSET_SECOND_RANGE ( adapter ,
NETXEN_PCIX_PH_REG
2007-08-28 15:53:26 +04:00
( PCIX_SN_WINDOW ( adapter - > ahw . pci_func ) ) ) ) ;
2006-10-21 23:33:03 +04:00
/* MUST make sure window is set before we forge on... */
2006-11-29 20:00:10 +03:00
readl ( PCI_OFFSET_SECOND_RANGE ( adapter ,
NETXEN_PCIX_PH_REG
2007-08-28 15:53:26 +04:00
( PCIX_SN_WINDOW ( adapter - > ahw . pci_func ) ) ) ) ;
2006-10-21 23:33:03 +04:00
}
addr - = ( window * 0x400000 ) ;
addr + = NETXEN_PCI_QDR_NET ;
} else {
/*
* peg gdb frequently accesses memory that doesn ' t exist ,
* this limits the chit chat so debugging isn ' t slowed down .
*/
if ( ( netxen_pci_set_window_warning_count + + < 8 )
| | ( netxen_pci_set_window_warning_count % 64 = = 0 ) )
printk ( " %s: Warning:netxen_nic_pci_set_window() "
" Unknown address range! \n " ,
netxen_nic_driver_name ) ;
}
return addr ;
}
2007-11-05 20:07:31 +03:00
#if 0
2007-04-20 18:53:05 +04:00
int
netxen_nic_erase_pxe ( struct netxen_adapter * adapter )
{
2007-06-07 15:36:36 +04:00
if ( netxen_rom_fast_write ( adapter , NETXEN_PXE_START , 0 ) = = - 1 ) {
2007-11-24 05:23:36 +03:00
printk ( KERN_ERR " %s: erase pxe failed \n " ,
2007-04-20 18:53:05 +04:00
netxen_nic_driver_name ) ;
return - 1 ;
}
return 0 ;
}
2007-11-05 20:07:31 +03:00
# endif /* 0 */
2007-04-20 18:53:05 +04:00
2006-10-21 23:33:03 +04:00
int netxen_nic_get_board_info ( struct netxen_adapter * adapter )
{
int rv = 0 ;
2007-06-07 15:36:36 +04:00
int addr = NETXEN_BRDCFG_START ;
2006-10-21 23:33:03 +04:00
struct netxen_board_info * boardinfo ;
int index ;
u32 * ptr32 ;
boardinfo = & adapter - > ahw . boardcfg ;
ptr32 = ( u32 * ) boardinfo ;
for ( index = 0 ; index < sizeof ( struct netxen_board_info ) / sizeof ( u32 ) ;
index + + ) {
if ( netxen_rom_fast_read ( adapter , addr , ptr32 ) = = - 1 ) {
return - EIO ;
}
ptr32 + + ;
addr + = sizeof ( u32 ) ;
}
if ( boardinfo - > magic ! = NETXEN_BDINFO_MAGIC ) {
printk ( " %s: ERROR reading %s board config. "
" Read %x, expected %x \n " , netxen_nic_driver_name ,
netxen_nic_driver_name ,
boardinfo - > magic , NETXEN_BDINFO_MAGIC ) ;
rv = - 1 ;
}
if ( boardinfo - > header_version ! = NETXEN_BDINFO_VERSION ) {
printk ( " %s: Unknown board config version. "
" Read %x, expected %x \n " , netxen_nic_driver_name ,
boardinfo - > header_version , NETXEN_BDINFO_VERSION ) ;
rv = - 1 ;
}
DPRINTK ( INFO , " Discovered board type:0x%x " , boardinfo - > board_type ) ;
switch ( ( netxen_brdtype_t ) boardinfo - > board_type ) {
case NETXEN_BRDTYPE_P2_SB35_4G :
adapter - > ahw . board_type = NETXEN_NIC_GBE ;
break ;
case NETXEN_BRDTYPE_P2_SB31_10G :
case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ :
case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ :
case NETXEN_BRDTYPE_P2_SB31_10G_CX4 :
adapter - > ahw . board_type = NETXEN_NIC_XGBE ;
break ;
case NETXEN_BRDTYPE_P1_BD :
case NETXEN_BRDTYPE_P1_SB :
case NETXEN_BRDTYPE_P1_SMAX :
case NETXEN_BRDTYPE_P1_SOCK :
adapter - > ahw . board_type = NETXEN_NIC_GBE ;
break ;
default :
printk ( " %s: Unknown(%x) \n " , netxen_nic_driver_name ,
boardinfo - > board_type ) ;
break ;
}
return rv ;
}
/* NIU access sections */
2007-04-20 18:52:37 +04:00
int netxen_nic_set_mtu_gb ( struct netxen_adapter * adapter , int new_mtu )
2006-10-21 23:33:03 +04:00
{
netxen_nic_write_w0 ( adapter ,
2007-04-20 18:55:26 +04:00
NETXEN_NIU_GB_MAX_FRAME_SIZE (
physical_port [ adapter - > portnum ] ) , new_mtu ) ;
2006-10-21 23:33:03 +04:00
return 0 ;
}
2007-04-20 18:52:37 +04:00
int netxen_nic_set_mtu_xgb ( struct netxen_adapter * adapter , int new_mtu )
2006-10-21 23:33:03 +04:00
{
new_mtu + = NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE ;
2007-04-20 18:55:26 +04:00
if ( physical_port [ adapter - > portnum ] = = 0 )
2007-11-24 05:23:36 +03:00
netxen_nic_write_w0 ( adapter , NETXEN_NIU_XGE_MAX_FRAME_SIZE ,
2007-04-20 18:53:52 +04:00
new_mtu ) ;
2007-11-24 05:23:36 +03:00
else
2007-04-20 18:53:52 +04:00
netxen_nic_write_w0 ( adapter , NETXEN_NIU_XG1_MAX_FRAME_SIZE ,
new_mtu ) ;
2006-10-21 23:33:03 +04:00
return 0 ;
}
void netxen_nic_init_niu_gb ( struct netxen_adapter * adapter )
{
2007-04-20 18:55:26 +04:00
netxen_niu_gbe_init_port ( adapter , physical_port [ adapter - > portnum ] ) ;
2006-10-21 23:33:03 +04:00
}
void
netxen_crb_writelit_adapter ( struct netxen_adapter * adapter , unsigned long off ,
int data )
{
void __iomem * addr ;
if ( ADDR_IN_WINDOW1 ( off ) ) {
writel ( data , NETXEN_CRB_NORMALIZE ( adapter , off ) ) ;
} else {
netxen_nic_pci_change_crbwindow ( adapter , 0 ) ;
2006-12-01 16:36:22 +03:00
addr = pci_base_offset ( adapter , off ) ;
2006-10-21 23:33:03 +04:00
writel ( data , addr ) ;
netxen_nic_pci_change_crbwindow ( adapter , 1 ) ;
}
}
2007-04-20 18:52:37 +04:00
void netxen_nic_set_link_parameters ( struct netxen_adapter * adapter )
2006-10-21 23:33:03 +04:00
{
2007-01-02 13:39:10 +03:00
__u32 status ;
__u32 autoneg ;
__u32 mode ;
2006-10-21 23:33:03 +04:00
netxen_nic_read_w0 ( adapter , NETXEN_NIU_MODE , & mode ) ;
if ( netxen_get_niu_enable_ge ( mode ) ) { /* Gb 10/100/1000 Mbps mode */
2006-12-04 20:18:00 +03:00
if ( adapter - > phy_read
& & adapter - >
2007-04-20 18:53:05 +04:00
phy_read ( adapter ,
2006-10-21 23:33:03 +04:00
NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS ,
& status ) = = 0 ) {
if ( netxen_get_phy_link ( status ) ) {
switch ( netxen_get_phy_speed ( status ) ) {
case 0 :
2007-04-20 18:52:37 +04:00
adapter - > link_speed = SPEED_10 ;
2006-10-21 23:33:03 +04:00
break ;
case 1 :
2007-04-20 18:52:37 +04:00
adapter - > link_speed = SPEED_100 ;
2006-10-21 23:33:03 +04:00
break ;
case 2 :
2007-04-20 18:52:37 +04:00
adapter - > link_speed = SPEED_1000 ;
2006-10-21 23:33:03 +04:00
break ;
default :
2007-04-20 18:52:37 +04:00
adapter - > link_speed = - 1 ;
2006-10-21 23:33:03 +04:00
break ;
}
switch ( netxen_get_phy_duplex ( status ) ) {
case 0 :
2007-04-20 18:52:37 +04:00
adapter - > link_duplex = DUPLEX_HALF ;
2006-10-21 23:33:03 +04:00
break ;
case 1 :
2007-04-20 18:52:37 +04:00
adapter - > link_duplex = DUPLEX_FULL ;
2006-10-21 23:33:03 +04:00
break ;
default :
2007-04-20 18:52:37 +04:00
adapter - > link_duplex = - 1 ;
2006-10-21 23:33:03 +04:00
break ;
}
2006-12-04 20:18:00 +03:00
if ( adapter - > phy_read
& & adapter - >
2007-04-20 18:53:05 +04:00
phy_read ( adapter ,
2006-10-21 23:33:03 +04:00
NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG ,
2006-12-04 20:23:25 +03:00
& autoneg ) ! = 0 )
2007-04-20 18:52:37 +04:00
adapter - > link_autoneg = autoneg ;
2006-10-21 23:33:03 +04:00
} else
goto link_down ;
} else {
link_down :
2007-04-20 18:52:37 +04:00
adapter - > link_speed = - 1 ;
adapter - > link_duplex = - 1 ;
2006-10-21 23:33:03 +04:00
}
}
}
void netxen_nic_flash_print ( struct netxen_adapter * adapter )
{
int valid = 1 ;
u32 fw_major = 0 ;
u32 fw_minor = 0 ;
u32 fw_build = 0 ;
2006-11-29 20:00:10 +03:00
char brd_name [ NETXEN_MAX_SHORT_NAME ] ;
struct netxen_new_user_info user_info ;
2007-06-07 15:36:36 +04:00
int i , addr = NETXEN_USER_START ;
2007-04-20 18:56:42 +04:00
__le32 * ptr32 ;
2006-10-21 23:33:03 +04:00
struct netxen_board_info * board_info = & ( adapter - > ahw . boardcfg ) ;
if ( board_info - > magic ! = NETXEN_BDINFO_MAGIC ) {
printk
( " NetXen Unknown board config, Read 0x%x expected as 0x%x \n " ,
board_info - > magic , NETXEN_BDINFO_MAGIC ) ;
valid = 0 ;
}
if ( board_info - > header_version ! = NETXEN_BDINFO_VERSION ) {
printk ( " NetXen Unknown board config version. "
" Read %x, expected %x \n " ,
board_info - > header_version , NETXEN_BDINFO_VERSION ) ;
valid = 0 ;
}
if ( valid ) {
2006-11-29 20:00:10 +03:00
ptr32 = ( u32 * ) & user_info ;
for ( i = 0 ;
i < sizeof ( struct netxen_new_user_info ) / sizeof ( u32 ) ;
i + + ) {
if ( netxen_rom_fast_read ( adapter , addr , ptr32 ) = = - 1 ) {
printk ( " %s: ERROR reading %s board userarea. \n " ,
netxen_nic_driver_name ,
netxen_nic_driver_name ) ;
return ;
}
ptr32 + + ;
addr + = sizeof ( u32 ) ;
}
get_brd_name_by_type ( board_info - > board_type , brd_name ) ;
printk ( " NetXen %s Board S/N %s Chip id 0x%x \n " ,
brd_name , user_info . serial_num , board_info - > chip_id ) ;
2006-10-21 23:33:03 +04:00
printk ( " NetXen %s Board #%d, Chip id 0x%x \n " ,
board_info - > board_type = = 0x0b ? " XGB " : " GBE " ,
board_info - > board_num , board_info - > chip_id ) ;
fw_major = readl ( NETXEN_CRB_NORMALIZE ( adapter ,
NETXEN_FW_VERSION_MAJOR ) ) ;
fw_minor = readl ( NETXEN_CRB_NORMALIZE ( adapter ,
NETXEN_FW_VERSION_MINOR ) ) ;
fw_build =
readl ( NETXEN_CRB_NORMALIZE ( adapter , NETXEN_FW_VERSION_SUB ) ) ;
printk ( " NetXen Firmware version %d.%d.%d \n " , fw_major , fw_minor ,
fw_build ) ;
}
if ( fw_major ! = _NETXEN_NIC_LINUX_MAJOR ) {
printk ( KERN_ERR " The mismatch in driver version and firmware "
" version major number \n "
" Driver version major number = %d \t "
" Firmware version major number = %d \n " ,
_NETXEN_NIC_LINUX_MAJOR , fw_major ) ;
adapter - > driver_mismatch = 1 ;
}
2007-01-22 17:38:05 +03:00
if ( fw_minor ! = _NETXEN_NIC_LINUX_MINOR & &
fw_minor ! = ( _NETXEN_NIC_LINUX_MINOR + 1 ) ) {
2006-10-21 23:33:03 +04:00
printk ( KERN_ERR " The mismatch in driver version and firmware "
" version minor number \n "
" Driver version minor number = %d \t "
" Firmware version minor number = %d \n " ,
_NETXEN_NIC_LINUX_MINOR , fw_minor ) ;
adapter - > driver_mismatch = 1 ;
}
if ( adapter - > driver_mismatch )
printk ( KERN_INFO " Use the driver with version no %d.%d.xxx \n " ,
fw_major , fw_minor ) ;
}