/*
* Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* 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.
*
* 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.
*
* 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.
*
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
*
* Contact Information:
* info@netxen.com
* NetXen Inc,
* 18922 Forge Drive
* Cupertino, CA 95014-0701
*
*/
#include <linux/netdevice.h>
#include <linux/delay.h>
#include "netxen_nic.h"
#include "netxen_nic_hw.h"
#include "netxen_nic_phan_reg.h"
struct crb_addr_pair {
u32 addr;
u32 data;
};
#define NETXEN_MAX_CRB_XFORM 60
static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM];
#define NETXEN_ADDR_ERROR (0xffffffff)
#define crb_addr_transform(name) \
crb_addr_xform[NETXEN_HW_PX_MAP_CRB_##name] = \
NETXEN_HW_CRB_HUB_AGT_ADR_##name << 20
#define NETXEN_NIC_XDMA_RESET 0x8000ff
static void
netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ringid);
static void crb_addr_transform_setup(void)
{
crb_addr_transform(XDMA);
crb_addr_transform(TIMR);
crb_addr_transform(SRE);
crb_addr_transform(SQN3);
crb_addr_transform(SQN2);
crb_addr_transform(SQN1);
crb_addr_transform(SQN0);
crb_addr_transform(SQS3);
crb_addr_transform(SQS2);
crb_addr_transform(SQS1);
crb_addr_transform(SQS0);
crb_addr_transform(RPMX7);
crb_addr_transform(RPMX6);
crb_addr_transform(RPMX5);
crb_addr_transform(RPMX4);
crb_addr_transform(RPMX3);
crb_addr_transform(RPMX2);
crb_addr_transform(RPMX1);
crb_addr_transform(RPMX0);
crb_addr_transform(ROMUSB);
crb_addr_transform(SN);
crb_addr_transform(QMN);
crb_addr_transform(QMS);
crb_addr_transform(PGNI);
crb_addr_transform(PGND);
crb_addr_transform(PGN3);
crb_addr_transform(PGN2);
crb_addr_transform(PGN1);
crb_addr_transform(PGN0);
crb_addr_transform(PGSI);
crb_addr_transform(PGSD);
crb_addr_transform(PGS3);
crb_addr_transform(PGS2);
crb_addr_transform(PGS1);
crb_addr_transform(PGS0);
crb_addr_transform(PS);
crb_addr_transform(PH);
crb_addr_transform(NIU);
crb_addr_transform(I2Q);
crb_addr_transform(EG);
crb_addr_transform(MN);
crb_addr_transform(MS);
crb_addr_transform(CAS2);
crb_addr_transform(CAS1);
crb_addr_transform(CAS0);
crb_addr_transform(CAM);
crb_addr_transform(C2C1);
crb_addr_transform(C2C0);
crb_addr_transform(SMB);
crb_addr_transform(OCM0);
crb_addr_transform(I2C0);
}
int netxen_init_firmware(struct netxen_adapter *adapter)
{
u32 state = 0, loops = 0, err = 0;
/* Window 1 call */
state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE);
if (state == PHAN_INITIALIZE_ACK)
return 0;
while (state != PHAN_INITIALIZE_COMPLETE && loops < 2000) {
msleep(1);
/* Window 1 call */
state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE);
loops++;
}
if (loops >= 2000) {
printk(KERN_ERR "Cmd Peg initialization not complete:%x.\n",
state);
err = -EIO;
return err;
}
/* Window 1 call */
adapter->pci_write_normalize(adapter,
CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT);
adapter->pci_write_normalize(adapter,
CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC);
adapter->pci_write_normalize(adapter,
CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE);
adapter->pci_write_normalize(adapter,
CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
return err;
}
void netxen_release_rx_buffers(