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

📄 mpc85xx.c

📁 qnx powerpc MPC8245的 BSP源文件
💻 C
📖 第 1 页 / 共 3 页
字号:
	param.sched_priority = cfg->priority;	pthread_attr_setschedparam (&pattr, &param);	pthread_attr_setinheritsched (&pattr, PTHREAD_EXPLICIT_SCHED);	if ((ret = pthread_create (&ext->tid, &pattr,(void *) mpc_driver_thread, ext)) != EOK) {		errno = ret;		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "pthread_create at \"%s\":%d: %s\n",			__FILE__, __LINE__, strerror(errno));		goto error;	}	err++;	memset (&event, 0, sizeof(event));	SIGEV_PULSE_INIT (&event, ext->coid, cfg->priority, NIC_INTR_EVENT_TX, 0);	if ((ext->iid [0] = InterruptAttachEvent (cfg->irq [0], &event, _NTO_INTR_FLAGS_TRK_MSK)) < 0) {		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "InterruptAttachEvent at \"%s\":%d: %s\n",			__FILE__, __LINE__, strerror(errno));		goto error;	}	err++;	memset (&event, 0, sizeof(event));	SIGEV_PULSE_INIT (&event, ext->coid, cfg->priority, NIC_INTR_EVENT_RX, 0);	if ((ext->iid [1] = InterruptAttachEvent (cfg->irq [1], &event, _NTO_INTR_FLAGS_TRK_MSK)) < 0) {		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "InterruptAttachEvent at \"%s\":%d: %s\n",			__FILE__, __LINE__, strerror(errno));		goto error;	}	err++;	memset (&event, 0, sizeof(event));	SIGEV_PULSE_INIT (&event, ext->coid, cfg->priority, NIC_INTR_EVENT_ERR, 0);	if ((ext->iid [2] = InterruptAttachEvent (cfg->irq [2], &event, _NTO_INTR_FLAGS_TRK_MSK)) < 0) {		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "InterruptAttachEvent at \"%s\":%d: %s\n",			__FILE__, __LINE__, strerror(errno));		goto error;	}	return (EOK);error:	switch (err) {		case	6:			pthread_kill (ext->tid, SIGKILL);		case	5:			pthread_mutex_destroy (&ext->rx_free_pkt_q_mutex);		case	4:			pthread_mutex_destroy (&ext->tx_mutex);		case	3://			cache_fini (&ext->cachectl);		case	2:			ConnectDetach (ext->coid);		case	1:			ChannelDestroy (ext->chid);	}	return (errno);}/****************************************************************************//*                                                                          *//****************************************************************************/int		mpc_advertise (int reg_hdl, void *func_hdl){	npkt_t					*npkt;	net_iov_t				*iov;	mpc85xx_t    		    *ext = (mpc85xx_t *) func_hdl;	io_net_msg_dl_advert_t	*ap;	nic_config_t			*cfg = &ext->cfg;	_mutex_lock (&ext->rx_free_pkt_q_mutex);	if ((npkt = ext->rx_free_pkt_q)) {		ext->rx_free_pkt_q = npkt->next;		npkt->next = NULL;		ext->num_rx_free--;		_mutex_unlock (&ext->rx_free_pkt_q_mutex);	} else {		_mutex_unlock (&ext->rx_free_pkt_q_mutex);		if ((npkt = mpc_alloc_npkt(ext, MPC_MTU_SIZE, 1)) == NULL) {			return (0);		}	}	iov = TAILQ_FIRST(&npkt->buffers)->net_iov;	ap = iov->iov_base;	memset (ap, 0x00, sizeof *ap);	ap->type = _IO_NET_MSG_DL_ADVERT;	ap->iflags = (IFF_SIMPLEX | IFF_BROADCAST | IFF_RUNNING);	if (cfg->flags & NIC_FLAG_MULTICAST) {		ap->iflags |= IFF_MULTICAST;	} 	ap->mtu_min = 0;	ap->mtu_max = cfg->mtu;	ap->mtu_preferred = cfg->mtu;	strcpy (ap->up_type, "en");	itoa (cfg->lan, ap->up_type + 2, 10);	strcpy (ap->dl.sdl_data, ap->up_type);	ap->dl.sdl_len = sizeof(struct sockaddr_dl);	ap->dl.sdl_family = AF_LINK;	ap->dl.sdl_index  = cfg->lan;	ap->dl.sdl_type = IFT_ETHER;	ap->dl.sdl_nlen = strlen(ap->dl.sdl_data); /* not null terminated */	ap->dl.sdl_alen = 6;	memcpy (ap->dl.sdl_data + ap->dl.sdl_nlen, cfg->current_address, 6);	npkt->flags |= _NPKT_MSG;	npkt->iface = 0;	npkt->framelen = iov->iov_len = sizeof *ap;	npkt->tot_iov = 1;		if (ion_add_done (ext->reg_hdl, npkt, ext) == -1) {		mpc_receive_complete(npkt, ext, ext);		return (0);	}	if(ion_rx_packets (ext->reg_hdl, npkt, 0, 0, ext->cell, cfg->lan, 0) == 0) {		ion_tx_complete (ext->reg_hdl, npkt);	}	return (0);}/****************************************************************************//*                                                                          *//*  The Usual Multicast Setup                                               *//*                                                                          *//****************************************************************************/// CRC table (256 entries) generated by RFC3309unsigned crctab[] = {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,0x2d02ef8d,};// crc32core: returns RFC3309 CRC valueunsigned crc32core(unsigned char *buf, int len){    unsigned crc = 0xffffffff;    while(len--) {        crc = (crc>>8) ^ crctab[(crc ^ *buf)&0xff];        buf++;    }    return crc;}// reflect: bit-reverse value, swap 0 for n, 1 for n-1 and so onunsigned reflect(unsigned val, int nbits){    unsigned ret = 0;    int k;    for (k=1; k < (nbits+1); k++){        if (val & 1)            ret |= 1 << (nbits-k);        val >>= 1;    }    return ret;}// bump_macaddr: increment multicast address by onevoidbump_macaddr(uint8_t *mcaddr){    int i;    for (i = 5; i >= 0; i--) {        if (mcaddr[i] + 1 < 0x100) {            mcaddr[i]++;            while (i++ < 6)                mcaddr[i] = 0;            return;        }    }}void	setup_mcast_range (mpc85xx_t *ext, unsigned char *da, uint64_t len, int on){	unsigned 	crc;	unsigned 	lsb;	unsigned	bitIndex;	unsigned	regIndex;	uint32_t	*gaddr_reg = ext->reg + MPC_GADDR0;	while (len--) {		crc = crc32core(da, ETHER_ADDR_LEN);        lsb = reflect(crc, 8);    // reverse bottom 8 bits        bitIndex = lsb & 0x1f;    // least 5 bits for bit index        regIndex = lsb >> 5;      // most 3 bits for register index		if (ext->cfg.verbose) {			fprintf(stderr,"setup_mcast_range(): mac addr: %X %X %X %X %X %X\n",				da[0], da[1], da[2], da[3], da[4], da[5]);			fprintf(stderr,"setup_mcast_range(): crc:      %X\n",crc);			fprintf(stderr,"setup_mcast_range(): rev lsb:  %X\n",lsb);			fprintf(stderr,"setup_mcast_range(): regIndex: %d\n",regIndex);			fprintf(stderr,"setup_mcast_range(): bitIndex: %d\n",bitIndex);			fprintf(stderr,"setup_mcast_range(): on:       %d\n",on);		}        if (on) {  // set bit in indicated register			ext->gaddr[regIndex] |=  (0x80000000 >> bitIndex);        } else {   // drop bit in indicated register			ext->gaddr[regIndex] &= ~(0x80000000 >> bitIndex);        }		// if we are not in multicast promiscusous mode, write		// changed hash mask to TSEC.  When we come out of        // multicast promiscuous mode, our in-memory copy of		// the hash mask will be rewritten to TSEC by mcast_prom()        if (!ext->mcast_nprom) {            gaddr_reg[regIndex] = ext->gaddr[regIndex];        }		bump_macaddr(da);	}}void	mcast_prom (mpc85xx_t *ext, int enable){	int			 I;	uint32_t	*gaddr_reg = ext->reg + MPC_GADDR0;	if (enable) {		if (++ext->mcast_nprom != 1) {			return;  // stacked request - already done		}        // first enable request - enable all in TSEC        for(I=0; I<8; I++) {            gaddr_reg[I] = 0xffffffff;		}	} else {  // disable (previous) request        if (ext->mcast_nprom <= 0) {			return;  // no underflow allowed during regression testing        }        // decrement positive valued counter		if (--ext->mcast_nprom) {			return;  // still outstanding stacked enable all requests		}		// coming out of multicast promiscuous mode - refresh TSEC             for(I=0; I<8; I++) {            gaddr_reg[I] = ext->gaddr[I];		}	}}#define CONVERT_MAC_ADDR_2_VAL(x)  \(x[5] + (x[4]<<8) + (x[3]<<16) + (x[2]<<24) + \(((unsigned long long)(x[1]))<<32) + (((unsigned long long)x[0])<<40) )int		do_multicast (mpc85xx_t *ext, struct _io_net_msg_mcast *mcast){	unsigned long long		start_val;	unsigned long long   	end_val;	unsigned long long   	range_length;	unsigned char   		start[ETHER_ADDR_LEN];	unsigned char   		end[ETHER_ADDR_LEN];	if (ext->cfg.verbose) {		nic_slogf (_SLOGC_NETWORK, _SLOG_INFO, 		"multicast msg %p - type %x - flags %x", mcast, mcast->type, mcast->flags);	}	if (mcast->type == _IO_NET_REMOVE_MCAST) {		if ((mcast->flags & _IO_NET_MCAST_ALL) == 0) {			memcpy (start, LLADDR(&mcast->mc_min.addr_dl), ETHER_ADDR_LEN);			memcpy (end,   LLADDR(&mcast->mc_max.addr_dl), ETHER_ADDR_LEN);            start_val = CONVERT_MAC_ADDR_2_VAL(start);            end_val   = CONVERT_MAC_ADDR_2_VAL(end);            if (start_val > end_val) {				if (ext->cfg.verbose) {				    nic_slogf(_SLOGC_NETWORK, _SLOG_ERROR,			        "devn-mpc85xx: _IO_NET_REMOVE_MCAST: start_val > end_val",			        mcast->type);				}                return EINVAL;            }            range_length = end_val - start_val + 1;            if (range_length > 256) {				mcast_prom(ext, 0);  // was never added to filter			} else {				setup_mcast_range (ext, start, range_length, 0);			}        } else {			mcast_prom(ext, 0);  // remove all multicast		}	} else if (mcast->type ==  _IO_NET_JOIN_MCAST) {		if ((mcast->flags & _IO_NET_MCAST_ALL) == 0) {			if (nic_ether_mcast_valid(mcast) == -1) {				return EINVAL;			}			memcpy (start, LLADDR(&mcast->mc_min.addr_dl), ETHER_ADDR_LEN);			memcpy (end,   LLADDR(&mcast->mc_max.addr_dl), ETHER_ADDR_LEN);            start_val = CONVERT_MAC_ADDR_2_VAL(start);            end_val   = CONVERT_MAC_ADDR_2_VAL(end);            if (start_val > end_val) {				if (ext->cfg.verbose) {				    nic_slogf(_SLOGC_NETWORK, _SLOG_ERROR,			        "devn-mpc85xx: _IO_NET_JOIN_MCAST: start_val > end_val",			        mcast->type);				}                return EINVAL;            }            range_length = end_val - start_val + 1;            if (range_length > 256) {				mcast_prom(ext, 1);  // dont add to filter			} else {				setup_mcast_range(ext, start, range_length, 1);			}		} else {			mcast_prom(ext, 1);  // join all multicast		}	} else {		if (ext->cfg.verbose) {		    nic_slogf(_SLOGC_NETWORK, _SLOG_ERROR,		        "devn-mpc85xx: message 0x%x not supported",		        mcast->type);		}		return EINVAL; 	}	return (EOK);}

⌨️ 快捷键说明

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