コード例 #1
0
ファイル: 3c589_cs.c プロジェクト: 3sOx/asuswrt-merlin
static int tc589_config(struct pcmcia_device *link)
{
    struct net_device *dev = link->priv;
    __be16 *phys_addr;
    int ret, i, j, multi = 0, fifo;
    unsigned int ioaddr;
    char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
    u8 *buf;
    size_t len;

    dev_dbg(&link->dev, "3c589_config\n");

    phys_addr = (__be16 *)dev->dev_addr;
    /* Is this a 3c562? */
    if (link->manf_id != MANFID_3COM)
	    printk(KERN_INFO "3c589_cs: hmmm, is this really a "
		   "3Com card??\n");
    multi = (link->card_id == PRODID_3COM_3C562);

    link->io_lines = 16;

    /* For the 3c562, the base address must be xx00-xx7f */
    for (i = j = 0; j < 0x400; j += 0x10) {
	if (multi && (j & 0x80)) continue;
	link->resource[0]->start = j ^ 0x300;
	i = pcmcia_request_io(link);
	if (i == 0)
		break;
    }
    if (i != 0)
	goto failed;

    ret = pcmcia_request_irq(link, el3_interrupt);
    if (ret)
	    goto failed;

    ret = pcmcia_request_configuration(link, &link->conf);
    if (ret)
	    goto failed;

    dev->irq = link->irq;
    dev->base_addr = link->resource[0]->start;
    ioaddr = dev->base_addr;
    EL3WINDOW(0);

    /* The 3c589 has an extra EEPROM for configuration info, including
       the hardware address.  The 3c562 puts the address in the CIS. */
    len = pcmcia_get_tuple(link, 0x88, &buf);
    if (buf && len >= 6) {
	    for (i = 0; i < 3; i++)
		    phys_addr[i] = htons(le16_to_cpu(buf[i*2]));
	    kfree(buf);
    } else {
	kfree(buf); /* 0 < len < 6 */
	for (i = 0; i < 3; i++)
	    phys_addr[i] = htons(read_eeprom(ioaddr, i));
	if (phys_addr[0] == htons(0x6060)) {
	    printk(KERN_ERR "3c589_cs: IO port conflict at 0x%03lx"
		   "-0x%03lx\n", dev->base_addr, dev->base_addr+15);
	    goto failed;
	}
    }

    /* The address and resource configuration register aren't loaded from
       the EEPROM and *must* be set to 0 and IRQ3 for the PCMCIA version. */
    outw(0x3f00, ioaddr + 8);
    fifo = inl(ioaddr);

    /* The if_port symbol can be set when the module is loaded */
    if ((if_port >= 0) && (if_port <= 3))
	dev->if_port = if_port;
    else
	printk(KERN_ERR "3c589_cs: invalid if_port requested\n");

    SET_NETDEV_DEV(dev, &link->dev);

    if (register_netdev(dev) != 0) {
	printk(KERN_ERR "3c589_cs: register_netdev() failed\n");
	goto failed;
    }

    netdev_info(dev, "3Com 3c%s, io %#3lx, irq %d, hw_addr %pM\n",
		(multi ? "562" : "589"), dev->base_addr, dev->irq,
		dev->dev_addr);
    netdev_info(dev, "  %dK FIFO split %s Rx:Tx, %s xcvr\n",
		(fifo & 7) ? 32 : 8, ram_split[(fifo >> 16) & 3],
		if_names[dev->if_port]);
    return 0;

failed:
    tc589_release(link);
    return -ENODEV;
} /* tc589_config */
コード例 #2
0
ファイル: nmclan_cs.c プロジェクト: Aircell/asp-kernel
static int nmclan_config(struct pcmcia_device *link)
{
  struct net_device *dev = link->priv;
  mace_private *lp = netdev_priv(dev);
  u8 *buf;
  size_t len;
  int i, ret;
  unsigned int ioaddr;

  dev_dbg(&link->dev, "nmclan_config\n");

  ret = pcmcia_request_io(link, &link->io);
  if (ret)
	  goto failed;
  ret = pcmcia_request_irq(link, &link->irq);
  if (ret)
	  goto failed;
  ret = pcmcia_request_configuration(link, &link->conf);
  if (ret)
	  goto failed;

  dev->irq = link->irq.AssignedIRQ;
  dev->base_addr = link->io.BasePort1;

  ioaddr = dev->base_addr;

  /* Read the ethernet address from the CIS. */
  len = pcmcia_get_tuple(link, 0x80, &buf);
  if (!buf || len < ETHER_ADDR_LEN) {
	  kfree(buf);
	  goto failed;
  }
  memcpy(dev->dev_addr, buf, ETHER_ADDR_LEN);
  kfree(buf);

  /* Verify configuration by reading the MACE ID. */
  {
    char sig[2];

    sig[0] = mace_read(lp, ioaddr, MACE_CHIPIDL);
    sig[1] = mace_read(lp, ioaddr, MACE_CHIPIDH);
    if ((sig[0] == 0x40) && ((sig[1] & 0x0F) == 0x09)) {
      dev_dbg(&link->dev, "nmclan_cs configured: mace id=%x %x\n",
	    sig[0], sig[1]);
    } else {
      printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should"
	     " be 0x40 0x?9\n", sig[0], sig[1]);
      return -ENODEV;
    }
  }

  if(mace_init(lp, ioaddr, dev->dev_addr) == -1)
  	goto failed;

  /* The if_port symbol can be set when the module is loaded */
  if (if_port <= 2)
    dev->if_port = if_port;
  else
    printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n");

  link->dev_node = &lp->node;
  SET_NETDEV_DEV(dev, &link->dev);

  i = register_netdev(dev);
  if (i != 0) {
    printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n");
    link->dev_node = NULL;
    goto failed;
  }

  strcpy(lp->node.dev_name, dev->name);

  printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port,"
	 " hw_addr %pM\n",
	 dev->name, dev->base_addr, dev->irq, if_names[dev->if_port],
	 dev->dev_addr);
  return 0;

failed:
	nmclan_release(link);
	return -ENODEV;
} /* nmclan_config */
コード例 #3
0
static int
xirc2ps_config(struct pcmcia_device * link)
{
    struct net_device *dev = link->priv;
    local_info_t *local = netdev_priv(dev);
    unsigned int ioaddr;
    int err;
    u8 *buf;
    size_t len;

    local->dingo_ccr = NULL;

    dev_dbg(&link->dev, "config\n");

    
    if (link->has_manf_id == 0) {
	pr_notice("manfid not found in CIS\n");
	goto failure;
    }

    switch (link->manf_id) {
      case MANFID_XIRCOM:
	local->manf_str = "Xircom";
	break;
      case MANFID_ACCTON:
	local->manf_str = "Accton";
	break;
      case MANFID_COMPAQ:
      case MANFID_COMPAQ2:
	local->manf_str = "Compaq";
	break;
      case MANFID_INTEL:
	local->manf_str = "Intel";
	break;
      case MANFID_TOSHIBA:
	local->manf_str = "Toshiba";
	break;
      default:
	pr_notice("Unknown Card Manufacturer ID: 0x%04x\n",
		  (unsigned)link->manf_id);
	goto failure;
    }
    dev_dbg(&link->dev, "found %s card\n", local->manf_str);

    if (!set_card_type(link)) {
	pr_notice("this card is not supported\n");
	goto failure;
    }

    
    err = pcmcia_get_mac_from_cis(link, dev);

    
    if (err) {
	    len = pcmcia_get_tuple(link, 0x89, &buf);
	    
	    if (buf && len == 8) {
		    if (*buf == CISTPL_FUNCE_LAN_NODE_ID) {
			    int i;
			    for (i = 2; i < 6; i++)
				    dev->dev_addr[i] = buf[i+2];
		    } else
			    err = -1;
	    }
	    kfree(buf);
    }

    if (err)
	err = pcmcia_loop_tuple(link, CISTPL_FUNCE, pcmcia_get_mac_ce, dev);

    if (err) {
	pr_notice("node-id not found in CIS\n");
	goto failure;
    }

    if (local->modem) {
	int pass;
	link->config_flags |= CONF_AUTO_SET_IO;

	if (local->dingo) {
	    if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL))
		    goto port_found;
	} else {
	    for (pass=0; pass < 2; pass++)
		    if (!pcmcia_loop_config(link, xirc2ps_config_check,
						    &pass))
			    goto port_found;
	}
	pr_notice("no ports available\n");
    } else {
	link->io_lines = 10;
	link->resource[0]->end = 16;
	link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
	for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
	    link->resource[0]->start = ioaddr;
	    if (!(err = pcmcia_request_io(link)))
		goto port_found;
	}
	link->resource[0]->start = 0; 
	if ((err = pcmcia_request_io(link)))
	    goto config_error;
    }
  port_found:
    if (err)
	 goto config_error;

    if ((err=pcmcia_request_irq(link, xirc2ps_interrupt)))
	goto config_error;

    link->config_flags |= CONF_ENABLE_IRQ;
    if (do_sound)
	    link->config_flags |= CONF_ENABLE_SPKR;

    if ((err = pcmcia_enable_device(link)))
	goto config_error;

    if (local->dingo) {
	/* Reset the modem's BAR to the correct value
	 * This is necessary because in the RequestConfiguration call,
	 * the base address of the ethernet port (BasePort1) is written
	 * to the BAR registers of the modem.
	 */
	err = pcmcia_write_config_byte(link, CISREG_IOBASE_0, (u8)
				link->resource[1]->start & 0xff);
	if (err)
	    goto config_error;

	err = pcmcia_write_config_byte(link, CISREG_IOBASE_1,
				(link->resource[1]->start >> 8) & 0xff);
	if (err)
	    goto config_error;

	link->resource[2]->flags = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM |
					WIN_ENABLE;
	link->resource[2]->start = link->resource[2]->end = 0;
	if ((err = pcmcia_request_window(link, link->resource[2], 0)))
	    goto config_error;

	local->dingo_ccr = ioremap(link->resource[2]->start, 0x1000) + 0x0800;
	if ((err = pcmcia_map_mem_page(link, link->resource[2], 0)))
	    goto config_error;

	writeb(0x47, local->dingo_ccr + CISREG_COR);
	ioaddr = link->resource[0]->start;
	writeb(ioaddr & 0xff	  , local->dingo_ccr + CISREG_IOBASE_0);
	writeb((ioaddr >> 8)&0xff , local->dingo_ccr + CISREG_IOBASE_1);

      #if 0
	{
	    u_char tmp;
	    pr_info("ECOR:");
	    for (i=0; i < 7; i++) {
		tmp = readb(local->dingo_ccr + i*2);
		pr_cont(" %02x", tmp);
	    }
	    pr_cont("\n");
	    pr_info("DCOR:");
	    for (i=0; i < 4; i++) {
		tmp = readb(local->dingo_ccr + 0x20 + i*2);
		pr_cont(" %02x", tmp);
	    }
	    pr_cont("\n");
	    pr_info("SCOR:");
	    for (i=0; i < 10; i++) {
		tmp = readb(local->dingo_ccr + 0x40 + i*2);
		pr_cont(" %02x", tmp);
	    }
	    pr_cont("\n");
	}
      #endif

	writeb(0x01, local->dingo_ccr + 0x20);
	writeb(0x0c, local->dingo_ccr + 0x22);
	writeb(0x00, local->dingo_ccr + 0x24);
	writeb(0x00, local->dingo_ccr + 0x26);
	writeb(0x00, local->dingo_ccr + 0x28);
    }
コード例 #4
0
static int nmclan_config(struct pcmcia_device *link)
{
  struct net_device *dev = link->priv;
  mace_private *lp = netdev_priv(dev);
  u8 *buf;
  size_t len;
  int i, ret;
  unsigned int ioaddr;

  dev_dbg(&link->dev, "nmclan_config\n");

  link->io_lines = 5;
  ret = pcmcia_request_io(link);
  if (ret)
	  goto failed;
  ret = pcmcia_request_exclusive_irq(link, mace_interrupt);
  if (ret)
	  goto failed;
  ret = pcmcia_enable_device(link);
  if (ret)
	  goto failed;

  dev->irq = link->irq;
  dev->base_addr = link->resource[0]->start;

  ioaddr = dev->base_addr;

  /* Read the ethernet address from the CIS. */
  len = pcmcia_get_tuple(link, 0x80, &buf);
  if (!buf || len < ETH_ALEN) {
	  kfree(buf);
	  goto failed;
  }
  memcpy(dev->dev_addr, buf, ETH_ALEN);
  kfree(buf);

  /* Verify configuration by reading the MACE ID. */
  {
    char sig[2];

    sig[0] = mace_read(lp, ioaddr, MACE_CHIPIDL);
    sig[1] = mace_read(lp, ioaddr, MACE_CHIPIDH);
    if ((sig[0] == 0x40) && ((sig[1] & 0x0F) == 0x09)) {
      dev_dbg(&link->dev, "nmclan_cs configured: mace id=%x %x\n",
	    sig[0], sig[1]);
    } else {
      pr_notice("mace id not found: %x %x should be 0x40 0x?9\n",
		sig[0], sig[1]);
      return -ENODEV;
    }
  }

  if(mace_init(lp, ioaddr, dev->dev_addr) == -1)
  	goto failed;

  /* The if_port symbol can be set when the module is loaded */
  if (if_port <= 2)
    dev->if_port = if_port;
  else
    pr_notice("invalid if_port requested\n");

  SET_NETDEV_DEV(dev, &link->dev);

  i = register_netdev(dev);
  if (i != 0) {
    pr_notice("register_netdev() failed\n");
    goto failed;
  }

  netdev_info(dev, "nmclan: port %#3lx, irq %d, %s port, hw_addr %pM\n",
	      dev->base_addr, dev->irq, if_names[dev->if_port], dev->dev_addr);
  return 0;

failed:
	nmclan_release(link);
	return -ENODEV;
} /* nmclan_config */
コード例 #5
0
static int
set_card_type(struct pcmcia_device *link)
{
    struct net_device *dev = link->priv;
    local_info_t *local = netdev_priv(dev);
    u8 *buf;
    unsigned int cisrev, mediaid, prodid;
    size_t len;

    len = pcmcia_get_tuple(link, CISTPL_MANFID, &buf);
    if (len < 5) {
	    dev_err(&link->dev, "invalid CIS -- sorry\n");
	    return 0;
    }

    cisrev = buf[2];
    mediaid = buf[3];
    prodid = buf[4];

    dev_dbg(&link->dev, "cisrev=%02x mediaid=%02x prodid=%02x\n",
	  cisrev, mediaid, prodid);

    local->mohawk = 0;
    local->dingo = 0;
    local->modem = 0;
    local->card_type = XIR_UNKNOWN;
    if (!(prodid & 0x40)) {
	pr_notice("Oops: Not a creditcard\n");
	return 0;
    }
    if (!(mediaid & 0x01)) {
	pr_notice("Not an Ethernet card\n");
	return 0;
    }
    if (mediaid & 0x10) {
	local->modem = 1;
	switch(prodid & 15) {
	  case 1: local->card_type = XIR_CEM   ; break;
	  case 2: local->card_type = XIR_CEM2  ; break;
	  case 3: local->card_type = XIR_CEM3  ; break;
	  case 4: local->card_type = XIR_CEM33 ; break;
	  case 5: local->card_type = XIR_CEM56M;
		  local->mohawk = 1;
		  break;
	  case 6:
	  case 7: 
		  local->card_type = XIR_CEM56 ;
		  local->mohawk = 1;
		  local->dingo = 1;
		  break;
	}
    } else {
	switch(prodid & 15) {
	  case 1: local->card_type = has_ce2_string(link)? XIR_CE2 : XIR_CE ;
		  break;
	  case 2: local->card_type = XIR_CE2; break;
	  case 3: local->card_type = XIR_CE3;
		  local->mohawk = 1;
		  break;
	}
    }
    if (local->card_type == XIR_CE || local->card_type == XIR_CEM) {
	pr_notice("Sorry, this is an old CE card\n");
	return 0;
    }
    if (local->card_type == XIR_UNKNOWN)
	pr_notice("unknown card (mediaid=%02x prodid=%02x)\n", mediaid, prodid);

    return 1;
}