static int init_card()

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;
}