⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xirc2ps_cs.c

📁 h内核
💻 C
📖 第 1 页 / 共 4 页
字号:
    unsigned d;    PutByte(XIRCREG2_GPR2, 4|0); /* drive MDCK low */    udelay(1);    d = GetByte(XIRCREG2_GPR2); /* read MDIO */    PutByte(XIRCREG2_GPR2, 4|1); /* drive MDCK high again */    udelay(1);    return d & 0x20; /* read MDIO */}static voidmii_wbits(kio_addr_t ioaddr, unsigned data, int len){    unsigned m = 1 << (len-1);    for (; m; m >>= 1)	mii_putbit(ioaddr, data & m);}static unsignedmii_rd(kio_addr_t ioaddr,	u_char phyaddr, u_char phyreg){    int i;    unsigned data=0, m;    SelectPage(2);    for (i=0; i < 32; i++)		/* 32 bit preamble */	mii_putbit(ioaddr, 1);    mii_wbits(ioaddr, 0x06, 4); 	/* Start and opcode for read */    mii_wbits(ioaddr, phyaddr, 5);	/* PHY address to be accessed */    mii_wbits(ioaddr, phyreg, 5);	/* PHY register to read */    mii_idle(ioaddr);			/* turn around */    mii_getbit(ioaddr);    for (m = 1<<15; m; m >>= 1)	if (mii_getbit(ioaddr))	    data |= m;    mii_idle(ioaddr);    return data;}static voidmii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg, unsigned data, int len){    int i;    SelectPage(2);    for (i=0; i < 32; i++)		/* 32 bit preamble */	mii_putbit(ioaddr, 1);    mii_wbits(ioaddr, 0x05, 4); 	/* Start and opcode for write */    mii_wbits(ioaddr, phyaddr, 5);	/* PHY address to be accessed */    mii_wbits(ioaddr, phyreg, 5);	/* PHY Register to write */    mii_putbit(ioaddr, 1);		/* turn around */    mii_putbit(ioaddr, 0);    mii_wbits(ioaddr, data, len);	/* And write the data */    mii_idle(ioaddr);}/*============= Main bulk of functions	=========================*//**************** * xirc2ps_attach() creates an "instance" of the driver, allocating * local data structures for one device.  The device is registered * with Card Services. * * The dev_link structure is initialized, but we don't actually * configure the card at this point -- we wait until we receive a * card insertion event. */static dev_link_t *xirc2ps_attach(void){    client_reg_t client_reg;    dev_link_t *link;    struct net_device *dev;    local_info_t *local;    int err;    DEBUG(0, "attach()\n");    /* Allocate the device structure */    dev = alloc_etherdev(sizeof(local_info_t));    if (!dev)	    return NULL;    local = netdev_priv(dev);    link = &local->link;    link->priv = dev;    /* General socket configuration */    link->conf.Attributes = CONF_ENABLE_IRQ;    link->conf.Vcc = 50;    link->conf.IntType = INT_MEMORY_AND_IO;    link->conf.ConfigIndex = 1;    link->conf.Present = PRESENT_OPTION;    link->irq.Handler = xirc2ps_interrupt;    link->irq.Instance = dev;    /* Fill in card specific entries */    SET_MODULE_OWNER(dev);    dev->hard_start_xmit = &do_start_xmit;    dev->set_config = &do_config;    dev->get_stats = &do_get_stats;    dev->do_ioctl = &do_ioctl;    SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);    dev->set_multicast_list = &set_multicast_list;    dev->open = &do_open;    dev->stop = &do_stop;#ifdef HAVE_TX_TIMEOUT    dev->tx_timeout = do_tx_timeout;    dev->watchdog_timeo = TX_TIMEOUT;#endif    /* Register with Card Services */    link->next = dev_list;    dev_list = link;    client_reg.dev_info = &dev_info;    client_reg.EventMask =	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |	CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;    client_reg.event_handler = &xirc2ps_event;    client_reg.Version = 0x0210;    client_reg.event_callback_args.client_data = link;    if ((err = pcmcia_register_client(&link->handle, &client_reg))) {	cs_error(link->handle, RegisterClient, err);	xirc2ps_detach(link);	return NULL;    }    return link;} /* xirc2ps_attach *//**************** *  This deletes a driver "instance".  The device is de-registered *  with Card Services.  If it has been released, all local data *  structures are freed.  Otherwise, the structures will be freed *  when the device is released. */static voidxirc2ps_detach(dev_link_t * link){    struct net_device *dev = link->priv;    dev_link_t **linkp;    DEBUG(0, "detach(0x%p)\n", link);    /* Locate device structure */    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)	if (*linkp == link)	    break;    if (!*linkp) {	DEBUG(0, "detach(0x%p): dev_link lost\n", link);	return;    }    if (link->dev)	unregister_netdev(dev);    /*     * If the device is currently configured and active, we won't     * actually delete it yet.	Instead, it is marked so that when     * the release() function is called, that will trigger a proper     * detach().     */    if (link->state & DEV_CONFIG)	xirc2ps_release(link);    /* Break the link with Card Services */    if (link->handle)	pcmcia_deregister_client(link->handle);    /* Unlink device structure, free it */    *linkp = link->next;    free_netdev(dev);} /* xirc2ps_detach *//**************** * Detect the type of the card. s is the buffer with the data of tuple 0x20 * Returns: 0 := not supported *		       mediaid=11 and prodid=47 * Media-Id bits: *  Ethernet	    0x01 *  Tokenring	    0x02 *  Arcnet	    0x04 *  Wireless	    0x08 *  Modem	    0x10 *  GSM only	    0x20 * Prod-Id bits: *  Pocket	    0x10 *  External	    0x20 *  Creditcard	    0x40 *  Cardbus	    0x80 * */static intset_card_type(dev_link_t *link, const void *s){    struct net_device *dev = link->priv;    local_info_t *local = netdev_priv(dev);  #ifdef PCMCIA_DEBUG    unsigned cisrev = ((const unsigned char *)s)[2];  #endif    unsigned mediaid= ((const unsigned char *)s)[3];    unsigned prodid = ((const unsigned char *)s)[4];    DEBUG(0, "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)) {	printk(KNOT_XIRC "Ooops: Not a creditcard\n");	return 0;    }    if (!(mediaid & 0x01)) {	printk(KNOT_XIRC "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: /* 7 is the RealPort 10/56 */		  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) {	printk(KNOT_XIRC "Sorry, this is an old CE card\n");	return 0;    }    if (local->card_type == XIR_UNKNOWN)	printk(KNOT_XIRC "unknown card (mediaid=%02x prodid=%02x)\n",	       mediaid, prodid);    return 1;}/**************** * There are some CE2 cards out which claim to be a CE card. * This function looks for a "CE2" in the 3rd version field. * Returns: true if this is a CE2 */static inthas_ce2_string(dev_link_t * link){    client_handle_t handle = link->handle;    tuple_t tuple;    cisparse_t parse;    u_char buf[256];    tuple.Attributes = 0;    tuple.TupleData = buf;    tuple.TupleDataMax = 254;    tuple.TupleOffset = 0;    tuple.DesiredTuple = CISTPL_VERS_1;    if (!first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 2) {	if (strstr(parse.version_1.str + parse.version_1.ofs[2], "CE2"))	    return 1;    }    return 0;}/**************** * xirc2ps_config() is scheduled to run after a CARD_INSERTION event * is received, to configure the PCMCIA socket, and to make the * ethernet device available to the system. */static voidxirc2ps_config(dev_link_t * link){    client_handle_t handle = link->handle;    struct net_device *dev = link->priv;    local_info_t *local = netdev_priv(dev);    tuple_t tuple;    cisparse_t parse;    kio_addr_t ioaddr;    int err, i;    u_char buf[64];    cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;    cistpl_cftable_entry_t *cf = &parse.cftable_entry;    local->dingo_ccr = NULL;    DEBUG(0, "config(0x%p)\n", link);    /*     * This reads the card's CONFIG tuple to find its configuration     * registers.     */    tuple.Attributes = 0;    tuple.TupleData = buf;    tuple.TupleDataMax = 64;    tuple.TupleOffset = 0;    /* Is this a valid	card */    tuple.DesiredTuple = CISTPL_MANFID;    if ((err=first_tuple(handle, &tuple, &parse))) {	printk(KNOT_XIRC "manfid not found in CIS\n");	goto failure;    }    switch(parse.manfid.manf) {      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:	printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n",	       (unsigned)parse.manfid.manf);	goto failure;    }    DEBUG(0, "found %s card\n", local->manf_str);    if (!set_card_type(link, buf)) {	printk(KNOT_XIRC "this card is not supported\n");	goto failure;    }    /* get configuration stuff */    tuple.DesiredTuple = CISTPL_CONFIG;    if ((err=first_tuple(handle, &tuple, &parse)))	goto cis_error;    link->conf.ConfigBase = parse.config.base;    link->conf.Present =    parse.config.rmask[0];    /* get the ethernet address from the CIS */    tuple.DesiredTuple = CISTPL_FUNCE;    for (err = first_tuple(handle, &tuple, &parse); !err;			     err = next_tuple(handle, &tuple, &parse)) {	/* Once I saw two CISTPL_FUNCE_LAN_NODE_ID entries:	 * the first one with a length of zero the second correct -	 * so I skip all entries with length 0 */	if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID	    && ((cistpl_lan_node_id_t *)parse.funce.data)->nb)	    break;    }    if (err) { /* not found: try to get the node-id from tuple 0x89 */	tuple.DesiredTuple = 0x89;  /* data layout looks like tuple 0x22 */	if ((err = pcmcia_get_first_tuple(handle, &tuple)) == 0 &&		(err = pcmcia_get_tuple_data(handle, &tuple)) == 0) {	    if (tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID)		memcpy(&parse, buf, 8);	    else		err = -1;	}    }    if (err) { /* another try	(James Lehmer's CE2 version 4.1)*/	tuple.DesiredTuple = CISTPL_FUNCE;	for (err = first_tuple(handle, &tuple, &parse); !err;				 err = next_tuple(handle, &tuple, &parse)) {	    if (parse.funce.type == 0x02 && parse.funce.data[0] == 1		&& parse.funce.data[1] == 6 && tuple.TupleDataLen == 13) {		buf[1] = 4;		memcpy(&parse, buf+1, 8);		break;	    }	}    }    if (err) {	printk(KNOT_XIRC "node-id not found in CIS\n");	goto failure;    }    node_id = (cistpl_lan_node_id_t *)parse.funce.data;    if (node_id->nb != 6) {	printk(KNOT_XIRC "malformed node-id in CIS\n");	goto failure;    }    for (i=0; i < 6; i++)	dev->dev_addr[i] = node_id->id[i];    /* Configure card */    link->state |= DEV_CONFIG;    link->io.IOAddrLines =10;    link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;    link->irq.Attributes = IRQ_HANDLE_PRESENT;    link->irq.IRQInfo1 = IRQ_LEVEL_ID;    if (local->modem) {	int pass;	if (do_sound) {	    link->conf.Attributes |= CONF_ENABLE_SPKR;	    link->conf.Status |= CCSR_AUDIO_ENA;	}	link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED ;	link->io.NumPorts2 = 8;	link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;	if (local->dingo) {	    /* Take the Modem IO port from the CIS and scan for a free	     * Ethernet port */	    link->io.NumPorts1 = 16; /* no Mako stuff anymore */	    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;	    for (err = first_tuple(handle, &tuple, &parse); !err;				 err = next_tuple(handle, &tuple, &parse)) {		if (cf->io.nwin > 0  &&  (cf->io.win[0].base & 0xf) == 8) {		    for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {			link->conf.ConfigIndex = cf->index ;			link->io.BasePort2 = cf->io.win[0].base;			link->io.BasePort1 = ioaddr;			if (!(err=pcmcia_request_io(link->handle, &link->io)))			    goto port_found;		    }		}	    }	} else {	    link->io.NumPorts1 = 18;	    /* We do 2 passes here: The first one uses the regular mapping and	     * the second tries again, thereby considering that the 32 ports are	     * mirrored every 32 bytes. Actually we use a mirrored port for	     * the Mako if (on the first pass) the COR bit 5 is set.	     */	    for (pass=0; pass < 2; pass++) {		tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;		for (err = first_tuple(handle, &tuple, &parse); !err;				     err = next_tuple(handle, &tuple, &parse)){		    if (cf->io.nwin > 0  &&  (cf->io.win[0].base & 0xf) == 8){			link->conf.ConfigIndex = cf->index ;			link->io.BasePort2 = cf->io.win[0].base;			link->io.BasePort1 = link->io.BasePort2				    + (pass ? (cf->index & 0x20 ? -24:8)					    : (cf->index & 0x20 ?   8:-24));			if (!(err=pcmcia_request_io(link->handle, &link->io)))			    goto port_found;		    }		}	    }	    /* if special option:	     * try to configure as Ethernet only.	     * .... */	}	printk(KNOT_XIRC "no ports available\n");    } else {	link->irq.Attributes |= IRQ_TYPE_EXCLUSIVE;	link->io.NumPorts1 = 16;	for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {	    link->io.BasePort1 = ioaddr;	    if (!(err=pcmcia_request_io(link->handle, &link->io)))		goto port_found;	}	link->io.BasePort1 = 0; /* let CS decide */	if ((err=pcmcia_request_io(link->handle, &link->io))) {	    cs_error(link->handle, RequestIO, err);	    goto config_error;	}    }  port_found:    if (err)	 goto config_error;    /****************     * Now allocate an interrupt line.	Note that this does not     * actually assign a handler to the interrupt.     */    if ((err=pcmcia_request_irq(link->handle, &link->irq))) {	cs_error(link->handle, RequestIRQ, err);	goto config_error;    }    /****************     * This actually configures the PCMCIA socket -- setting up     * the I/O windows and the interrupt mapping.     */    if ((err=pcmcia_request_configuration(link->handle, &link->conf))) {	cs_error(link->handle, RequestConfiguration, err);	goto config_error;    }    if (local->dingo) {	conf_reg_t reg;	win_req_t req;	memreq_t mem;	/* 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.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -