in idt77252.c [3243:3513]
static int init_card(struct atm_dev *dev)
{
struct idt77252_dev *card = dev->dev_data;
struct pci_dev *pcidev = card->pcidev;
unsigned long tmpl, modl;
unsigned int linkrate, rsvdcr;
unsigned int tst_entries;
struct net_device *tmp;
char tname[10];
u32 size;
u_char pci_byte;
u32 conf;
int i, k;
if (test_bit(IDT77252_BIT_INIT, &card->flags)) {
printk("Error: SAR already initialized.\n");
return -1;
}
/*****************************************************************/
/* P C I C O N F I G U R A T I O N */
/*****************************************************************/
/* Set PCI Retry-Timeout and TRDY timeout */
IPRINTK("%s: Checking PCI retries.\n", card->name);
if (pci_read_config_byte(pcidev, 0x40, &pci_byte) != 0) {
printk("%s: can't read PCI retry timeout.\n", card->name);
deinit_card(card);
return -1;
}
if (pci_byte != 0) {
IPRINTK("%s: PCI retry timeout: %d, set to 0.\n",
card->name, pci_byte);
if (pci_write_config_byte(pcidev, 0x40, 0) != 0) {
printk("%s: can't set PCI retry timeout.\n",
card->name);
deinit_card(card);
return -1;
}
}
IPRINTK("%s: Checking PCI TRDY.\n", card->name);
if (pci_read_config_byte(pcidev, 0x41, &pci_byte) != 0) {
printk("%s: can't read PCI TRDY timeout.\n", card->name);
deinit_card(card);
return -1;
}
if (pci_byte != 0) {
IPRINTK("%s: PCI TRDY timeout: %d, set to 0.\n",
card->name, pci_byte);
if (pci_write_config_byte(pcidev, 0x41, 0) != 0) {
printk("%s: can't set PCI TRDY timeout.\n", card->name);
deinit_card(card);
return -1;
}
}
/* Reset Timer register */
if (readl(SAR_REG_STAT) & SAR_STAT_TMROF) {
printk("%s: resetting timer overflow.\n", card->name);
writel(SAR_STAT_TMROF, SAR_REG_STAT);
}
IPRINTK("%s: Request IRQ ... ", card->name);
if (request_irq(pcidev->irq, idt77252_interrupt, IRQF_SHARED,
card->name, card) != 0) {
printk("%s: can't allocate IRQ.\n", card->name);
deinit_card(card);
return -1;
}
IPRINTK("got %d.\n", pcidev->irq);
/*****************************************************************/
/* C H E C K A N D I N I T S R A M */
/*****************************************************************/
IPRINTK("%s: Initializing SRAM\n", card->name);
/* preset size of connecton table, so that init_sram() knows about it */
conf = SAR_CFG_TX_FIFO_SIZE_9 | /* Use maximum fifo size */
SAR_CFG_RXSTQ_SIZE_8k | /* Receive Status Queue is 8k */
SAR_CFG_IDLE_CLP | /* Set CLP on idle cells */
#ifndef ATM_IDT77252_SEND_IDLE
SAR_CFG_NO_IDLE | /* Do not send idle cells */
#endif
0;
if (card->sramsize == (512 * 1024))
conf |= SAR_CFG_CNTBL_1k;
else
conf |= SAR_CFG_CNTBL_512;
switch (vpibits) {
case 0:
conf |= SAR_CFG_VPVCS_0;
break;
default:
case 1:
conf |= SAR_CFG_VPVCS_1;
break;
case 2:
conf |= SAR_CFG_VPVCS_2;
break;
case 8:
conf |= SAR_CFG_VPVCS_8;
break;
}
writel(readl(SAR_REG_CFG) | conf, SAR_REG_CFG);
init_sram(card);
/********************************************************************/
/* A L L O C R A M A N D S E T V A R I O U S T H I N G S */
/********************************************************************/
/* Initialize TSQ */
if (0 != init_tsq(card)) {
deinit_card(card);
return -1;
}
/* Initialize RSQ */
if (0 != init_rsq(card)) {
deinit_card(card);
return -1;
}
card->vpibits = vpibits;
if (card->sramsize == (512 * 1024)) {
card->vcibits = 10 - card->vpibits;
} else {
card->vcibits = 9 - card->vpibits;
}
card->vcimask = 0;
for (k = 0, i = 1; k < card->vcibits; k++) {
card->vcimask |= i;
i <<= 1;
}
IPRINTK("%s: Setting VPI/VCI mask to zero.\n", card->name);
writel(0, SAR_REG_VPM);
/* Little Endian Order */
writel(0, SAR_REG_GP);
/* Initialize RAW Cell Handle Register */
card->raw_cell_hnd = dma_alloc_coherent(&card->pcidev->dev,
2 * sizeof(u32),
&card->raw_cell_paddr,
GFP_KERNEL);
if (!card->raw_cell_hnd) {
printk("%s: memory allocation failure.\n", card->name);
deinit_card(card);
return -1;
}
writel(card->raw_cell_paddr, SAR_REG_RAWHND);
IPRINTK("%s: raw cell handle is at 0x%p.\n", card->name,
card->raw_cell_hnd);
size = sizeof(struct vc_map *) * card->tct_size;
IPRINTK("%s: allocate %d byte for VC map.\n", card->name, size);
card->vcs = vzalloc(size);
if (!card->vcs) {
printk("%s: memory allocation failure.\n", card->name);
deinit_card(card);
return -1;
}
size = sizeof(struct vc_map *) * card->scd_size;
IPRINTK("%s: allocate %d byte for SCD to VC mapping.\n",
card->name, size);
card->scd2vc = vzalloc(size);
if (!card->scd2vc) {
printk("%s: memory allocation failure.\n", card->name);
deinit_card(card);
return -1;
}
size = sizeof(struct tst_info) * (card->tst_size - 2);
IPRINTK("%s: allocate %d byte for TST to VC mapping.\n",
card->name, size);
card->soft_tst = vmalloc(size);
if (!card->soft_tst) {
printk("%s: memory allocation failure.\n", card->name);
deinit_card(card);
return -1;
}
for (i = 0; i < card->tst_size - 2; i++) {
card->soft_tst[i].tste = TSTE_OPC_VAR;
card->soft_tst[i].vc = NULL;
}
if (dev->phy == NULL) {
printk("%s: No LT device defined.\n", card->name);
deinit_card(card);
return -1;
}
if (dev->phy->ioctl == NULL) {
printk("%s: LT had no IOCTL function defined.\n", card->name);
deinit_card(card);
return -1;
}
#ifdef CONFIG_ATM_IDT77252_USE_SUNI
/*
* this is a jhs hack to get around special functionality in the
* phy driver for the atecom hardware; the functionality doesn't
* exist in the linux atm suni driver
*
* it isn't the right way to do things, but as the guy from NIST
* said, talking about their measurement of the fine structure
* constant, "it's good enough for government work."
*/
linkrate = 149760000;
#endif
card->link_pcr = (linkrate / 8 / 53);
printk("%s: Linkrate on ATM line : %u bit/s, %u cell/s.\n",
card->name, linkrate, card->link_pcr);
#ifdef ATM_IDT77252_SEND_IDLE
card->utopia_pcr = card->link_pcr;
#else
card->utopia_pcr = (160000000 / 8 / 54);
#endif
rsvdcr = 0;
if (card->utopia_pcr > card->link_pcr)
rsvdcr = card->utopia_pcr - card->link_pcr;
tmpl = (unsigned long) rsvdcr * ((unsigned long) card->tst_size - 2);
modl = tmpl % (unsigned long)card->utopia_pcr;
tst_entries = (int) (tmpl / (unsigned long)card->utopia_pcr);
if (modl)
tst_entries++;
card->tst_free -= tst_entries;
fill_tst(card, NULL, tst_entries, TSTE_OPC_NULL);
#ifdef HAVE_EEPROM
idt77252_eeprom_init(card);
printk("%s: EEPROM: %02x:", card->name,
idt77252_eeprom_read_status(card));
for (i = 0; i < 0x80; i++) {
printk(" %02x",
idt77252_eeprom_read_byte(card, i)
);
}
printk("\n");
#endif /* HAVE_EEPROM */
/*
* XXX: <hack>
*/
sprintf(tname, "eth%d", card->index);
tmp = dev_get_by_name(&init_net, tname); /* jhs: was "tmp = dev_get(tname);" */
if (tmp) {
memcpy(card->atmdev->esi, tmp->dev_addr, 6);
dev_put(tmp);
printk("%s: ESI %pM\n", card->name, card->atmdev->esi);
}
/*
* XXX: </hack>
*/
/* Set Maximum Deficit Count for now. */
writel(0xffff, SAR_REG_MDFCT);
set_bit(IDT77252_BIT_INIT, &card->flags);
XPRINTK("%s: IDT77252 ABR SAR initialization complete.\n", card->name);
return 0;
}