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>
2008-07-22 06:44:03 +04:00
# define MASK(n) ((1ULL<<(n))-1)
# define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
# define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff))
# define MS_WIN(addr) (addr & 0x0ffc0000)
# define GET_MEM_OFFS_2M(addr) (addr & MASK(18))
# define CRB_BLK(off) ((off >> 20) & 0x3f)
# define CRB_SUBBLK(off) ((off >> 16) & 0xf)
# define CRB_WINDOW_2M (0x130060)
# define CRB_HI(off) ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
# define CRB_INDIRECT_2M (0x1e0000UL)
# define CRB_WIN_LOCK_TIMEOUT 100000000
static crb_128M_2M_block_map_t crb_128M_2M_map [ 64 ] = {
{ { { 0 , 0 , 0 , 0 } } } , /* 0: PCI */
{ { { 1 , 0x0100000 , 0x0102000 , 0x120000 } , /* 1: PCIE */
{ 1 , 0x0110000 , 0x0120000 , 0x130000 } ,
{ 1 , 0x0120000 , 0x0122000 , 0x124000 } ,
{ 1 , 0x0130000 , 0x0132000 , 0x126000 } ,
{ 1 , 0x0140000 , 0x0142000 , 0x128000 } ,
{ 1 , 0x0150000 , 0x0152000 , 0x12a000 } ,
{ 1 , 0x0160000 , 0x0170000 , 0x110000 } ,
{ 1 , 0x0170000 , 0x0172000 , 0x12e000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 1 , 0x01e0000 , 0x01e0800 , 0x122000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } } } ,
{ { { 1 , 0x0200000 , 0x0210000 , 0x180000 } } } , /* 2: MN */
{ { { 0 , 0 , 0 , 0 } } } , /* 3: */
{ { { 1 , 0x0400000 , 0x0401000 , 0x169000 } } } , /* 4: P2NR1 */
{ { { 1 , 0x0500000 , 0x0510000 , 0x140000 } } } , /* 5: SRE */
{ { { 1 , 0x0600000 , 0x0610000 , 0x1c0000 } } } , /* 6: NIU */
{ { { 1 , 0x0700000 , 0x0704000 , 0x1b8000 } } } , /* 7: QM */
{ { { 1 , 0x0800000 , 0x0802000 , 0x170000 } , /* 8: SQM0 */
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 1 , 0x08f0000 , 0x08f2000 , 0x172000 } } } ,
{ { { 1 , 0x0900000 , 0x0902000 , 0x174000 } , /* 9: SQM1*/
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 1 , 0x09f0000 , 0x09f2000 , 0x176000 } } } ,
{ { { 0 , 0x0a00000 , 0x0a02000 , 0x178000 } , /* 10: SQM2*/
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 1 , 0x0af0000 , 0x0af2000 , 0x17a000 } } } ,
{ { { 0 , 0x0b00000 , 0x0b02000 , 0x17c000 } , /* 11: SQM3*/
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 1 , 0x0bf0000 , 0x0bf2000 , 0x17e000 } } } ,
{ { { 1 , 0x0c00000 , 0x0c04000 , 0x1d4000 } } } , /* 12: I2Q */
{ { { 1 , 0x0d00000 , 0x0d04000 , 0x1a4000 } } } , /* 13: TMR */
{ { { 1 , 0x0e00000 , 0x0e04000 , 0x1a0000 } } } , /* 14: ROMUSB */
{ { { 1 , 0x0f00000 , 0x0f01000 , 0x164000 } } } , /* 15: PEG4 */
{ { { 0 , 0x1000000 , 0x1004000 , 0x1a8000 } } } , /* 16: XDMA */
{ { { 1 , 0x1100000 , 0x1101000 , 0x160000 } } } , /* 17: PEG0 */
{ { { 1 , 0x1200000 , 0x1201000 , 0x161000 } } } , /* 18: PEG1 */
{ { { 1 , 0x1300000 , 0x1301000 , 0x162000 } } } , /* 19: PEG2 */
{ { { 1 , 0x1400000 , 0x1401000 , 0x163000 } } } , /* 20: PEG3 */
{ { { 1 , 0x1500000 , 0x1501000 , 0x165000 } } } , /* 21: P2ND */
{ { { 1 , 0x1600000 , 0x1601000 , 0x166000 } } } , /* 22: P2NI */
{ { { 0 , 0 , 0 , 0 } } } , /* 23: */
{ { { 0 , 0 , 0 , 0 } } } , /* 24: */
{ { { 0 , 0 , 0 , 0 } } } , /* 25: */
{ { { 0 , 0 , 0 , 0 } } } , /* 26: */
{ { { 0 , 0 , 0 , 0 } } } , /* 27: */
{ { { 0 , 0 , 0 , 0 } } } , /* 28: */
{ { { 1 , 0x1d00000 , 0x1d10000 , 0x190000 } } } , /* 29: MS */
{ { { 1 , 0x1e00000 , 0x1e01000 , 0x16a000 } } } , /* 30: P2NR2 */
{ { { 1 , 0x1f00000 , 0x1f10000 , 0x150000 } } } , /* 31: EPG */
{ { { 0 } } } , /* 32: PCI */
{ { { 1 , 0x2100000 , 0x2102000 , 0x120000 } , /* 33: PCIE */
{ 1 , 0x2110000 , 0x2120000 , 0x130000 } ,
{ 1 , 0x2120000 , 0x2122000 , 0x124000 } ,
{ 1 , 0x2130000 , 0x2132000 , 0x126000 } ,
{ 1 , 0x2140000 , 0x2142000 , 0x128000 } ,
{ 1 , 0x2150000 , 0x2152000 , 0x12a000 } ,
{ 1 , 0x2160000 , 0x2170000 , 0x110000 } ,
{ 1 , 0x2170000 , 0x2172000 , 0x12e000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } ,
{ 0 , 0x0000000 , 0x0000000 , 0x000000 } } } ,
{ { { 1 , 0x2200000 , 0x2204000 , 0x1b0000 } } } , /* 34: CAM */
{ { { 0 } } } , /* 35: */
{ { { 0 } } } , /* 36: */
{ { { 0 } } } , /* 37: */
{ { { 0 } } } , /* 38: */
{ { { 0 } } } , /* 39: */
{ { { 1 , 0x2800000 , 0x2804000 , 0x1a4000 } } } , /* 40: TMR */
{ { { 1 , 0x2900000 , 0x2901000 , 0x16b000 } } } , /* 41: P2NR3 */
{ { { 1 , 0x2a00000 , 0x2a00400 , 0x1ac400 } } } , /* 42: RPMX1 */
{ { { 1 , 0x2b00000 , 0x2b00400 , 0x1ac800 } } } , /* 43: RPMX2 */
{ { { 1 , 0x2c00000 , 0x2c00400 , 0x1acc00 } } } , /* 44: RPMX3 */
{ { { 1 , 0x2d00000 , 0x2d00400 , 0x1ad000 } } } , /* 45: RPMX4 */
{ { { 1 , 0x2e00000 , 0x2e00400 , 0x1ad400 } } } , /* 46: RPMX5 */
{ { { 1 , 0x2f00000 , 0x2f00400 , 0x1ad800 } } } , /* 47: RPMX6 */
{ { { 1 , 0x3000000 , 0x3000400 , 0x1adc00 } } } , /* 48: RPMX7 */
{ { { 0 , 0x3100000 , 0x3104000 , 0x1a8000 } } } , /* 49: XDMA */
{ { { 1 , 0x3200000 , 0x3204000 , 0x1d4000 } } } , /* 50: I2Q */
{ { { 1 , 0x3300000 , 0x3304000 , 0x1a0000 } } } , /* 51: ROMUSB */
{ { { 0 } } } , /* 52: */
{ { { 1 , 0x3500000 , 0x3500400 , 0x1ac000 } } } , /* 53: RPMX0 */
{ { { 1 , 0x3600000 , 0x3600400 , 0x1ae000 } } } , /* 54: RPMX8 */
{ { { 1 , 0x3700000 , 0x3700400 , 0x1ae400 } } } , /* 55: RPMX9 */
{ { { 1 , 0x3800000 , 0x3804000 , 0x1d0000 } } } , /* 56: OCM0 */
{ { { 1 , 0x3900000 , 0x3904000 , 0x1b4000 } } } , /* 57: CRYPTO */
{ { { 1 , 0x3a00000 , 0x3a04000 , 0x1d8000 } } } , /* 58: SMB */
{ { { 0 } } } , /* 59: I2C0 */
{ { { 0 } } } , /* 60: I2C1 */
{ { { 1 , 0x3d00000 , 0x3d04000 , 0x1d8000 } } } , /* 61: LPC */
{ { { 1 , 0x3e00000 , 0x3e01000 , 0x167000 } } } , /* 62: P2NC */
{ { { 1 , 0x3f00000 , 0x3f01000 , 0x168000 } } } /* 63: P2NR0 */
} ;
/*
* top 12 bits of crb internal address ( hub , agent )
*/
static unsigned crb_hub_agt [ 64 ] =
{
0 ,
NETXEN_HW_CRB_HUB_AGT_ADR_PS ,
NETXEN_HW_CRB_HUB_AGT_ADR_MN ,
NETXEN_HW_CRB_HUB_AGT_ADR_MS ,
0 ,
NETXEN_HW_CRB_HUB_AGT_ADR_SRE ,
NETXEN_HW_CRB_HUB_AGT_ADR_NIU ,
NETXEN_HW_CRB_HUB_AGT_ADR_QMN ,
NETXEN_HW_CRB_HUB_AGT_ADR_SQN0 ,
NETXEN_HW_CRB_HUB_AGT_ADR_SQN1 ,
NETXEN_HW_CRB_HUB_AGT_ADR_SQN2 ,
NETXEN_HW_CRB_HUB_AGT_ADR_SQN3 ,
NETXEN_HW_CRB_HUB_AGT_ADR_I2Q ,
NETXEN_HW_CRB_HUB_AGT_ADR_TIMR ,
NETXEN_HW_CRB_HUB_AGT_ADR_ROMUSB ,
NETXEN_HW_CRB_HUB_AGT_ADR_PGN4 ,
NETXEN_HW_CRB_HUB_AGT_ADR_XDMA ,
NETXEN_HW_CRB_HUB_AGT_ADR_PGN0 ,
NETXEN_HW_CRB_HUB_AGT_ADR_PGN1 ,
NETXEN_HW_CRB_HUB_AGT_ADR_PGN2 ,
NETXEN_HW_CRB_HUB_AGT_ADR_PGN3 ,
NETXEN_HW_CRB_HUB_AGT_ADR_PGND ,
NETXEN_HW_CRB_HUB_AGT_ADR_PGNI ,
NETXEN_HW_CRB_HUB_AGT_ADR_PGS0 ,
NETXEN_HW_CRB_HUB_AGT_ADR_PGS1 ,
NETXEN_HW_CRB_HUB_AGT_ADR_PGS2 ,
NETXEN_HW_CRB_HUB_AGT_ADR_PGS3 ,
0 ,
NETXEN_HW_CRB_HUB_AGT_ADR_PGSI ,
NETXEN_HW_CRB_HUB_AGT_ADR_SN ,
0 ,
NETXEN_HW_CRB_HUB_AGT_ADR_EG ,
0 ,
NETXEN_HW_CRB_HUB_AGT_ADR_PS ,
NETXEN_HW_CRB_HUB_AGT_ADR_CAM ,
0 ,
0 ,
0 ,
0 ,
0 ,
NETXEN_HW_CRB_HUB_AGT_ADR_TIMR ,
0 ,
NETXEN_HW_CRB_HUB_AGT_ADR_RPMX1 ,
NETXEN_HW_CRB_HUB_AGT_ADR_RPMX2 ,
NETXEN_HW_CRB_HUB_AGT_ADR_RPMX3 ,
NETXEN_HW_CRB_HUB_AGT_ADR_RPMX4 ,
NETXEN_HW_CRB_HUB_AGT_ADR_RPMX5 ,
NETXEN_HW_CRB_HUB_AGT_ADR_RPMX6 ,
NETXEN_HW_CRB_HUB_AGT_ADR_RPMX7 ,
NETXEN_HW_CRB_HUB_AGT_ADR_XDMA ,
NETXEN_HW_CRB_HUB_AGT_ADR_I2Q ,
NETXEN_HW_CRB_HUB_AGT_ADR_ROMUSB ,
0 ,
NETXEN_HW_CRB_HUB_AGT_ADR_RPMX0 ,
NETXEN_HW_CRB_HUB_AGT_ADR_RPMX8 ,
NETXEN_HW_CRB_HUB_AGT_ADR_RPMX9 ,
NETXEN_HW_CRB_HUB_AGT_ADR_OCM0 ,
0 ,
NETXEN_HW_CRB_HUB_AGT_ADR_SMB ,
NETXEN_HW_CRB_HUB_AGT_ADR_I2C0 ,
NETXEN_HW_CRB_HUB_AGT_ADR_I2C1 ,
0 ,
NETXEN_HW_CRB_HUB_AGT_ADR_PGNC ,
0 ,
} ;
2006-10-21 23:33:03 +04:00
/* PCI Windowing for DDR regions. */
# define ADDR_IN_RANGE(addr, low, high) \
( ( ( addr ) < = ( high ) ) & & ( ( addr ) > = ( low ) ) )
2008-07-22 06:44:03 +04:00
# define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */
2006-10-21 23:33:03 +04:00
2006-11-29 20:00:10 +03:00
# 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
2006-10-21 23:33:03 +04:00
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 ;
memcpy ( netdev - > dev_addr , addr - > sa_data , netdev - > addr_len ) ;
2008-07-22 06:44:07 +04:00
/* For P3, MAC addr is not set in NIU */
if ( NX_IS_REVISION_P2 ( adapter - > ahw . revision_id ) )
if ( adapter - > macaddr_set )
adapter - > macaddr_set ( adapter , addr - > sa_data ) ;
2006-10-21 23:33:03 +04:00
return 0 ;
}
2008-07-22 06:44:01 +04:00
# define NETXEN_UNICAST_ADDR(port, index) \
( NETXEN_UNICAST_ADDR_BASE + ( port * 32 ) + ( index * 8 ) )
# define NETXEN_MCAST_ADDR(port, index) \
( NETXEN_MULTICAST_ADDR_BASE + ( port * 0x80 ) + ( index * 8 ) )
# define MAC_HI(addr) \
( ( addr [ 2 ] < < 16 ) | ( addr [ 1 ] < < 8 ) | ( addr [ 0 ] ) )
# define MAC_LO(addr) \
( ( addr [ 5 ] < < 16 ) | ( addr [ 4 ] < < 8 ) | ( addr [ 3 ] ) )
static int
netxen_nic_enable_mcast_filter ( struct netxen_adapter * adapter )
{
u32 val = 0 ;
u16 port = adapter - > physical_port ;
u8 * addr = adapter - > netdev - > dev_addr ;
if ( adapter - > mc_enabled )
return 0 ;
2008-07-22 06:44:03 +04:00
adapter - > hw_read_wx ( adapter , NETXEN_MAC_ADDR_CNTL_REG , & val , 4 ) ;
2008-07-22 06:44:01 +04:00
val | = ( 1UL < < ( 28 + port ) ) ;
2008-07-22 06:44:03 +04:00
adapter - > hw_write_wx ( adapter , NETXEN_MAC_ADDR_CNTL_REG , & val , 4 ) ;
2008-07-22 06:44:01 +04:00
/* add broadcast addr to filter */
val = 0xffffff ;
netxen_crb_writelit_adapter ( adapter , NETXEN_UNICAST_ADDR ( port , 0 ) , val ) ;
netxen_crb_writelit_adapter ( adapter ,
NETXEN_UNICAST_ADDR ( port , 0 ) + 4 , val ) ;
/* add station addr to filter */
val = MAC_HI ( addr ) ;
netxen_crb_writelit_adapter ( adapter , NETXEN_UNICAST_ADDR ( port , 1 ) , val ) ;
val = MAC_LO ( addr ) ;
netxen_crb_writelit_adapter ( adapter ,
NETXEN_UNICAST_ADDR ( port , 1 ) + 4 , val ) ;
adapter - > mc_enabled = 1 ;
return 0 ;
}
static int
netxen_nic_disable_mcast_filter ( struct netxen_adapter * adapter )
{
u32 val = 0 ;
u16 port = adapter - > physical_port ;
u8 * addr = adapter - > netdev - > dev_addr ;
if ( ! adapter - > mc_enabled )
return 0 ;
2008-07-22 06:44:03 +04:00
adapter - > hw_read_wx ( adapter , NETXEN_MAC_ADDR_CNTL_REG , & val , 4 ) ;
2008-07-22 06:44:01 +04:00
val & = ~ ( 1UL < < ( 28 + port ) ) ;
2008-07-22 06:44:03 +04:00
adapter - > hw_write_wx ( adapter , NETXEN_MAC_ADDR_CNTL_REG , & val , 4 ) ;
2008-07-22 06:44:01 +04:00
val = MAC_HI ( addr ) ;
netxen_crb_writelit_adapter ( adapter , NETXEN_UNICAST_ADDR ( port , 0 ) , val ) ;
val = MAC_LO ( addr ) ;
netxen_crb_writelit_adapter ( adapter ,
NETXEN_UNICAST_ADDR ( port , 0 ) + 4 , val ) ;
netxen_crb_writelit_adapter ( adapter , NETXEN_UNICAST_ADDR ( port , 1 ) , 0 ) ;
netxen_crb_writelit_adapter ( adapter , NETXEN_UNICAST_ADDR ( port , 1 ) + 4 , 0 ) ;
adapter - > mc_enabled = 0 ;
return 0 ;
}
static int
netxen_nic_set_mcast_addr ( struct netxen_adapter * adapter ,
int index , u8 * addr )
{
u32 hi = 0 , lo = 0 ;
u16 port = adapter - > physical_port ;
lo = MAC_LO ( addr ) ;
hi = MAC_HI ( addr ) ;
netxen_crb_writelit_adapter ( adapter ,
NETXEN_MCAST_ADDR ( port , index ) , hi ) ;
netxen_crb_writelit_adapter ( adapter ,
NETXEN_MCAST_ADDR ( port , index ) + 4 , lo ) ;
return 0 ;
}
2008-07-22 06:44:07 +04:00
void netxen_p2_nic_set_multi ( struct net_device * netdev )
2006-10-21 23:33:03 +04:00
{
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 ;
2008-07-22 06:44:01 +04:00
u8 null_addr [ 6 ] ;
int index = 0 ;
memset ( null_addr , 0 , 6 ) ;
2006-10-21 23:33:03 +04:00
if ( netdev - > flags & IFF_PROMISC ) {
2008-07-22 06:44:01 +04:00
adapter - > set_promisc ( adapter ,
NETXEN_NIU_PROMISC_MODE ) ;
/* Full promiscuous mode */
netxen_nic_disable_mcast_filter ( adapter ) ;
return ;
}
if ( netdev - > mc_count = = 0 ) {
adapter - > set_promisc ( adapter ,
NETXEN_NIU_NON_PROMISC_MODE ) ;
netxen_nic_disable_mcast_filter ( adapter ) ;
return ;
}
adapter - > set_promisc ( adapter , NETXEN_NIU_ALLMULTI_MODE ) ;
if ( netdev - > flags & IFF_ALLMULTI | |
netdev - > mc_count > adapter - > max_mc_count ) {
netxen_nic_disable_mcast_filter ( adapter ) ;
return ;
2006-10-21 23:33:03 +04:00
}
2008-07-22 06:44:01 +04:00
netxen_nic_enable_mcast_filter ( adapter ) ;
for ( mc_ptr = netdev - > mc_list ; mc_ptr ; mc_ptr = mc_ptr - > next , index + + )
netxen_nic_set_mcast_addr ( adapter , index , mc_ptr - > dmi_addr ) ;
if ( index ! = netdev - > mc_count )
printk ( KERN_WARNING " %s: %s multicast address count mismatch \n " ,
netxen_nic_driver_name , netdev - > name ) ;
/* Clear out remaining addresses */
for ( ; index < adapter - > max_mc_count ; index + + )
netxen_nic_set_mcast_addr ( adapter , index , null_addr ) ;
2006-10-21 23:33:03 +04:00
}
2008-07-22 06:44:07 +04:00
static int nx_p3_nic_add_mac ( struct netxen_adapter * adapter ,
u8 * addr , nx_mac_list_t * * add_list , nx_mac_list_t * * del_list )
{
nx_mac_list_t * cur , * prev ;
/* if in del_list, move it to adapter->mac_list */
for ( cur = * del_list , prev = NULL ; cur ; ) {
if ( memcmp ( addr , cur - > mac_addr , ETH_ALEN ) = = 0 ) {
if ( prev = = NULL )
* del_list = cur - > next ;
else
prev - > next = cur - > next ;
cur - > next = adapter - > mac_list ;
adapter - > mac_list = cur ;
return 0 ;
}
prev = cur ;
cur = cur - > next ;
}
/* make sure to add each mac address only once */
for ( cur = adapter - > mac_list ; cur ; cur = cur - > next ) {
if ( memcmp ( addr , cur - > mac_addr , ETH_ALEN ) = = 0 )
return 0 ;
}
/* not in del_list, create new entry and add to add_list */
cur = kmalloc ( sizeof ( * cur ) , in_atomic ( ) ? GFP_ATOMIC : GFP_KERNEL ) ;
if ( cur = = NULL ) {
printk ( KERN_ERR " %s: cannot allocate memory. MAC filtering may "
" not work properly from now. \n " , __func__ ) ;
return - 1 ;
}
memcpy ( cur - > mac_addr , addr , ETH_ALEN ) ;
cur - > next = * add_list ;
* add_list = cur ;
return 0 ;
}
static int
netxen_send_cmd_descs ( struct netxen_adapter * adapter ,
struct cmd_desc_type0 * cmd_desc_arr , int nr_elements )
{
uint32_t i , producer ;
struct netxen_cmd_buffer * pbuf ;
struct cmd_desc_type0 * cmd_desc ;
if ( nr_elements > MAX_PENDING_DESC_BLOCK_SIZE | | nr_elements = = 0 ) {
printk ( KERN_WARNING " %s: Too many command descriptors in a "
" request \n " , __func__ ) ;
return - EINVAL ;
}
i = 0 ;
2009-01-15 07:49:43 +03:00
netif_tx_lock_bh ( adapter - > netdev ) ;
2008-07-22 06:44:07 +04:00
producer = adapter - > cmd_producer ;
do {
cmd_desc = & cmd_desc_arr [ i ] ;
pbuf = & adapter - > cmd_buf_arr [ producer ] ;
pbuf - > skb = NULL ;
pbuf - > frag_count = 0 ;
/* adapter->ahw.cmd_desc_head[producer] = *cmd_desc; */
memcpy ( & adapter - > ahw . cmd_desc_head [ producer ] ,
& cmd_desc_arr [ i ] , sizeof ( struct cmd_desc_type0 ) ) ;
producer = get_next_index ( producer ,
adapter - > max_tx_desc_count ) ;
i + + ;
} while ( i ! = nr_elements ) ;
adapter - > cmd_producer = producer ;
/* write producer index to start the xmit */
netxen_nic_update_cmd_producer ( adapter , adapter - > cmd_producer ) ;
2009-01-15 07:49:43 +03:00
netif_tx_unlock_bh ( adapter - > netdev ) ;
2008-07-22 06:44:07 +04:00
return 0 ;
}
static int nx_p3_sre_macaddr_change ( struct net_device * dev ,
u8 * addr , unsigned op )
{
2008-11-13 10:38:14 +03:00
struct netxen_adapter * adapter = netdev_priv ( dev ) ;
2008-07-22 06:44:07 +04:00
nx_nic_req_t req ;
2009-01-15 07:47:30 +03:00
nx_mac_req_t * mac_req ;
u64 word ;
2008-07-22 06:44:07 +04:00
int rv ;
memset ( & req , 0 , sizeof ( nx_nic_req_t ) ) ;
2009-01-15 07:47:30 +03:00
req . qhdr = cpu_to_le64 ( NX_NIC_REQUEST < < 23 ) ;
word = NX_MAC_EVENT | ( ( u64 ) adapter - > portnum < < 16 ) ;
req . req_hdr = cpu_to_le64 ( word ) ;
mac_req = ( nx_mac_req_t * ) & req . words [ 0 ] ;
mac_req - > op = op ;
memcpy ( mac_req - > mac_addr , addr , 6 ) ;
2008-07-22 06:44:07 +04:00
rv = netxen_send_cmd_descs ( adapter , ( struct cmd_desc_type0 * ) & req , 1 ) ;
if ( rv ! = 0 ) {
printk ( KERN_ERR " ERROR. Could not send mac update \n " ) ;
return rv ;
}
return 0 ;
}
void netxen_p3_nic_set_multi ( struct net_device * netdev )
{
struct netxen_adapter * adapter = netdev_priv ( netdev ) ;
nx_mac_list_t * cur , * next , * del_list , * add_list = NULL ;
struct dev_mc_list * mc_ptr ;
u8 bcast_addr [ ETH_ALEN ] = { 0xff , 0xff , 0xff , 0xff , 0xff , 0xff } ;
2008-08-01 14:14:59 +04:00
u32 mode = VPORT_MISS_MODE_DROP ;
2008-07-22 06:44:07 +04:00
del_list = adapter - > mac_list ;
adapter - > mac_list = NULL ;
nx_p3_nic_add_mac ( adapter , netdev - > dev_addr , & add_list , & del_list ) ;
2008-08-01 14:14:59 +04:00
nx_p3_nic_add_mac ( adapter , bcast_addr , & add_list , & del_list ) ;
if ( netdev - > flags & IFF_PROMISC ) {
mode = VPORT_MISS_MODE_ACCEPT_ALL ;
goto send_fw_cmd ;
}
if ( ( netdev - > flags & IFF_ALLMULTI ) | |
( netdev - > mc_count > adapter - > max_mc_count ) ) {
mode = VPORT_MISS_MODE_ACCEPT_MULTI ;
goto send_fw_cmd ;
}
2008-07-22 06:44:07 +04:00
if ( netdev - > mc_count > 0 ) {
for ( mc_ptr = netdev - > mc_list ; mc_ptr ;
mc_ptr = mc_ptr - > next ) {
nx_p3_nic_add_mac ( adapter , mc_ptr - > dmi_addr ,
& add_list , & del_list ) ;
}
}
2008-08-01 14:14:59 +04:00
send_fw_cmd :
adapter - > set_promisc ( adapter , mode ) ;
2008-07-22 06:44:07 +04:00
for ( cur = del_list ; cur ; ) {
nx_p3_sre_macaddr_change ( netdev , cur - > mac_addr , NETXEN_MAC_DEL ) ;
next = cur - > next ;
kfree ( cur ) ;
cur = next ;
}
for ( cur = add_list ; cur ; ) {
nx_p3_sre_macaddr_change ( netdev , cur - > mac_addr , NETXEN_MAC_ADD ) ;
next = cur - > next ;
cur - > next = adapter - > mac_list ;
adapter - > mac_list = cur ;
cur = next ;
}
}
2008-08-01 14:14:59 +04:00
int netxen_p3_nic_set_promisc ( struct netxen_adapter * adapter , u32 mode )
{
nx_nic_req_t req ;
2009-01-15 07:47:30 +03:00
u64 word ;
2008-08-01 14:14:59 +04:00
memset ( & req , 0 , sizeof ( nx_nic_req_t ) ) ;
2009-01-15 07:47:30 +03:00
req . qhdr = cpu_to_le64 ( NX_HOST_REQUEST < < 23 ) ;
word = NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE |
( ( u64 ) adapter - > portnum < < 16 ) ;
req . req_hdr = cpu_to_le64 ( word ) ;
2008-08-01 14:14:59 +04:00
req . words [ 0 ] = cpu_to_le64 ( mode ) ;
return netxen_send_cmd_descs ( adapter ,
( struct cmd_desc_type0 * ) & req , 1 ) ;
}
2009-01-15 07:49:22 +03:00
void netxen_p3_free_mac_list ( struct netxen_adapter * adapter )
{
nx_mac_list_t * cur , * next ;
cur = adapter - > mac_list ;
while ( cur ) {
next = cur - > next ;
kfree ( cur ) ;
cur = next ;
}
}
2008-07-22 06:44:09 +04:00
# define NETXEN_CONFIG_INTR_COALESCE 3
/*
* Send the interrupt coalescing parameter set by ethtool to the card .
*/
int netxen_config_intr_coalesce ( struct netxen_adapter * adapter )
{
nx_nic_req_t req ;
2009-01-15 07:47:30 +03:00
u64 word ;
2008-07-22 06:44:09 +04:00
int rv ;
memset ( & req , 0 , sizeof ( nx_nic_req_t ) ) ;
2009-01-15 07:47:30 +03:00
req . qhdr = cpu_to_le64 ( NX_NIC_REQUEST < < 23 ) ;
word = NETXEN_CONFIG_INTR_COALESCE | ( ( u64 ) adapter - > portnum < < 16 ) ;
req . req_hdr = cpu_to_le64 ( word ) ;
2008-07-22 06:44:09 +04:00
memcpy ( & req . words [ 0 ] , & adapter - > coal , sizeof ( adapter - > coal ) ) ;
rv = netxen_send_cmd_descs ( adapter , ( struct cmd_desc_type0 * ) & req , 1 ) ;
if ( rv ! = 0 ) {
printk ( KERN_ERR " ERROR. Could not send "
" interrupt coalescing parameters \n " ) ;
}
return rv ;
}
2006-10-21 23:33:03 +04:00
/*
* netxen_nic_change_mtu - Change the Maximum Transfer Unit
* @ returns 0 on success , negative on failure
*/
2008-07-22 06:44:07 +04:00
# define MTU_FUDGE_FACTOR 100
2006-10-21 23:33:03 +04:00
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 ) ;
2008-07-22 06:44:07 +04:00
int max_mtu ;
2008-08-01 14:14:59 +04:00
int rc = 0 ;
2006-10-21 23:33:03 +04:00
2008-07-22 06:44:07 +04:00
if ( NX_IS_REVISION_P3 ( adapter - > ahw . revision_id ) )
max_mtu = P3_MAX_MTU ;
else
max_mtu = P2_MAX_MTU ;
if ( mtu > max_mtu ) {
printk ( KERN_ERR " %s: mtu > %d bytes unsupported \n " ,
netdev - > name , max_mtu ) ;
2006-10-21 23:33:03 +04:00
return - EINVAL ;
}
2006-12-04 20:18:00 +03:00
if ( adapter - > set_mtu )
2008-08-01 14:14:59 +04:00
rc = adapter - > set_mtu ( adapter , mtu ) ;
2006-10-21 23:33:03 +04:00
2008-08-01 14:14:59 +04:00
if ( ! rc )
netdev - > mtu = mtu ;
2008-07-22 06:44:07 +04:00
2008-08-01 14:14:59 +04:00
return rc ;
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 ,
2007-12-22 22:44:00 +03:00
int size , __le32 * buf )
2006-10-21 23:33:03 +04:00
{
int i , addr ;
2007-12-22 22:44:00 +03:00
__le32 * ptr32 ;
u32 v ;
2006-10-21 23:33:03 +04:00
addr = base ;
ptr32 = buf ;
for ( i = 0 ; i < size / sizeof ( u32 ) ; i + + ) {
2007-12-22 22:44:00 +03:00
if ( netxen_rom_fast_read ( adapter , addr , & v ) = = - 1 )
2006-10-21 23:33:03 +04:00
return - 1 ;
2007-12-22 22:44:00 +03:00
* ptr32 = cpu_to_le32 ( v ) ;
2006-10-21 23:33:03 +04:00
ptr32 + + ;
addr + = sizeof ( u32 ) ;
}
if ( ( char * ) buf + size > ( char * ) ptr32 ) {
2007-12-22 22:44:00 +03:00
__le32 local ;
if ( netxen_rom_fast_read ( adapter , addr , & v ) = = - 1 )
2006-10-21 23:33:03 +04:00
return - 1 ;
2007-12-22 22:44:00 +03:00
local = cpu_to_le32 ( v ) ;
2006-10-21 23:33:03 +04:00
memcpy ( ptr32 , & local , ( char * ) buf + size - ( char * ) ptr32 ) ;
}
return 0 ;
}
2008-08-08 11:08:39 +04:00
int netxen_get_flash_mac_addr ( struct netxen_adapter * adapter , __le64 * mac )
2006-10-21 23:33:03 +04:00
{
2008-08-08 11:08:39 +04:00
__le32 * pmac = ( __le32 * ) mac ;
u32 offset ;
2006-10-21 23:33:03 +04:00
2008-08-08 11:08:39 +04:00
offset = NETXEN_USER_START +
offsetof ( struct netxen_new_user_info , mac_addr ) +
adapter - > portnum * sizeof ( u64 ) ;
if ( netxen_get_flash_block ( adapter , offset , sizeof ( u64 ) , pmac ) = = - 1 )
2006-10-21 23:33:03 +04:00
return - 1 ;
2008-08-08 11:08:39 +04:00
2007-12-22 22:44:00 +03:00
if ( * mac = = cpu_to_le64 ( ~ 0ULL ) ) {
2008-08-08 11:08:39 +04:00
offset = NETXEN_USER_START_OLD +
offsetof ( struct netxen_user_old_info , mac_addr ) +
adapter - > portnum * sizeof ( u64 ) ;
2006-10-21 23:33:03 +04:00
if ( netxen_get_flash_block ( adapter ,
2008-08-08 11:08:39 +04:00
offset , sizeof ( u64 ) , pmac ) = = - 1 )
2006-10-21 23:33:03 +04:00
return - 1 ;
2008-08-08 11:08:39 +04:00
2007-12-22 22:44:00 +03:00
if ( * mac = = cpu_to_le64 ( ~ 0ULL ) )
2006-10-21 23:33:03 +04:00
return - 1 ;
}
return 0 ;
}
2008-08-08 11:08:39 +04:00
int netxen_p3_get_mac_addr ( struct netxen_adapter * adapter , __le64 * mac )
{
uint32_t crbaddr , mac_hi , mac_lo ;
int pci_func = adapter - > ahw . pci_func ;
crbaddr = CRB_MAC_BLOCK_START +
( 4 * ( ( pci_func / 2 ) * 3 ) ) + ( 4 * ( pci_func & 1 ) ) ;
adapter - > hw_read_wx ( adapter , crbaddr , & mac_lo , 4 ) ;
adapter - > hw_read_wx ( adapter , crbaddr + 4 , & mac_hi , 4 ) ;
if ( pci_func & 1 )
2009-01-15 07:47:30 +03:00
* mac = le64_to_cpu ( ( mac_lo > > 16 ) | ( ( u64 ) mac_hi < < 16 ) ) ;
2008-08-08 11:08:39 +04:00
else
2009-01-15 07:47:30 +03:00
* mac = le64_to_cpu ( ( u64 ) mac_lo | ( ( u64 ) mac_hi < < 32 ) ) ;
2008-08-08 11:08:39 +04:00
return 0 ;
}
2008-07-22 06:44:03 +04:00
# define CRB_WIN_LOCK_TIMEOUT 100000000
static int crb_win_lock ( struct netxen_adapter * adapter )
{
int done = 0 , timeout = 0 ;
while ( ! done ) {
/* acquire semaphore3 from PCI HW block */
adapter - > hw_read_wx ( adapter ,
NETXEN_PCIE_REG ( PCIE_SEM7_LOCK ) , & done , 4 ) ;
if ( done = = 1 )
break ;
if ( timeout > = CRB_WIN_LOCK_TIMEOUT )
return - 1 ;
timeout + + ;
udelay ( 1 ) ;
}
netxen_crb_writelit_adapter ( adapter ,
NETXEN_CRB_WIN_LOCK_ID , adapter - > portnum ) ;
return 0 ;
}
static void crb_win_unlock ( struct netxen_adapter * adapter )
{
int val ;
adapter - > hw_read_wx ( adapter ,
NETXEN_PCIE_REG ( PCIE_SEM7_UNLOCK ) , & val , 4 ) ;
}
2006-10-21 23:33:03 +04:00
/*
* Changes the CRB window to the specified window .
*/
2008-07-22 06:44:03 +04:00
void
netxen_nic_pci_change_crbwindow_128M ( struct netxen_adapter * adapter , u32 wndw )
2006-10-21 23:33:03 +04:00
{
void __iomem * offset ;
u32 tmp ;
int count = 0 ;
2008-07-22 06:44:02 +04:00
uint8_t func = adapter - > ahw . pci_func ;
2006-10-21 23:33:03 +04:00
if ( adapter - > curr_window = = wndw )
return ;
/*
* 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 .
*/
2008-07-22 06:44:02 +04:00
offset = PCI_OFFSET_SECOND_RANGE ( adapter ,
NETXEN_PCIX_PH_REG ( PCIE_CRB_WINDOW_REG ( func ) ) ) ;
2006-10-21 23:33:03 +04:00
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 " ,
2008-07-22 06:44:03 +04:00
netxen_nic_driver_name , __func__ , tmp ) ;
2006-10-21 23:33:03 +04:00
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
}
2008-07-22 06:44:03 +04:00
/*
* Return - 1 if off is not valid ,
* 1 if window access is needed . ' off ' is set to offset from
* CRB space in 128 M pci map
* 0 if no window access is needed . ' off ' is set to 2 M addr
* In : ' off ' is offset from base in 128 M pci map
*/
static int
netxen_nic_pci_get_crb_addr_2M ( struct netxen_adapter * adapter ,
ulong * off , int len )
{
unsigned long end = * off + len ;
crb_128M_2M_sub_block_map_t * m ;
if ( * off > = NETXEN_CRB_MAX )
return - 1 ;
if ( * off > = NETXEN_PCI_CAMQM & & ( end < = NETXEN_PCI_CAMQM_2M_END ) ) {
* off = ( * off - NETXEN_PCI_CAMQM ) + NETXEN_PCI_CAMQM_2M_BASE +
( ulong ) adapter - > ahw . pci_base0 ;
return 0 ;
}
if ( * off < NETXEN_PCI_CRBSPACE )
return - 1 ;
* off - = NETXEN_PCI_CRBSPACE ;
end = * off + len ;
/*
* Try direct map
*/
m = & crb_128M_2M_map [ CRB_BLK ( * off ) ] . sub_block [ CRB_SUBBLK ( * off ) ] ;
if ( m - > valid & & ( m - > start_128M < = * off ) & & ( m - > end_128M > = end ) ) {
* off = * off + m - > start_2M - m - > start_128M +
( ulong ) adapter - > ahw . pci_base0 ;
return 0 ;
}
/*
* Not in direct map , use crb window
*/
return 1 ;
}
/*
* In : ' off ' is offset from CRB space in 128 M pci map
* Out : ' off ' is 2 M pci map addr
* side effect : lock crb window
*/
static void
netxen_nic_pci_set_crbwindow_2M ( struct netxen_adapter * adapter , ulong * off )
{
u32 win_read ;
adapter - > crb_win = CRB_HI ( * off ) ;
writel ( adapter - > crb_win , ( void * ) ( CRB_WINDOW_2M +
adapter - > ahw . pci_base0 ) ) ;
/*
* Read back value to make sure write has gone through before trying
* to use it .
*/
win_read = readl ( ( void * ) ( CRB_WINDOW_2M + adapter - > ahw . pci_base0 ) ) ;
if ( win_read ! = adapter - > crb_win ) {
printk ( KERN_ERR " %s: Written crbwin (0x%x) != "
" Read crbwin (0x%x), off=0x%lx \n " ,
__func__ , adapter - > crb_win , win_read , * off ) ;
}
* off = ( * off & MASK ( 16 ) ) + CRB_INDIRECT_2M +
( ulong ) adapter - > ahw . pci_base0 ;
}
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 ;
2009-01-15 07:49:00 +03:00
u32 flashaddr = NETXEN_BOOTLD_START ;
2008-07-22 06:44:04 +04:00
size = ( NETXEN_IMAGE_START - NETXEN_BOOTLD_START ) / 4 ;
2006-10-21 23:33:03 +04:00
2008-07-22 06:44:04 +04:00
if ( NX_IS_REVISION_P2 ( adapter - > ahw . revision_id ) )
adapter - > pci_write_normalize ( adapter ,
2008-07-22 06:44:03 +04:00
NETXEN_ROMUSB_GLB_CAS_RST , 1 ) ;
2006-10-21 23:33:03 +04:00
for ( i = 0 ; i < size ; i + + ) {
2007-07-02 08:07:57 +04:00
if ( netxen_rom_fast_read ( adapter , flashaddr , ( int * ) & data ) ! = 0 )
return - EIO ;
2009-01-15 07:49:00 +03:00
adapter - > pci_mem_write ( adapter , flashaddr , & data , 4 ) ;
2006-10-21 23:33:03 +04:00
flashaddr + = 4 ;
}
2008-07-22 06:44:04 +04:00
msleep ( 1 ) ;
if ( NX_IS_REVISION_P3 ( adapter - > ahw . revision_id ) )
adapter - > pci_write_normalize ( adapter ,
NETXEN_ROMUSB_GLB_SW_RESET , 0x80001d ) ;
else {
adapter - > pci_write_normalize ( adapter ,
2008-07-22 06:44:03 +04:00
NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL , 0x3fff ) ;
2008-07-22 06:44:04 +04:00
adapter - > pci_write_normalize ( adapter ,
2008-07-22 06:44:03 +04:00
NETXEN_ROMUSB_GLB_CAS_RST , 0 ) ;
2008-07-22 06:44:04 +04:00
}
2006-10-21 23:33:03 +04:00
2007-07-02 08:07:57 +04:00
return 0 ;
2006-10-21 23:33:03 +04:00
}
int
2008-07-22 06:44:03 +04:00
netxen_nic_hw_write_wx_128M ( struct netxen_adapter * adapter ,
ulong off , void * data , int len )
2006-10-21 23:33:03 +04:00
{
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 ) ;
2008-07-22 06:44:03 +04:00
netxen_nic_pci_change_crbwindow_128M ( adapter , 0 ) ;
2006-10-21 23:33:03 +04:00
}
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 ) {
2008-07-22 06:44:03 +04:00
netxen_nic_pci_change_crbwindow_128M ( adapter , 1 ) ;
2006-11-29 20:00:10 +03:00
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 ) )
2008-07-22 06:44:03 +04:00
netxen_nic_pci_change_crbwindow_128M ( adapter , 1 ) ;
2006-10-21 23:33:03 +04:00
return 0 ;
}
int
2008-07-22 06:44:03 +04:00
netxen_nic_hw_read_wx_128M ( struct netxen_adapter * adapter ,
ulong off , void * data , int len )
2006-10-21 23:33:03 +04:00
{
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 ) ;
2008-07-22 06:44:03 +04:00
netxen_nic_pci_change_crbwindow_128M ( adapter , 0 ) ;
2006-10-21 23:33:03 +04:00
}
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 ) {
2008-07-22 06:44:03 +04:00
netxen_nic_pci_change_crbwindow_128M ( adapter , 1 ) ;
2006-11-29 20:00:10 +03:00
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 ) )
2008-07-22 06:44:03 +04:00
netxen_nic_pci_change_crbwindow_128M ( adapter , 1 ) ;
2006-10-21 23:33:03 +04:00
return 0 ;
}
2008-07-22 06:44:03 +04:00
int
netxen_nic_hw_write_wx_2M ( struct netxen_adapter * adapter ,
ulong off , void * data , int len )
{
unsigned long flags = 0 ;
int rv ;
2006-10-21 23:33:03 +04:00
2008-07-22 06:44:03 +04:00
rv = netxen_nic_pci_get_crb_addr_2M ( adapter , & off , len ) ;
2006-10-21 23:33:03 +04:00
2008-07-22 06:44:03 +04:00
if ( rv = = - 1 ) {
printk ( KERN_ERR " %s: invalid offset: 0x%016lx \n " ,
__func__ , off ) ;
dump_stack ( ) ;
return - 1 ;
}
if ( rv = = 1 ) {
write_lock_irqsave ( & adapter - > adapter_lock , flags ) ;
crb_win_lock ( adapter ) ;
netxen_nic_pci_set_crbwindow_2M ( adapter , & off ) ;
}
DPRINTK ( 1 , INFO , " write data %lx to offset %llx, len=%d \n " ,
* ( unsigned long * ) data , off , len ) ;
switch ( len ) {
case 1 :
writeb ( * ( uint8_t * ) data , ( void * ) off ) ;
break ;
case 2 :
writew ( * ( uint16_t * ) data , ( void * ) off ) ;
break ;
case 4 :
writel ( * ( uint32_t * ) data , ( void * ) off ) ;
break ;
case 8 :
writeq ( * ( uint64_t * ) data , ( void * ) off ) ;
break ;
default :
DPRINTK ( 1 , INFO ,
" writing data %lx to offset %llx, num words=%d \n " ,
* ( unsigned long * ) data , off , ( len > > 3 ) ) ;
break ;
}
if ( rv = = 1 ) {
crb_win_unlock ( adapter ) ;
write_unlock_irqrestore ( & adapter - > adapter_lock , flags ) ;
}
return 0 ;
2006-10-21 23:33:03 +04:00
}
2008-07-22 06:44:03 +04:00
int
netxen_nic_hw_read_wx_2M ( struct netxen_adapter * adapter ,
ulong off , void * data , int len )
{
unsigned long flags = 0 ;
int rv ;
2006-10-21 23:33:03 +04:00
2008-07-22 06:44:03 +04:00
rv = netxen_nic_pci_get_crb_addr_2M ( adapter , & off , len ) ;
if ( rv = = - 1 ) {
printk ( KERN_ERR " %s: invalid offset: 0x%016lx \n " ,
__func__ , off ) ;
dump_stack ( ) ;
return - 1 ;
}
if ( rv = = 1 ) {
write_lock_irqsave ( & adapter - > adapter_lock , flags ) ;
crb_win_lock ( adapter ) ;
netxen_nic_pci_set_crbwindow_2M ( adapter , & off ) ;
}
DPRINTK ( 1 , INFO , " read from offset %lx, len=%d \n " , off , len ) ;
switch ( len ) {
case 1 :
* ( uint8_t * ) data = readb ( ( void * ) off ) ;
break ;
case 2 :
* ( uint16_t * ) data = readw ( ( void * ) off ) ;
break ;
case 4 :
* ( uint32_t * ) data = readl ( ( void * ) off ) ;
break ;
case 8 :
* ( uint64_t * ) data = readq ( ( void * ) off ) ;
break ;
default :
break ;
}
DPRINTK ( 1 , INFO , " read %lx \n " , * ( unsigned long * ) data ) ;
2006-10-21 23:33:03 +04:00
2008-07-22 06:44:03 +04:00
if ( rv = = 1 ) {
crb_win_unlock ( adapter ) ;
write_unlock_irqrestore ( & adapter - > adapter_lock , flags ) ;
}
return 0 ;
}
void netxen_nic_reg_write ( struct netxen_adapter * adapter , u64 off , u32 val )
{
adapter - > hw_write_wx ( adapter , off , & val , 4 ) ;
}
int netxen_nic_reg_read ( struct netxen_adapter * adapter , u64 off )
{
int val ;
adapter - > hw_read_wx ( adapter , off , & val , 4 ) ;
2006-10-21 23:33:03 +04:00
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 )
{
2008-07-22 06:44:03 +04:00
adapter - > hw_write_wx ( adapter , index , & value , 4 ) ;
2006-10-21 23:33:03 +04:00
}
/* Change the window to 0, read and change back to window 1. */
2008-07-22 06:44:03 +04:00
void netxen_nic_read_w0 ( struct netxen_adapter * adapter , u32 index , u32 * value )
2006-10-21 23:33:03 +04:00
{
2008-07-22 06:44:03 +04:00
adapter - > hw_read_wx ( adapter , index , value , 4 ) ;
}
2006-10-21 23:33:03 +04:00
2008-07-22 06:44:03 +04:00
void netxen_nic_write_w1 ( struct netxen_adapter * adapter , u32 index , u32 value )
{
adapter - > hw_write_wx ( adapter , index , & value , 4 ) ;
}
void netxen_nic_read_w1 ( struct netxen_adapter * adapter , u32 index , u32 * value )
{
adapter - > hw_read_wx ( adapter , index , value , 4 ) ;
}
/*
* check memory access boundary .
* used by test agent . support ddr access only for now
*/
static unsigned long
netxen_nic_pci_mem_bound_check ( struct netxen_adapter * adapter ,
unsigned long long addr , int size )
{
if ( ! ADDR_IN_RANGE ( addr ,
NETXEN_ADDR_DDR_NET , NETXEN_ADDR_DDR_NET_MAX ) | |
! ADDR_IN_RANGE ( addr + size - 1 ,
NETXEN_ADDR_DDR_NET , NETXEN_ADDR_DDR_NET_MAX ) | |
( ( size ! = 1 ) & & ( size ! = 2 ) & & ( size ! = 4 ) & & ( size ! = 8 ) ) ) {
return 0 ;
}
2006-10-21 23:33:03 +04:00
2008-07-22 06:44:03 +04:00
return 1 ;
2006-10-21 23:33:03 +04:00
}
2007-11-24 05:23:36 +03:00
static int netxen_pci_set_window_warning_count ;
2006-10-21 23:33:03 +04:00
2008-07-22 06:44:03 +04:00
unsigned long
netxen_nic_pci_set_window_128M ( struct netxen_adapter * adapter ,
unsigned long long addr )
2006-10-21 23:33:03 +04:00
{
2008-07-22 06:44:02 +04:00
void __iomem * offset ;
2006-10-21 23:33:03 +04:00
int window ;
2008-07-22 06:44:03 +04:00
unsigned long long qdr_max ;
2008-07-22 06:44:02 +04:00
uint8_t func = adapter - > ahw . pci_func ;
2006-10-21 23:33:03 +04:00
2008-07-22 06:44:03 +04:00
if ( NX_IS_REVISION_P2 ( adapter - > ahw . revision_id ) ) {
qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2 ;
} else {
qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3 ;
}
2006-10-21 23:33:03 +04:00
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 ;
2008-07-22 06:44:03 +04:00
if ( adapter - > ahw . ddr_mn_window ! = window ) {
adapter - > ahw . ddr_mn_window = window ;
2008-07-22 06:44:02 +04:00
offset = PCI_OFFSET_SECOND_RANGE ( adapter ,
NETXEN_PCIX_PH_REG ( PCIE_MN_WINDOW_REG ( func ) ) ) ;
writel ( window , offset ) ;
2006-10-21 23:33:03 +04:00
/* MUST make sure window is set before we forge on... */
2008-07-22 06:44:02 +04:00
readl ( offset ) ;
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 ;
2008-07-22 06:44:03 +04:00
} else if ( ADDR_IN_RANGE ( addr , NETXEN_ADDR_QDR_NET , qdr_max ) ) {
2006-10-21 23:33:03 +04:00
/* QDR network side */
addr - = NETXEN_ADDR_QDR_NET ;
window = ( addr > > 22 ) & 0x3f ;
2008-07-22 06:44:03 +04:00
if ( adapter - > ahw . qdr_sn_window ! = window ) {
adapter - > ahw . qdr_sn_window = window ;
2008-07-22 06:44:02 +04:00
offset = PCI_OFFSET_SECOND_RANGE ( adapter ,
NETXEN_PCIX_PH_REG ( PCIE_SN_WINDOW_REG ( func ) ) ) ;
writel ( ( window < < 22 ) , offset ) ;
2006-10-21 23:33:03 +04:00
/* MUST make sure window is set before we forge on... */
2008-07-22 06:44:02 +04:00
readl ( offset ) ;
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 ) ;
2008-07-22 06:44:03 +04:00
addr = - 1UL ;
}
return addr ;
}
/*
* Note : only 32 - bit writes !
*/
int netxen_nic_pci_write_immediate_128M ( struct netxen_adapter * adapter ,
u64 off , u32 data )
{
writel ( data , ( void __iomem * ) ( PCI_OFFSET_SECOND_RANGE ( adapter , off ) ) ) ;
return 0 ;
}
u32 netxen_nic_pci_read_immediate_128M ( struct netxen_adapter * adapter , u64 off )
{
return readl ( ( void __iomem * ) ( pci_base_offset ( adapter , off ) ) ) ;
}
void netxen_nic_pci_write_normalize_128M ( struct netxen_adapter * adapter ,
u64 off , u32 data )
{
writel ( data , NETXEN_CRB_NORMALIZE ( adapter , off ) ) ;
}
u32 netxen_nic_pci_read_normalize_128M ( struct netxen_adapter * adapter , u64 off )
{
return readl ( NETXEN_CRB_NORMALIZE ( adapter , off ) ) ;
}
unsigned long
netxen_nic_pci_set_window_2M ( struct netxen_adapter * adapter ,
unsigned long long addr )
{
int window ;
u32 win_read ;
2006-10-21 23:33:03 +04:00
2008-07-22 06:44:03 +04:00
if ( ADDR_IN_RANGE ( addr , NETXEN_ADDR_DDR_NET , NETXEN_ADDR_DDR_NET_MAX ) ) {
/* DDR network side */
window = MN_WIN ( addr ) ;
adapter - > ahw . ddr_mn_window = window ;
adapter - > hw_write_wx ( adapter ,
adapter - > ahw . mn_win_crb | NETXEN_PCI_CRBSPACE ,
& window , 4 ) ;
adapter - > hw_read_wx ( adapter ,
adapter - > ahw . mn_win_crb | NETXEN_PCI_CRBSPACE ,
& win_read , 4 ) ;
if ( ( win_read < < 17 ) ! = window ) {
printk ( KERN_INFO " Written MNwin (0x%x) != "
" Read MNwin (0x%x) \n " , window , win_read ) ;
}
addr = GET_MEM_OFFS_2M ( addr ) + NETXEN_PCI_DDR_NET ;
} else if ( ADDR_IN_RANGE ( addr ,
NETXEN_ADDR_OCM0 , NETXEN_ADDR_OCM0_MAX ) ) {
if ( ( addr & 0x00ff800 ) = = 0xff800 ) {
printk ( " %s: QM access not handled. \n " , __func__ ) ;
addr = - 1UL ;
}
window = OCM_WIN ( addr ) ;
adapter - > ahw . ddr_mn_window = window ;
adapter - > hw_write_wx ( adapter ,
adapter - > ahw . mn_win_crb | NETXEN_PCI_CRBSPACE ,
& window , 4 ) ;
adapter - > hw_read_wx ( adapter ,
adapter - > ahw . mn_win_crb | NETXEN_PCI_CRBSPACE ,
& win_read , 4 ) ;
if ( ( win_read > > 7 ) ! = window ) {
printk ( KERN_INFO " %s: Written OCMwin (0x%x) != "
" Read OCMwin (0x%x) \n " ,
__func__ , window , win_read ) ;
}
addr = GET_MEM_OFFS_2M ( addr ) + NETXEN_PCI_OCM0_2M ;
} else if ( ADDR_IN_RANGE ( addr ,
NETXEN_ADDR_QDR_NET , NETXEN_ADDR_QDR_NET_MAX_P3 ) ) {
/* QDR network side */
window = MS_WIN ( addr ) ;
adapter - > ahw . qdr_sn_window = window ;
adapter - > hw_write_wx ( adapter ,
adapter - > ahw . ms_win_crb | NETXEN_PCI_CRBSPACE ,
& window , 4 ) ;
adapter - > hw_read_wx ( adapter ,
adapter - > ahw . ms_win_crb | NETXEN_PCI_CRBSPACE ,
& win_read , 4 ) ;
if ( win_read ! = window ) {
printk ( KERN_INFO " %s: Written MSwin (0x%x) != "
" Read MSwin (0x%x) \n " ,
__func__ , window , win_read ) ;
}
addr = GET_MEM_OFFS_2M ( 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:%s Unknown address range! \n " ,
__func__ , netxen_nic_driver_name ) ;
}
addr = - 1UL ;
2006-10-21 23:33:03 +04:00
}
return addr ;
}
2008-07-22 06:44:03 +04:00
static int netxen_nic_pci_is_same_window ( struct netxen_adapter * adapter ,
unsigned long long addr )
{
int window ;
unsigned long long qdr_max ;
if ( NX_IS_REVISION_P2 ( adapter - > ahw . revision_id ) )
qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2 ;
else
qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3 ;
if ( ADDR_IN_RANGE ( addr ,
NETXEN_ADDR_DDR_NET , NETXEN_ADDR_DDR_NET_MAX ) ) {
/* DDR network side */
BUG ( ) ; /* MN access can not come here */
} else if ( ADDR_IN_RANGE ( addr ,
NETXEN_ADDR_OCM0 , NETXEN_ADDR_OCM0_MAX ) ) {
return 1 ;
} else if ( ADDR_IN_RANGE ( addr ,
NETXEN_ADDR_OCM1 , NETXEN_ADDR_OCM1_MAX ) ) {
return 1 ;
} else if ( ADDR_IN_RANGE ( addr , NETXEN_ADDR_QDR_NET , qdr_max ) ) {
/* QDR network side */
window = ( ( addr - NETXEN_ADDR_QDR_NET ) > > 22 ) & 0x3f ;
if ( adapter - > ahw . qdr_sn_window = = window )
return 1 ;
}
return 0 ;
}
static int netxen_nic_pci_mem_read_direct ( struct netxen_adapter * adapter ,
u64 off , void * data , int size )
{
unsigned long flags ;
void * addr ;
int ret = 0 ;
u64 start ;
uint8_t * mem_ptr = NULL ;
unsigned long mem_base ;
unsigned long mem_page ;
write_lock_irqsave ( & adapter - > adapter_lock , flags ) ;
/*
* If attempting to access unknown address or straddle hw windows ,
* do not access .
*/
start = adapter - > pci_set_window ( adapter , off ) ;
if ( ( start = = - 1UL ) | |
( netxen_nic_pci_is_same_window ( adapter , off + size - 1 ) = = 0 ) ) {
write_unlock_irqrestore ( & adapter - > adapter_lock , flags ) ;
printk ( KERN_ERR " %s out of bound pci memory access. "
2008-07-30 23:50:12 +04:00
" offset is 0x%llx \n " , netxen_nic_driver_name ,
( unsigned long long ) off ) ;
2008-07-22 06:44:03 +04:00
return - 1 ;
}
addr = ( void * ) ( pci_base_offset ( adapter , start ) ) ;
if ( ! addr ) {
write_unlock_irqrestore ( & adapter - > adapter_lock , flags ) ;
mem_base = pci_resource_start ( adapter - > pdev , 0 ) ;
mem_page = start & PAGE_MASK ;
/* Map two pages whenever user tries to access addresses in two
consecutive pages .
*/
if ( mem_page ! = ( ( start + size - 1 ) & PAGE_MASK ) )
mem_ptr = ioremap ( mem_base + mem_page , PAGE_SIZE * 2 ) ;
else
mem_ptr = ioremap ( mem_base + mem_page , PAGE_SIZE ) ;
2008-12-26 11:04:26 +03:00
if ( mem_ptr = = NULL ) {
2008-07-22 06:44:03 +04:00
* ( uint8_t * ) data = 0 ;
return - 1 ;
}
addr = mem_ptr ;
addr + = start & ( PAGE_SIZE - 1 ) ;
write_lock_irqsave ( & adapter - > adapter_lock , flags ) ;
}
switch ( size ) {
case 1 :
* ( uint8_t * ) data = readb ( addr ) ;
break ;
case 2 :
* ( uint16_t * ) data = readw ( addr ) ;
break ;
case 4 :
* ( uint32_t * ) data = readl ( addr ) ;
break ;
case 8 :
* ( uint64_t * ) data = readq ( addr ) ;
break ;
default :
ret = - 1 ;
break ;
}
write_unlock_irqrestore ( & adapter - > adapter_lock , flags ) ;
DPRINTK ( 1 , INFO , " read %llx \n " , * ( unsigned long long * ) data ) ;
if ( mem_ptr )
iounmap ( mem_ptr ) ;
return ret ;
}
static int
netxen_nic_pci_mem_write_direct ( struct netxen_adapter * adapter , u64 off ,
void * data , int size )
{
unsigned long flags ;
void * addr ;
int ret = 0 ;
u64 start ;
uint8_t * mem_ptr = NULL ;
unsigned long mem_base ;
unsigned long mem_page ;
write_lock_irqsave ( & adapter - > adapter_lock , flags ) ;
/*
* If attempting to access unknown address or straddle hw windows ,
* do not access .
*/
start = adapter - > pci_set_window ( adapter , off ) ;
if ( ( start = = - 1UL ) | |
( netxen_nic_pci_is_same_window ( adapter , off + size - 1 ) = = 0 ) ) {
write_unlock_irqrestore ( & adapter - > adapter_lock , flags ) ;
printk ( KERN_ERR " %s out of bound pci memory access. "
2008-07-30 23:50:12 +04:00
" offset is 0x%llx \n " , netxen_nic_driver_name ,
( unsigned long long ) off ) ;
2008-07-22 06:44:03 +04:00
return - 1 ;
}
addr = ( void * ) ( pci_base_offset ( adapter , start ) ) ;
if ( ! addr ) {
write_unlock_irqrestore ( & adapter - > adapter_lock , flags ) ;
mem_base = pci_resource_start ( adapter - > pdev , 0 ) ;
mem_page = start & PAGE_MASK ;
/* Map two pages whenever user tries to access addresses in two
* consecutive pages .
*/
if ( mem_page ! = ( ( start + size - 1 ) & PAGE_MASK ) )
mem_ptr = ioremap ( mem_base + mem_page , PAGE_SIZE * 2 ) ;
else
mem_ptr = ioremap ( mem_base + mem_page , PAGE_SIZE ) ;
2008-12-26 11:04:26 +03:00
if ( mem_ptr = = NULL )
2008-07-22 06:44:03 +04:00
return - 1 ;
addr = mem_ptr ;
addr + = start & ( PAGE_SIZE - 1 ) ;
write_lock_irqsave ( & adapter - > adapter_lock , flags ) ;
}
switch ( size ) {
case 1 :
writeb ( * ( uint8_t * ) data , addr ) ;
break ;
case 2 :
writew ( * ( uint16_t * ) data , addr ) ;
break ;
case 4 :
writel ( * ( uint32_t * ) data , addr ) ;
break ;
case 8 :
writeq ( * ( uint64_t * ) data , addr ) ;
break ;
default :
ret = - 1 ;
break ;
}
write_unlock_irqrestore ( & adapter - > adapter_lock , flags ) ;
DPRINTK ( 1 , INFO , " writing data %llx to offset %llx \n " ,
* ( unsigned long long * ) data , start ) ;
if ( mem_ptr )
iounmap ( mem_ptr ) ;
return ret ;
}
# define MAX_CTL_CHECK 1000
int
netxen_nic_pci_mem_write_128M ( struct netxen_adapter * adapter ,
u64 off , void * data , int size )
{
unsigned long flags , mem_crb ;
int i , j , ret = 0 , loop , sz [ 2 ] , off0 ;
uint32_t temp ;
uint64_t off8 , tmpw , word [ 2 ] = { 0 , 0 } ;
/*
* If not MN , go check for MS or invalid .
*/
if ( netxen_nic_pci_mem_bound_check ( adapter , off , size ) = = 0 )
return netxen_nic_pci_mem_write_direct ( adapter ,
off , data , size ) ;
off8 = off & 0xfffffff8 ;
off0 = off & 0x7 ;
sz [ 0 ] = ( size < ( 8 - off0 ) ) ? size : ( 8 - off0 ) ;
sz [ 1 ] = size - sz [ 0 ] ;
loop = ( ( off0 + size - 1 ) > > 3 ) + 1 ;
mem_crb = ( unsigned long ) pci_base_offset ( adapter , NETXEN_CRB_DDR_NET ) ;
if ( ( size ! = 8 ) | | ( off0 ! = 0 ) ) {
for ( i = 0 ; i < loop ; i + + ) {
if ( adapter - > pci_mem_read ( adapter ,
off8 + ( i < < 3 ) , & word [ i ] , 8 ) )
return - 1 ;
}
}
switch ( size ) {
case 1 :
tmpw = * ( ( uint8_t * ) data ) ;
break ;
case 2 :
tmpw = * ( ( uint16_t * ) data ) ;
break ;
case 4 :
tmpw = * ( ( uint32_t * ) data ) ;
break ;
case 8 :
default :
tmpw = * ( ( uint64_t * ) data ) ;
break ;
}
word [ 0 ] & = ~ ( ( ~ ( ~ 0ULL < < ( sz [ 0 ] * 8 ) ) ) < < ( off0 * 8 ) ) ;
word [ 0 ] | = tmpw < < ( off0 * 8 ) ;
if ( loop = = 2 ) {
word [ 1 ] & = ~ ( ~ 0ULL < < ( sz [ 1 ] * 8 ) ) ;
word [ 1 ] | = tmpw > > ( sz [ 0 ] * 8 ) ;
}
write_lock_irqsave ( & adapter - > adapter_lock , flags ) ;
netxen_nic_pci_change_crbwindow_128M ( adapter , 0 ) ;
for ( i = 0 ; i < loop ; i + + ) {
writel ( ( uint32_t ) ( off8 + ( i < < 3 ) ) ,
( void * ) ( mem_crb + MIU_TEST_AGT_ADDR_LO ) ) ;
writel ( 0 ,
( void * ) ( mem_crb + MIU_TEST_AGT_ADDR_HI ) ) ;
writel ( word [ i ] & 0xffffffff ,
( void * ) ( mem_crb + MIU_TEST_AGT_WRDATA_LO ) ) ;
writel ( ( word [ i ] > > 32 ) & 0xffffffff ,
( void * ) ( mem_crb + MIU_TEST_AGT_WRDATA_HI ) ) ;
writel ( MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE ,
( void * ) ( mem_crb + MIU_TEST_AGT_CTRL ) ) ;
writel ( MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE ,
( void * ) ( mem_crb + MIU_TEST_AGT_CTRL ) ) ;
for ( j = 0 ; j < MAX_CTL_CHECK ; j + + ) {
temp = readl (
( void * ) ( mem_crb + MIU_TEST_AGT_CTRL ) ) ;
if ( ( temp & MIU_TA_CTL_BUSY ) = = 0 )
break ;
}
if ( j > = MAX_CTL_CHECK ) {
printk ( " %s: %s Fail to write through agent \n " ,
__func__ , netxen_nic_driver_name ) ;
ret = - 1 ;
break ;
}
}
netxen_nic_pci_change_crbwindow_128M ( adapter , 1 ) ;
write_unlock_irqrestore ( & adapter - > adapter_lock , flags ) ;
return ret ;
}
int
netxen_nic_pci_mem_read_128M ( struct netxen_adapter * adapter ,
u64 off , void * data , int size )
{
unsigned long flags , mem_crb ;
int i , j = 0 , k , start , end , loop , sz [ 2 ] , off0 [ 2 ] ;
uint32_t temp ;
uint64_t off8 , val , word [ 2 ] = { 0 , 0 } ;
/*
* If not MN , go check for MS or invalid .
*/
if ( netxen_nic_pci_mem_bound_check ( adapter , off , size ) = = 0 )
return netxen_nic_pci_mem_read_direct ( adapter , off , data , size ) ;
off8 = off & 0xfffffff8 ;
off0 [ 0 ] = off & 0x7 ;
off0 [ 1 ] = 0 ;
sz [ 0 ] = ( size < ( 8 - off0 [ 0 ] ) ) ? size : ( 8 - off0 [ 0 ] ) ;
sz [ 1 ] = size - sz [ 0 ] ;
loop = ( ( off0 [ 0 ] + size - 1 ) > > 3 ) + 1 ;
mem_crb = ( unsigned long ) pci_base_offset ( adapter , NETXEN_CRB_DDR_NET ) ;
write_lock_irqsave ( & adapter - > adapter_lock , flags ) ;
netxen_nic_pci_change_crbwindow_128M ( adapter , 0 ) ;
for ( i = 0 ; i < loop ; i + + ) {
writel ( ( uint32_t ) ( off8 + ( i < < 3 ) ) ,
( void * ) ( mem_crb + MIU_TEST_AGT_ADDR_LO ) ) ;
writel ( 0 ,
( void * ) ( mem_crb + MIU_TEST_AGT_ADDR_HI ) ) ;
writel ( MIU_TA_CTL_ENABLE ,
( void * ) ( mem_crb + MIU_TEST_AGT_CTRL ) ) ;
writel ( MIU_TA_CTL_START | MIU_TA_CTL_ENABLE ,
( void * ) ( mem_crb + MIU_TEST_AGT_CTRL ) ) ;
for ( j = 0 ; j < MAX_CTL_CHECK ; j + + ) {
temp = readl (
( void * ) ( mem_crb + MIU_TEST_AGT_CTRL ) ) ;
if ( ( temp & MIU_TA_CTL_BUSY ) = = 0 )
break ;
}
if ( j > = MAX_CTL_CHECK ) {
printk ( KERN_ERR " %s: %s Fail to read through agent \n " ,
__func__ , netxen_nic_driver_name ) ;
break ;
}
start = off0 [ i ] > > 2 ;
end = ( off0 [ i ] + sz [ i ] - 1 ) > > 2 ;
for ( k = start ; k < = end ; k + + ) {
word [ i ] | = ( ( uint64_t ) readl (
( void * ) ( mem_crb +
MIU_TEST_AGT_RDDATA ( k ) ) ) < < ( 32 * k ) ) ;
}
}
netxen_nic_pci_change_crbwindow_128M ( adapter , 1 ) ;
write_unlock_irqrestore ( & adapter - > adapter_lock , flags ) ;
if ( j > = MAX_CTL_CHECK )
return - 1 ;
if ( sz [ 0 ] = = 8 ) {
val = word [ 0 ] ;
} else {
val = ( ( word [ 0 ] > > ( off0 [ 0 ] * 8 ) ) & ( ~ ( ~ 0ULL < < ( sz [ 0 ] * 8 ) ) ) ) |
( ( word [ 1 ] & ( ~ ( ~ 0ULL < < ( sz [ 1 ] * 8 ) ) ) ) < < ( sz [ 0 ] * 8 ) ) ;
}
switch ( size ) {
case 1 :
* ( uint8_t * ) data = val ;
break ;
case 2 :
* ( uint16_t * ) data = val ;
break ;
case 4 :
* ( uint32_t * ) data = val ;
break ;
case 8 :
* ( uint64_t * ) data = val ;
break ;
}
DPRINTK ( 1 , INFO , " read %llx \n " , * ( unsigned long long * ) data ) ;
return 0 ;
}
int
netxen_nic_pci_mem_write_2M ( struct netxen_adapter * adapter ,
u64 off , void * data , int size )
{
int i , j , ret = 0 , loop , sz [ 2 ] , off0 ;
uint32_t temp ;
uint64_t off8 , mem_crb , tmpw , word [ 2 ] = { 0 , 0 } ;
/*
* If not MN , go check for MS or invalid .
*/
if ( off > = NETXEN_ADDR_QDR_NET & & off < = NETXEN_ADDR_QDR_NET_MAX_P3 )
mem_crb = NETXEN_CRB_QDR_NET ;
else {
mem_crb = NETXEN_CRB_DDR_NET ;
if ( netxen_nic_pci_mem_bound_check ( adapter , off , size ) = = 0 )
return netxen_nic_pci_mem_write_direct ( adapter ,
off , data , size ) ;
}
off8 = off & 0xfffffff8 ;
off0 = off & 0x7 ;
sz [ 0 ] = ( size < ( 8 - off0 ) ) ? size : ( 8 - off0 ) ;
sz [ 1 ] = size - sz [ 0 ] ;
loop = ( ( off0 + size - 1 ) > > 3 ) + 1 ;
if ( ( size ! = 8 ) | | ( off0 ! = 0 ) ) {
for ( i = 0 ; i < loop ; i + + ) {
if ( adapter - > pci_mem_read ( adapter , off8 + ( i < < 3 ) ,
& word [ i ] , 8 ) )
return - 1 ;
}
}
switch ( size ) {
case 1 :
tmpw = * ( ( uint8_t * ) data ) ;
break ;
case 2 :
tmpw = * ( ( uint16_t * ) data ) ;
break ;
case 4 :
tmpw = * ( ( uint32_t * ) data ) ;
break ;
case 8 :
default :
tmpw = * ( ( uint64_t * ) data ) ;
break ;
}
word [ 0 ] & = ~ ( ( ~ ( ~ 0ULL < < ( sz [ 0 ] * 8 ) ) ) < < ( off0 * 8 ) ) ;
word [ 0 ] | = tmpw < < ( off0 * 8 ) ;
if ( loop = = 2 ) {
word [ 1 ] & = ~ ( ~ 0ULL < < ( sz [ 1 ] * 8 ) ) ;
word [ 1 ] | = tmpw > > ( sz [ 0 ] * 8 ) ;
}
/*
* don ' t lock here - write_wx gets the lock if each time
* write_lock_irqsave ( & adapter - > adapter_lock , flags ) ;
* netxen_nic_pci_change_crbwindow_128M ( adapter , 0 ) ;
*/
for ( i = 0 ; i < loop ; i + + ) {
temp = off8 + ( i < < 3 ) ;
adapter - > hw_write_wx ( adapter ,
mem_crb + MIU_TEST_AGT_ADDR_LO , & temp , 4 ) ;
temp = 0 ;
adapter - > hw_write_wx ( adapter ,
mem_crb + MIU_TEST_AGT_ADDR_HI , & temp , 4 ) ;
temp = word [ i ] & 0xffffffff ;
adapter - > hw_write_wx ( adapter ,
mem_crb + MIU_TEST_AGT_WRDATA_LO , & temp , 4 ) ;
temp = ( word [ i ] > > 32 ) & 0xffffffff ;
adapter - > hw_write_wx ( adapter ,
mem_crb + MIU_TEST_AGT_WRDATA_HI , & temp , 4 ) ;
temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE ;
adapter - > hw_write_wx ( adapter ,
mem_crb + MIU_TEST_AGT_CTRL , & temp , 4 ) ;
temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE ;
adapter - > hw_write_wx ( adapter ,
mem_crb + MIU_TEST_AGT_CTRL , & temp , 4 ) ;
for ( j = 0 ; j < MAX_CTL_CHECK ; j + + ) {
adapter - > hw_read_wx ( adapter ,
mem_crb + MIU_TEST_AGT_CTRL , & temp , 4 ) ;
if ( ( temp & MIU_TA_CTL_BUSY ) = = 0 )
break ;
}
if ( j > = MAX_CTL_CHECK ) {
printk ( KERN_ERR " %s: Fail to write through agent \n " ,
netxen_nic_driver_name ) ;
ret = - 1 ;
break ;
}
}
/*
* netxen_nic_pci_change_crbwindow_128M ( adapter , 1 ) ;
* write_unlock_irqrestore ( & adapter - > adapter_lock , flags ) ;
*/
return ret ;
}
int
netxen_nic_pci_mem_read_2M ( struct netxen_adapter * adapter ,
u64 off , void * data , int size )
{
int i , j = 0 , k , start , end , loop , sz [ 2 ] , off0 [ 2 ] ;
uint32_t temp ;
uint64_t off8 , val , mem_crb , word [ 2 ] = { 0 , 0 } ;
/*
* If not MN , go check for MS or invalid .
*/
if ( off > = NETXEN_ADDR_QDR_NET & & off < = NETXEN_ADDR_QDR_NET_MAX_P3 )
mem_crb = NETXEN_CRB_QDR_NET ;
else {
mem_crb = NETXEN_CRB_DDR_NET ;
if ( netxen_nic_pci_mem_bound_check ( adapter , off , size ) = = 0 )
return netxen_nic_pci_mem_read_direct ( adapter ,
off , data , size ) ;
}
off8 = off & 0xfffffff8 ;
off0 [ 0 ] = off & 0x7 ;
off0 [ 1 ] = 0 ;
sz [ 0 ] = ( size < ( 8 - off0 [ 0 ] ) ) ? size : ( 8 - off0 [ 0 ] ) ;
sz [ 1 ] = size - sz [ 0 ] ;
loop = ( ( off0 [ 0 ] + size - 1 ) > > 3 ) + 1 ;
/*
* don ' t lock here - write_wx gets the lock if each time
* write_lock_irqsave ( & adapter - > adapter_lock , flags ) ;
* netxen_nic_pci_change_crbwindow_128M ( adapter , 0 ) ;
*/
for ( i = 0 ; i < loop ; i + + ) {
temp = off8 + ( i < < 3 ) ;
adapter - > hw_write_wx ( adapter ,
mem_crb + MIU_TEST_AGT_ADDR_LO , & temp , 4 ) ;
temp = 0 ;
adapter - > hw_write_wx ( adapter ,
mem_crb + MIU_TEST_AGT_ADDR_HI , & temp , 4 ) ;
temp = MIU_TA_CTL_ENABLE ;
adapter - > hw_write_wx ( adapter ,
mem_crb + MIU_TEST_AGT_CTRL , & temp , 4 ) ;
temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE ;
adapter - > hw_write_wx ( adapter ,
mem_crb + MIU_TEST_AGT_CTRL , & temp , 4 ) ;
for ( j = 0 ; j < MAX_CTL_CHECK ; j + + ) {
adapter - > hw_read_wx ( adapter ,
mem_crb + MIU_TEST_AGT_CTRL , & temp , 4 ) ;
if ( ( temp & MIU_TA_CTL_BUSY ) = = 0 )
break ;
}
if ( j > = MAX_CTL_CHECK ) {
printk ( KERN_ERR " %s: Fail to read through agent \n " ,
netxen_nic_driver_name ) ;
break ;
}
start = off0 [ i ] > > 2 ;
end = ( off0 [ i ] + sz [ i ] - 1 ) > > 2 ;
for ( k = start ; k < = end ; k + + ) {
adapter - > hw_read_wx ( adapter ,
mem_crb + MIU_TEST_AGT_RDDATA ( k ) , & temp , 4 ) ;
word [ i ] | = ( ( uint64_t ) temp < < ( 32 * k ) ) ;
}
}
/*
* netxen_nic_pci_change_crbwindow_128M ( adapter , 1 ) ;
* write_unlock_irqrestore ( & adapter - > adapter_lock , flags ) ;
*/
if ( j > = MAX_CTL_CHECK )
return - 1 ;
if ( sz [ 0 ] = = 8 ) {
val = word [ 0 ] ;
} else {
val = ( ( word [ 0 ] > > ( off0 [ 0 ] * 8 ) ) & ( ~ ( ~ 0ULL < < ( sz [ 0 ] * 8 ) ) ) ) |
( ( word [ 1 ] & ( ~ ( ~ 0ULL < < ( sz [ 1 ] * 8 ) ) ) ) < < ( sz [ 0 ] * 8 ) ) ;
}
switch ( size ) {
case 1 :
* ( uint8_t * ) data = val ;
break ;
case 2 :
* ( uint16_t * ) data = val ;
break ;
case 4 :
* ( uint32_t * ) data = val ;
break ;
case 8 :
* ( uint64_t * ) data = val ;
break ;
}
DPRINTK ( 1 , INFO , " read %llx \n " , * ( unsigned long long * ) data ) ;
return 0 ;
}
/*
* Note : only 32 - bit writes !
*/
int netxen_nic_pci_write_immediate_2M ( struct netxen_adapter * adapter ,
u64 off , u32 data )
{
adapter - > hw_write_wx ( adapter , off , & data , 4 ) ;
return 0 ;
}
u32 netxen_nic_pci_read_immediate_2M ( struct netxen_adapter * adapter , u64 off )
{
u32 temp ;
adapter - > hw_read_wx ( adapter , off , & temp , 4 ) ;
return temp ;
}
void netxen_nic_pci_write_normalize_2M ( struct netxen_adapter * adapter ,
u64 off , u32 data )
{
adapter - > hw_write_wx ( adapter , off , & data , 4 ) ;
}
u32 netxen_nic_pci_read_normalize_2M ( struct netxen_adapter * adapter , u64 off )
{
u32 temp ;
adapter - > hw_read_wx ( adapter , off , & temp , 4 ) ;
return temp ;
}
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 ;
}
2009-01-15 07:48:32 +03:00
if ( boardinfo - > board_type = = NETXEN_BRDTYPE_P3_4_GB_MM ) {
u32 gpio = netxen_nic_reg_read ( adapter ,
NETXEN_ROMUSB_GLB_PAD_GPIO_I ) ;
if ( ( gpio & 0x8000 ) = = 0 )
boardinfo - > board_type = NETXEN_BRDTYPE_P3_10G_TP ;
}
2006-10-21 23:33:03 +04:00
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 :
2008-07-22 06:44:02 +04:00
case NETXEN_BRDTYPE_P3_HMEZ :
case NETXEN_BRDTYPE_P3_XG_LOM :
case NETXEN_BRDTYPE_P3_10G_CX4 :
case NETXEN_BRDTYPE_P3_10G_CX4_LP :
case NETXEN_BRDTYPE_P3_IMEZ :
case NETXEN_BRDTYPE_P3_10G_SFP_PLUS :
2008-08-01 14:14:56 +04:00
case NETXEN_BRDTYPE_P3_10G_SFP_CT :
case NETXEN_BRDTYPE_P3_10G_SFP_QT :
2008-07-22 06:44:02 +04:00
case NETXEN_BRDTYPE_P3_10G_XFP :
case NETXEN_BRDTYPE_P3_10000_BASE_T :
2006-10-21 23:33:03 +04:00
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 :
2008-07-22 06:44:02 +04:00
case NETXEN_BRDTYPE_P3_REF_QG :
case NETXEN_BRDTYPE_P3_4_GB :
case NETXEN_BRDTYPE_P3_4_GB_MM :
2006-10-21 23:33:03 +04:00
adapter - > ahw . board_type = NETXEN_NIC_GBE ;
break ;
2009-01-15 07:48:32 +03:00
case NETXEN_BRDTYPE_P3_10G_TP :
adapter - > ahw . board_type = ( adapter - > portnum < 2 ) ?
NETXEN_NIC_XGBE : NETXEN_NIC_GBE ;
break ;
2006-10-21 23:33:03 +04:00
default :
printk ( " %s: Unknown(%x) \n " , netxen_nic_driver_name ,
boardinfo - > board_type ) ;
2008-08-01 14:14:56 +04:00
rv = - ENODEV ;
2006-10-21 23:33:03 +04:00
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
{
2008-08-01 14:14:59 +04:00
new_mtu + = MTU_FUDGE_FACTOR ;
2006-10-21 23:33:03 +04:00
netxen_nic_write_w0 ( adapter ,
2008-06-16 09:59:44 +04:00
NETXEN_NIU_GB_MAX_FRAME_SIZE ( adapter - > physical_port ) ,
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
{
2008-08-01 14:14:59 +04:00
new_mtu + = MTU_FUDGE_FACTOR ;
2008-06-16 09:59:44 +04:00
if ( adapter - > physical_port = = 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
2008-07-22 06:44:03 +04:00
netxen_crb_writelit_adapter ( struct netxen_adapter * adapter ,
unsigned long off , int data )
2006-10-21 23:33:03 +04:00
{
2008-07-22 06:44:03 +04:00
adapter - > hw_write_wx ( adapter , off , & data , 4 ) ;
2006-10-21 23:33:03 +04:00
}
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 ;
2008-08-01 14:14:55 +04:00
__u32 port_mode ;
2006-10-21 23:33:03 +04:00
2009-01-15 07:48:32 +03:00
if ( ! netif_carrier_ok ( adapter - > netdev ) ) {
adapter - > link_speed = 0 ;
adapter - > link_duplex = - 1 ;
adapter - > link_autoneg = AUTONEG_ENABLE ;
return ;
}
2008-08-01 14:14:55 +04:00
2009-01-15 07:48:32 +03:00
if ( adapter - > ahw . board_type = = NETXEN_NIC_GBE ) {
2008-08-01 14:14:55 +04:00
adapter - > hw_read_wx ( adapter ,
NETXEN_PORT_MODE_ADDR , & port_mode , 4 ) ;
if ( port_mode = = NETXEN_PORT_MODE_802_3_AP ) {
adapter - > link_speed = SPEED_1000 ;
adapter - > link_duplex = DUPLEX_FULL ;
adapter - > link_autoneg = AUTONEG_DISABLE ;
return ;
}
2006-12-04 20:18:00 +03:00
if ( adapter - > phy_read
2008-08-01 14:14:55 +04:00
& & adapter - > 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 :
2009-01-15 07:48:32 +03:00
adapter - > link_speed = 0 ;
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
2008-08-01 14:14:55 +04:00
& & adapter - > 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 :
2009-01-15 07:48:32 +03:00
adapter - > link_speed = 0 ;
2007-04-20 18:52:37 +04:00
adapter - > link_duplex = - 1 ;
2006-10-21 23:33:03 +04:00
}
}
}
void netxen_nic_flash_print ( struct netxen_adapter * adapter )
{
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 ] ;
2008-04-22 22:48:35 +04:00
char serial_num [ 32 ] ;
int i , addr ;
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 ) ;
2008-06-16 09:59:45 +04:00
adapter - > driver_mismatch = 0 ;
ptr32 = ( u32 * ) & serial_num ;
addr = NETXEN_USER_START +
offsetof ( struct netxen_new_user_info , serial_num ) ;
for ( i = 0 ; i < 8 ; 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 ) ;
adapter - > driver_mismatch = 1 ;
return ;
2006-11-29 20:00:10 +03:00
}
2008-06-16 09:59:45 +04:00
ptr32 + + ;
addr + = sizeof ( u32 ) ;
}
2008-07-22 06:44:03 +04:00
adapter - > hw_read_wx ( adapter , NETXEN_FW_VERSION_MAJOR , & fw_major , 4 ) ;
adapter - > hw_read_wx ( adapter , NETXEN_FW_VERSION_MINOR , & fw_minor , 4 ) ;
adapter - > hw_read_wx ( adapter , NETXEN_FW_VERSION_SUB , & fw_build , 4 ) ;
2008-04-22 22:48:35 +04:00
2008-07-22 06:44:04 +04:00
adapter - > fw_major = fw_major ;
2008-06-16 09:59:45 +04:00
if ( adapter - > portnum = = 0 ) {
2006-11-29 20:00:10 +03:00
get_brd_name_by_type ( board_info - > board_type , brd_name ) ;
2008-08-08 11:08:45 +04:00
printk ( KERN_INFO " NetXen %s Board S/N %s Chip rev 0x%x \n " ,
brd_name , serial_num , adapter - > ahw . revision_id ) ;
printk ( KERN_INFO " NetXen Firmware version %d.%d.%d \n " ,
fw_major , fw_minor , fw_build ) ;
2006-10-21 23:33:03 +04:00
}
2008-06-16 09:59:45 +04:00
2008-07-22 06:44:10 +04:00
if ( NETXEN_VERSION_CODE ( fw_major , fw_minor , fw_build ) <
NETXEN_VERSION_CODE ( 3 , 4 , 216 ) ) {
2006-10-21 23:33:03 +04:00
adapter - > driver_mismatch = 1 ;
2008-07-22 06:44:10 +04:00
printk ( KERN_ERR " %s: firmware version %d.%d.%d unsupported \n " ,
netxen_nic_driver_name ,
fw_major , fw_minor , fw_build ) ;
2008-06-16 09:59:45 +04:00
return ;
}
2006-10-21 23:33:03 +04:00
}