示例#1
0
/* Create and initialize a NAT entry. */
static __EASY_NAT_ENTRY* CreateNatEntry(__NAT_MANAGER* pMgr)
{
	__EASY_NAT_ENTRY* pEntry = NULL;

	BUG_ON(NULL == pMgr);

	/* 
	 * If too many NAT entries exist. Should in critical section,but
	 * now it's OK,since the routine will be called by tcp_ip thread only.
	 */
	if (MAX_NAT_ENTRY_NUM < pMgr->stat.entry_num)
	{
		_hx_printf("[NAT]: too many NAT entries.\r\n");
		goto __TERMINAL;
	}
	pMgr->stat.entry_num++;

	/* Create and initialize it. */
	pEntry = (__EASY_NAT_ENTRY*)_hx_malloc(sizeof(__EASY_NAT_ENTRY));
	if (NULL == pEntry)
	{
		goto __TERMINAL;
	}
	memset(pEntry, 0, sizeof(__EASY_NAT_ENTRY));

__TERMINAL:
	return pEntry;
}
示例#2
0
/* Set a network timer object. */
void _hx_sys_timeout(HANDLE hTarget, unsigned long msecs, sys_timeout_handler handler, void* arg)
{
	HANDLE hTimer = NULL;
	__network_timer_object* pTimerObject = NULL;

	pTimerObject = (__network_timer_object*)_hx_malloc(sizeof(__network_timer_object));
	if (NULL == pTimerObject)
	{
		goto __TERMINAL;
	}

	/* 
	 * Initialize the network timer object and 
	 * insert it into global list.
	 */
	pTimerObject->dwObjectSignature = KERNEL_OBJECT_SIGNATURE;
	pTimerObject->handler = handler;
	pTimerObject->handler_param = arg;
	pTimerObject->msecs = msecs;

	pTimerObject->pNext = timer_list.pNext;
	pTimerObject->pPrev = &timer_list;
	timer_list.pNext->pPrev = pTimerObject;
	timer_list.pNext = pTimerObject;

	/* Set a HelloX timer object. */
	//hTimer = SetTimer((DWORD)pTimerObject, msecs, NULL, NULL,
	//	TIMER_FLAGS_ONCE);
	hTimer = System.SetTimer(
		(__COMMON_OBJECT*)&System,
		(__KERNEL_THREAD_OBJECT*)hTarget,
		(DWORD)pTimerObject, msecs, NULL, NULL,
		TIMER_FLAGS_ONCE);
	if (NULL == hTimer)
	{
		_hx_printf("%s:failed to set timer.\r\n", __func__);
		goto __TERMINAL;
	}
	pTimerObject->hTimer = hTimer;

__TERMINAL:
	if (NULL == hTimer) /* Failed to set timer. */
	{
		_hx_release_network_tmo(pTimerObject);
	}
	return;
}
示例#3
0
char* itoa(int value, char* string, int radix)
{
	char tmp[33];
	char* tp = tmp;
	int i;
	unsigned v;
	int sign;
	char* sp;

	if (radix > 36 || radix <= 1)
	{
		//__set_errno(EDOM);
		return 0;
	}
	sign = (radix == 10 && value < 0);
	if (sign)
		v = -value;
	else
		v = (unsigned)value;
	while (v || tp == tmp)
	{
		i = v % radix;
		v = v / radix;
		if (i < 10)
			*tp++ = i+'0';
		else
			*tp++ = i + 'a' - 10;
	}

	if (string == 0)
		string = (char*)_hx_malloc((tp-tmp)+sign+1);
	sp = string;

	if (sign)
		*sp++ = '-';
	while (tp > tmp)
		*sp++ = *--tp;
	*sp = 0;
	return string;
}
示例#4
0
//Create a USB isochronous transfer descriptor and install it into system.
__USB_ISO_DESCRIPTOR* usbCreateISODescriptor(__PHYSICAL_DEVICE* pPhyDev, int direction, int bandwidth,
	char* buffer, int bufflength, __U8 endpoint,__U16 maxPacketSize,__U8 multi)
{
	__USB_ISO_DESCRIPTOR* pIsoDesc = NULL;
	BOOL bResult = FALSE;
	struct usb_device* pUsbDev = NULL;
	struct iTD* pitd = NULL;
	__COMMON_USB_CONTROLLER* pCtrl = NULL;
	struct ehci_ctrl* pEhciCtrl = NULL;
	int maxXferSize = 0, transact_leng = 0;
	int slot_num = 0;     //How many slot the iTD should link to.
	int slot_space = 0;   //The slot number between 2 iTDs in periodic list.
	int i = 0;
	char* buff_ptr = buffer;
	DWORD dwFlags;

	//Parameters check.
	if ((NULL == pPhyDev) || (NULL == buffer) || (0 == bufflength) || (0 == endpoint))
	{
		goto __TERMINAL;
	}
	if ((bandwidth > EHCI_ISO_MAX_BANDWIDTH) || (0 == multi))
	{
		goto __TERMINAL;
	}
	if (maxPacketSize > 1024)  //EHCI spec.
	{
		goto __TERMINAL;
	}
	if ((direction != USB_TRANSFER_DIR_IN) && (direction != USB_TRANSFER_DIR_OUT))
	{
		goto __TERMINAL;
	}
	pUsbDev = (struct usb_device*)pPhyDev->lpPrivateInfo;
	if (NULL == pUsbDev)
	{
		BUG();
	}
	pCtrl = (__COMMON_USB_CONTROLLER*)pUsbDev->controller;
	pEhciCtrl = (struct ehci_ctrl*)pCtrl->pUsbCtrl;

	//8 transactions in one iTD descriptor.
	maxXferSize = maxPacketSize * multi * 8;
	if (bufflength > (int)maxXferSize)
	{
		goto __TERMINAL;
	}

	//Allocate a ISOxfer descriptor and initialize it accordingly.
	pIsoDesc = _hx_malloc(sizeof(__USB_ISO_DESCRIPTOR));
	if (NULL == pIsoDesc)
	{
		goto __TERMINAL;
	}
	memset(pIsoDesc, 0, sizeof(__USB_ISO_DESCRIPTOR));
	pIsoDesc->bandwidth = bandwidth;
	pIsoDesc->buffer = buffer;
	pIsoDesc->bufflength = bufflength;
	pIsoDesc->direction = direction;
	pIsoDesc->ISOXferIntHandler = ISOXferIntHandler;
	pIsoDesc->itdArray = NULL; //Will be initialized later.
	pIsoDesc->itdnumber = 0;   //Will be initialized later.
	pIsoDesc->pCtrl = (__COMMON_USB_CONTROLLER*)pUsbDev->controller;
	pIsoDesc->hEvent = NULL;
	pIsoDesc->endpoint = endpoint;
	pIsoDesc->maxPacketSize = maxPacketSize;
	pIsoDesc->multi = multi;
	pIsoDesc->pNext = NULL;
	pIsoDesc->pPhyDev = pPhyDev;
	pIsoDesc->status = USB_ISODESC_STATUS_INITIALIZED;

	pIsoDesc->hEvent = CreateEvent(FALSE);
	if (NULL == pIsoDesc)
	{
		goto __TERMINAL;
	}

	//Create iTD and initialize it.
	pitd = (struct iTD*)_hx_aligned_malloc(sizeof(struct iTD), 32);
	if (NULL == pitd)
	{
		goto __TERMINAL;
	}
	memset(pitd, 0, sizeof(struct iTD));
	pitd->lp_next |= ITD_NEXT_TERMINATE;  //Terminate bit.
	pitd->lp_next |= ITD_NEXT_TYPE_SET(ITD_NEXT_TYPE_ITD);  //Type as iTD.

	//pitd->transaction[0] |= ITD_TRANS_XLEN_SET(bufflength); //xlength.
	//pitd->transaction[0] |= ITD_TRANS_IOC_SET(1);           //Set IOC bit.
	//pitd->transaction[0] |= ITD_TRANS_PG_SET(0);            //Page 0.
	//pitd->transaction[0] |= ITD_TRANS_XOFFSET_SET(buffer);  //Buffer offset.
	//pitd->pg_pointer[0] |= ITD_PGPTR_SET(buffer);           //Buffer page pointer.

	pitd->pg_pointer[0] |= ITD_ENDPOINT_SET(endpoint);      //Endpoint.
	pitd->pg_pointer[0] |= pUsbDev->devnum;                 //Device address.
	//Set transfer direction.
	if (USB_TRANSFER_DIR_IN == direction)
	{
		pitd->pg_pointer[1] |= ITD_XFERDIR_SET(1);
	}
	else
	{
		pitd->pg_pointer[1] |= ITD_XFERDIR_SET(0);
	}
	pitd->pg_pointer[1] |= ITD_MAX_PKTSZ_SET(maxPacketSize);  //Max packet size.
	pitd->pg_pointer[2] |= ITD_MULTI_SET(multi);              //multiple per (micro)frame.

	//Fill iTD's transaction(s) accordingly.
	__Fill_iTD(pIsoDesc,pitd,direction,buffer,bufflength,endpoint,maxPacketSize,multi);

#if 0
	//Initializes data buffer offset and pointer one by one.
	i = 0;
	buff_ptr = buffer;
	maxXferSize = bufflength;
	transact_leng = (maxPacketSize * multi > maxXferSize) ?
	maxXferSize : (maxPacketSize * multi);
	while (maxXferSize)
	{
		pitd->transaction[i] |= ITD_TRANS_XLEN_SET(bufflength); //xlength.
		pitd->transaction[i] |= ITD_TRANS_PG_SET(i);            //Page 0.
		pitd->transaction[i] |= ITD_TRANS_XOFFSET_SET(buffer);  //Buffer offset.
		pitd->pg_pointer[i] |= ITD_PGPTR_SET(buffer);           //Buffer page pointer.
	}
#endif

#ifdef __DEBUG_USB_ISO
	_hx_printf("iso_iTD:lp_next = 0x%X,trans[0] = 0x%X,pg_ptr[0] = 0x%X,pg_ptr[1] = 0x%X,pg_ptr[2] = 0x%X.\r\n",
		pitd->lp_next, pitd->transaction[0], pitd->pg_pointer[0], pitd->pg_pointer[1],pitd->pg_pointer[2]);
#endif

	flush_dcache_range((unsigned long)pitd, ALIGN_END_ADDR(struct iTD, pitd, 1));

	//Link the iTD to isochronous transfer descriptor.
	pIsoDesc->itdArray = pitd;
	pIsoDesc->itdnumber = 1;

	//Calculate how many periodic list slot shall we use.
	slot_num = bandwidth / 8;
	if (slot_num < bufflength)
	{
		slot_num = 1;
	}
	else
	{
		slot_num = (0 == slot_num % bufflength) ? (slot_num / bufflength) :
			(slot_num / bufflength + 1);
	}
	if (slot_num > USB_PERIODIC_LIST_LENGTH) //Paameter checking makes sure this can not happen.
	{
		_hx_printf("%s:too many slot number[bw = %d,buff_len = %d,slot_num = %d.\r\n",
			__func__,
			bandwidth,
			bufflength,
			slot_num);
		goto __TERMINAL;
	}
	//Save the slot_num to descriptor,since it will be used in usbDestroyISODescriptor routine.
	pIsoDesc->slot_num = slot_num;
	slot_space = USB_PERIODIC_LIST_LENGTH / slot_num;
	if (0 == slot_space)
	{
		slot_space = 1;
	}
#ifdef __DEBUG_USB_ISO
	_hx_printf("slot_num:%d,slot_space:%d.\r\n", slot_num, slot_space);
#endif

	//Stop periodic schedule if enabled already.
	WaitForThisObject(pEhciCtrl->hMutex);
	if (pEhciCtrl->periodic_schedules > 0)
	{
		if (ehci_disable_periodic(pEhciCtrl) < 0) {
			ReleaseMutex(pEhciCtrl->hMutex);
			_hx_printf("FATAL %s: periodic should never fail, but did.\r\n", __func__);
			goto __TERMINAL;
		}
	}

	//Insert the iTD to periodic list,and insert the ISOXfer descriptor into EHCI controller's
	//list.
	i = 0;
	__ENTER_CRITICAL_SECTION(NULL, dwFlags);
	while (slot_num)
	{
		pitd->lp_next = pEhciCtrl->periodic_list[i];
		pEhciCtrl->periodic_list[i] = ((__U32)pitd | QH_LINK_TYPE_ITD);
		flush_dcache_range((unsigned long)&pEhciCtrl->periodic_list[i],
			ALIGN_END_ADDR(uint32_t, &pEhciCtrl->periodic_list[i], 1));
		i += slot_space;
		//Re-calculate the space between slot to make sure the iTD can be linked into
		//periodic list as scatterly as possible.
		slot_space = (USB_PERIODIC_LIST_LENGTH - i) / slot_num;
		if (0 == slot_space)
		{
			slot_space = 1;
		}
		slot_num--;
	}

	//Insert it into global list.
	if (NULL == pEhciCtrl->pIsoDescFirst)  //First element.
	{
		pEhciCtrl->pIsoDescFirst = pIsoDesc;
		pEhciCtrl->pIsoDescLast = pIsoDesc;
	}
	else  //Put it at last.
	{
		//We only support one isochronous xfer at the sametime for simpicity.
		BUG();
		if (NULL == pEhciCtrl->pIsoDescLast)
		{
			BUG();
		}
		pEhciCtrl->pIsoDescLast->pNext = pIsoDesc;
		pEhciCtrl->pIsoDescLast = pIsoDesc;
	}
	__LEAVE_CRITICAL_SECTION(NULL, dwFlags);

	//Restart the periodic schedule if already enabled.
	if (pEhciCtrl->periodic_schedules > 0)
	{
		ehci_enable_periodic(pEhciCtrl);
	}
	ReleaseMutex(pEhciCtrl->hMutex);
	
	bResult = TRUE;

__TERMINAL:
	if (!bResult)
	{
		if (pIsoDesc)  //Should release it.
		{
			if (pIsoDesc->hEvent)
			{
				DestroyEvent(pIsoDesc->hEvent);
			}
			_hx_free(pIsoDesc);
		}
		if (pitd)
		{
			_hx_free(pitd);
		}
		pIsoDesc = NULL;  //Mark as failed.
	}
	return pIsoDesc;
}
示例#5
0
static DWORD copy(__CMD_PARA_OBJ* pCmdObj)
{
#ifdef __CFG_SYS_DDF
	HANDLE   hSourceFile = NULL;
	HANDLE   hDestinationFile = NULL;
	char*    pBuffer = NULL;
	DWORD    dwReadSize = 0;
	DWORD    dwWriteSize = 0;
	DWORD    dwTotalRead = 0;
	char     srcFullName[MAX_FILE_NAME_LEN];
	char     dstFullName[MAX_FILE_NAME_LEN];
	DWORD    dwFileSize = 0;
	DWORD    dwBatSize = 0;

	if (pCmdObj->byParameterNum < 3)
	{
		_hx_printf("Please specify the source and destination file name.\r\n");
		goto __TERMINAL;
	}
	/* Construct source file's full name. */
	if (IsRelative(pCmdObj->Parameter[1]))
	{
		/* Append current directory into the relative file name. */
		strcpy(srcFullName, FsGlobalData.CurrentDir);
		strcat(srcFullName, pCmdObj->Parameter[1]);
	}
	else
	{
		strcpy(srcFullName, pCmdObj->Parameter[1]);
	}
	ToCapital(srcFullName);

	/* Construct destination file's full name. */
	if (IsRelative(pCmdObj->Parameter[2]))
	{
		/* Append current directory into the relative file name. */
		strcpy(dstFullName, FsGlobalData.CurrentDir);
		strcat(dstFullName, pCmdObj->Parameter[2]);
	}
	else
	{
		strcpy(dstFullName, pCmdObj->Parameter[2]);
	}
	ToCapital(dstFullName);

	/* Can not copy one file to itself. */
	if (0 == strcmp(srcFullName, dstFullName))
	{
		_hx_printf("Can not copy a file to it's self.\r\n");
		goto __TERMINAL;
	}

	/* Try to open the source file. */
	hSourceFile = IOManager.CreateFile((__COMMON_OBJECT*)&IOManager,
		srcFullName,
		FILE_ACCESS_READ,
		0,
		NULL);
	if (NULL == hSourceFile)
	{
		_hx_printf("Can not open the source file[%s].\r\n",
			srcFullName);
		goto __TERMINAL;
	}

	/* Try to open or create the destination file name. */
	hDestinationFile = IOManager.CreateFile((__COMMON_OBJECT*)&IOManager,
		dstFullName,
		FILE_OPEN_ALWAYS,
		0,
		NULL);
	if (NULL == hDestinationFile)
	{
		_hx_printf("Can not open the target file[%s].\r\n",
			dstFullName);
		goto __TERMINAL;
	}

	/* Get the source file's size. */
	dwFileSize = GetFileSize(hSourceFile, NULL);
	dwBatSize = dwFileSize / 20;

	/* Allocate a buffer to hold the file's data. */
#define __TMP_FILE_BUFFSZ (64 * 1024)
	pBuffer = (char*)_hx_malloc(__TMP_FILE_BUFFSZ);
	if (NULL == pBuffer)
	{
		_hx_printf("Failed to allocate data buffer.\r\n");
		goto __TERMINAL;
	}

	/* Copy data now. */
	do {
		/* Read the source file. */
		if (!IOManager.ReadFile((__COMMON_OBJECT*)&IOManager,
			hSourceFile,
			__TMP_FILE_BUFFSZ,
			pBuffer,
			&dwReadSize))
		{
			_hx_printf("Can not read the source file.\r\n");
			goto __TERMINAL;
		}

		/* Write the data block into destination file. */
		if (!IOManager.WriteFile((__COMMON_OBJECT*)&IOManager,
			hDestinationFile,
			dwReadSize,
			pBuffer,
			&dwWriteSize))
		{
			_hx_printf("Failed to write data into target file.\r\n");
			goto __TERMINAL;
		}
		dwTotalRead += dwReadSize;

		/* Show out copying progress. */
		if (dwBatSize < dwReadSize)
		{
			_hx_printf(".");
			dwBatSize = dwFileSize / 20;
		}
		else
		{
			dwBatSize -= dwReadSize;
		}
	} while (dwReadSize == __TMP_FILE_BUFFSZ);
#undef __TMP_FILE_BUFFSZ

	_hx_printf("\r\n");
	_hx_printf("[copy]: %d byte(s) copied.\r\n", dwTotalRead);

__TERMINAL:
	if (NULL != hSourceFile)
	{
		IOManager.CloseFile((__COMMON_OBJECT*)&IOManager,
			hSourceFile);
	}
	if (NULL != hDestinationFile)
	{
		IOManager.CloseFile((__COMMON_OBJECT*)&IOManager,
			hDestinationFile);
	}
	if (NULL != pBuffer)
	{
		_hx_free(pBuffer);
	}
	return SHELL_CMD_PARSER_SUCCESS;;
#else
	return FS_CMD_FAILED;
#endif
}
示例#6
0
/*
 * Check if there is a PCI device in system that matches
 * the given ID,and initialize it if found.
 */
static BOOL _Check_E1000_Nic(struct pci_device_id* id)
{
	__PHYSICAL_DEVICE*    pDev = NULL;
	__IDENTIFIER          devId;
	struct e1000_hw*      priv = NULL;
	__U16                 iobase_s = 0, iobase_e = 0;
	LPVOID                memAddr_s = NULL;
	LPVOID                memAddr_e = NULL;
	int                   intVector = 0;
	int                   index = 0;
	BOOL                  bResult = FALSE;
	int                   cardnum = 0;

	//Set device ID accordingly.
	devId.dwBusType = BUS_TYPE_PCI;
	devId.Bus_ID.PCI_Identifier.ucMask = PCI_IDENTIFIER_MASK_VENDOR | PCI_IDENTIFIER_MASK_DEVICE;
	devId.Bus_ID.PCI_Identifier.wVendor = id->vendor_id;
	devId.Bus_ID.PCI_Identifier.wDevice = id->device_id;

	//Try to fetch the physical device with the specified ID.
	pDev = DeviceManager.GetDevice(
		&DeviceManager,
		BUS_TYPE_PCI,
		&devId,
		NULL);
	if (NULL == pDev)  //PCNet may not exist.
	{
		//DEBUGOUT("%s:No device[v_id = 0x%X,d_id = 0x%X] found.\r\n",
		//	__func__,id->vendor_id,id->device_id);
		goto __TERMINAL;
	}

	//Got a valid device,retrieve it's hardware resource and save them into 
	//private structure.
	while (pDev)
	{
		for (index = 0; index < MAX_RESOURCE_NUM; index++)
		{
			if (pDev->Resource[index].dwResType == RESOURCE_TYPE_INTERRUPT)
			{
				intVector = pDev->Resource[index].Dev_Res.ucVector;
			}
			if (pDev->Resource[index].dwResType == RESOURCE_TYPE_IO)
			{
				iobase_s = pDev->Resource[index].Dev_Res.IOPort.wStartPort;
				iobase_e = pDev->Resource[index].Dev_Res.IOPort.wEndPort;
			}
			if (pDev->Resource[index].dwResType == RESOURCE_TYPE_MEMORY)
			{
				memAddr_s = pDev->Resource[index].Dev_Res.MemoryRegion.lpStartAddr;
				memAddr_e = pDev->Resource[index].Dev_Res.MemoryRegion.lpEndAddr;
			}
		}
		//Check if the device with valid resource.
		if ((0 == intVector) && (0 == iobase_s) && (NULL == memAddr_s))
		{
			DEBUGOUT("%s: Find a device without valid resource.\r\n", __func__);
			goto __TERMINAL;
		}

		//Now allocate a rtl8111_priv_t structure and fill the resource.
		priv = (struct e1000_hw*)_hx_malloc(sizeof(struct e1000_hw));
		if (NULL == priv)
		{
			DEBUGOUT("%s:allocate e1000 private structure failed.\r\n", __func__);
			goto __TERMINAL;
		}
		memset(priv, 0, sizeof(struct e1000_hw));

		/* Create tx/rx descriptors and packet buffer. */
		priv->tx_base = (struct e1000_tx_desc*)_hx_aligned_malloc(
			TX_DESC_NUM * sizeof(struct e1000_tx_desc), E1000_BUFFER_ALIGN);
		if (NULL == priv->tx_base)
		{
			goto __TERMINAL;
		}
		priv->rx_base = (struct e1000_rx_desc*)_hx_aligned_malloc(
			RX_DESC_NUM * sizeof(struct e1000_rx_desc), E1000_BUFFER_ALIGN);
		if (NULL == priv->rx_base)
		{
			goto __TERMINAL;
		}
		priv->packet = (unsigned char*)_hx_aligned_malloc(PACKET_BUFFER_SIZE,
			E1000_BUFFER_ALIGN);
		if (NULL == priv->packet)
		{
			goto __TERMINAL;
		}

		priv->pdev = pDev;
		priv->ioport_s = iobase_s;
		priv->ioport_e = iobase_e;
		priv->memaddr_s = memAddr_s;
		priv->memaddr_e = memAddr_e;
		priv->int_vector = intVector;
		priv->cardnum = cardnum++;
		/* Save PCI id. */
		priv->device_id = id->device_id;
		priv->vendor_id = id->vendor_id;

		if (_Init_E1000(priv))
		{
			//Link the private object into global list.
			priv->pNext = e1000_hw_list;
			e1000_hw_list = priv;
			bResult = TRUE;
		}
		else
		{
			goto __TERMINAL;
		}

		DEBUGOUT("%s: Get a E1000 NIC device[int = %d,iobase = 0x%X,mem = 0x%X].\r\n",
			__func__,
			intVector,
			iobase_s,
			memAddr_s);

		//Try to fetch another PCNet device.
		pDev = DeviceManager.GetDevice(
			&DeviceManager,
			BUS_TYPE_PCI,
			&devId,
			pDev);
	}

__TERMINAL:
	if (!bResult)
	{
		if (priv)
		{
			if (priv->tx_base)
			{
				_hx_free(priv->tx_base);
			}
			if (priv->rx_base)
			{
				_hx_free(priv->rx_base);
			}
			if (priv->packet)
			{
				_hx_free(priv->packet);
			}
			_hx_free(priv);
		}
	}
	return bResult;
}
示例#7
0
/* 
 * Send out a packet through PPP/PPPoE main thread.
 * This routine is mainly used as sending routine of PPP interface,
 * which is called by IP layer.
 */
static BOOL pppSendPacket(struct netif* out_if, struct pbuf* pb, ip_addr_t* ipaddr)
{
	__PPP_SENDPACKET_BLOCK* pBlock = NULL;
	__KERNEL_THREAD_MESSAGE msg;
	DWORD dwFlags;
	BOOL bResult = FALSE;

	BUG_ON(NULL == out_if);
	BUG_ON(NULL == pb);

	/* Make sure the PPPoE main thread is in place. */
	if (NULL == pppoeManager.hMainThread)
	{
		goto __TERMINAL;
	}

	/* Allocate a parameter block object to hold all parameters. */
	pBlock = (__PPP_SENDPACKET_BLOCK*)_hx_malloc(sizeof(__PPP_SENDPACKET_BLOCK));
	if (NULL == pBlock)
	{
		goto __TERMINAL;
	}
	/* 
	 * Increase reference counter of pbuf,avoid to be deleted by 
	 * this routine's caller.
	 * The pbuf object will be released in the handler of SENDPACKET
	 * message.
	 */
	pbuf_ref(pb);

	pBlock->pNext = NULL;
	pBlock->out_if = out_if;
	pBlock->pkt_buff = pb; /* Should be confirmed if a new pbuf object should be allocated here. */
	pBlock->addr = *ipaddr;

	/*
	 * Hook the send packet block object into pppoeManager's out going list,
	 * and send a message to the PPPoE main thread if the list is empty,to
	 * trigger the sending process.
	 * Use critical section to protect the list operation since it maybe accessed
	 * in interrupt context.
	 */
	__ENTER_CRITICAL_SECTION_SMP(pppoeManager.spin_lock, dwFlags);
	if (0 == pppoeManager.nOutgSize) /* List is empty. */
	{
		BUG_ON(pppoeManager.pOutgFirst != NULL);
		BUG_ON(pppoeManager.pOutgLast != NULL);
		pppoeManager.pOutgFirst = pppoeManager.pOutgLast = pBlock;
		pBlock->pNext = NULL; /* Very important. */
		pppoeManager.nOutgSize++;
		/* 
		 * Send sending message to PPPoE main thread.
		 * Disable kernel thread's scheduling since in critical
		 * section.
		 */
		__LEAVE_CRITICAL_SECTION_SMP(pppoeManager.spin_lock, dwFlags);
		msg.wCommand = PPPOE_MSG_SENDPACKET;
		msg.wParam = 0;
		msg.dwParam = 0;
		bResult = SendMessage(pppoeManager.hMainThread, &msg);

		if (!bResult) /* Msg queue is full? */
		{
			__ENTER_CRITICAL_SECTION_SMP(pppoeManager.spin_lock, dwFlags);
			/* Unlink from list. */
			pppoeManager.pOutgFirst = pppoeManager.pOutgLast = NULL;
			pppoeManager.nOutgSize = 0;
			__LEAVE_CRITICAL_SECTION_SMP(pppoeManager.spin_lock, dwFlags);
			goto __TERMINAL;
		}
	}
	else /* The out going list is not empty. */
	{
		BUG_ON(NULL == pppoeManager.pOutgFirst);
		BUG_ON(NULL == pppoeManager.pOutgLast);
		if (pppoeManager.nOutgSize > PPPOE_MAX_PENDINGLIST_SIZE)
		{
			__LEAVE_CRITICAL_SECTION_SMP(pppoeManager.spin_lock, dwFlags);
			bResult = FALSE;
			goto __TERMINAL;
		}
		/* Link the block into lsit. */
		pBlock->pNext = NULL;
		pppoeManager.pOutgLast->pNext = pBlock;
		pppoeManager.pOutgLast = pBlock;
		pppoeManager.nOutgSize++;
		__LEAVE_CRITICAL_SECTION_SMP(pppoeManager.spin_lock, dwFlags);
		bResult = TRUE;
	}

#if 0 /* Obsoleted. */
	/* Send message to PPP/PPPoE main thread to trigger sending. */
	msg.wCommand = PPPOE_MSG_SENDPACKET;
	msg.wParam = 0;
	msg.dwParam = (DWORD)pBlock;
	bResult = SendMessage(pppoeManager.hMainThread, &msg);
#endif

__TERMINAL:
	if (!bResult)
	{
		/* Should release the parameter block object. */
		if (pBlock)
		{
			_hx_free(pBlock);
		}
		/* Free pbuf since we refered it. */
		pbuf_free(pb);
		LINK_STATS_INC(link.drop);
	}
	return bResult;
}
示例#8
0
/* Create a new PPPoE instance. */
static __PPPOE_INSTANCE* CreatePPPoEInstance(char* ethName, char* instName, char* user_name, 
	char* password,__PPPOE_AUTH_TYPE authType)
{
	__PPPOE_INSTANCE* pInstance = NULL;
	int i = 0;
	__ETHERNET_INTERFACE* pEthInt = NULL;
	__PPPOE_ETHIF_BINDING* pBinding = NULL;
	BOOL bResult = FALSE;

	BUG_ON(NULL == instName);
	BUG_ON(NULL == user_name);
	BUG_ON(NULL == ethName);

	/* 
	 * Can not create PPPoE instance without any ethernet interface
	 * that bound to PPPoE protocol.
	 */
	if (0 == current_bind_num)
	{
		goto __TERMINAL;
	}

	pInstance = _hx_malloc(sizeof(__PPPOE_INSTANCE));
	if (NULL == pInstance)
	{
		goto __TERMINAL;
	}
	/* Initialize it. */
	memset(pInstance, 0, sizeof(*pInstance));
	pInstance->authType = authType;
	pInstance->instance_id = session_id++;
	pInstance->ppp_session_id = -1;
	pInstance->status = SESSION_IDLE;
	pInstance->pEthInt = NULL;

	/* Set PPPoE user name. */
	if (strlen(user_name) > PPPOE_USER_NAME_LEN)
	{
		goto __TERMINAL;
	}
	strcpy(pInstance->user_name, user_name);

	/* Set PPPoE instance name. */
	if (strlen(instName) > PPPOE_SESSION_NAME_LEN)
	{
		goto __TERMINAL;
	}
	strcpy(pInstance->session_name, instName);

	/* Set password if specified. */
	if (strlen(password) > PPPOE_PASSWORD_LEN)
	{
		goto __TERMINAL;
	}
	strcpy(pInstance->password, password);

#if 0
	/* Set the ethernet interface this session based on. */
	pEthInt = EthernetManager.GetEthernetInterface(ethName);
	if (NULL == pEthInt)
	{
		goto __TERMINAL;
	}
	pInstance->pEthInt = pEthInt;
#endif

	/* Find the ethernet interface that this instance based on. */
	for (i = 0; i < PPPOE_MAX_INSTANCE_NUM; i++)
	{
		pBinding = &pppoeBinding[i];
		if (NULL == pBinding->pEthInt)
		{
			continue;
		}
		if (0 == strcmp(ethName, pBinding->pEthInt->ethName))
		{
			pInstance->pEthInt = pBinding->pEthInt;
			pBinding->pInstance = pInstance;
			break;
		}
	}
	if (NULL == pInstance->pEthInt) /* Can not match ethernet interface. */
	{
		goto __TERMINAL;
	}

	/* Link the instance to global list. */
	pInstance->pNext = pppoeManager.pInstanceList;
	pppoeManager.pInstanceList = pInstance;

	/* Set success indictor. */
	bResult = TRUE;

__TERMINAL:
	if (!bResult) /* Should release the instance. */
	{
		if (pInstance)
		{
			_hx_free(pInstance);
			pInstance = NULL;
		}
	}
	return pInstance;
}
示例#9
0
/*
* A helper routine to initialize and register a new found R8152
* device. It will be invoked when a new device is scaned in Driver Entry
* routine.
*/
static int Init_R8152(struct usb_device *dev, unsigned int ifnum)
{
	struct usb_interface *iface;
	struct usb_interface_descriptor *iface_desc;
	int ep_in_found = 0, ep_out_found = 0;
	struct ueth_data* ss = NULL;
	int i, ret = 0;
	struct r8152 *tp = NULL;
	char recv_name[64];
	static int ef_idx = 0;

	/* Construct a new management data struct of R8152. */
	ss = _hx_malloc(sizeof(struct ueth_data));
	if (NULL == ss)
	{
		goto __TERMINAL;
	}
	memset(ss, 0, sizeof(struct ueth_data));

	/* let's examine the device now */
	iface = &dev->config.if_desc[ifnum];
	iface_desc = &dev->config.if_desc[ifnum].desc;

	/* At this point, we know we've got a live one */
	debug("\n\nUSB Ethernet device detected: %#04x:%#04x\n",
		dev->descriptor.idVendor, dev->descriptor.idProduct);

	/* Initialize the ueth_data structure with some useful info */
	ss->ifnum = ifnum;
	ss->pusb_dev = dev;
	ss->subclass = iface_desc->bInterfaceSubClass;
	ss->protocol = iface_desc->bInterfaceProtocol;

	/* alloc driver private */
	ss->dev_priv = calloc(1, sizeof(struct r8152));
	if (!ss->dev_priv)
	{
		goto __TERMINAL;
	}
	memzero(ss->dev_priv, sizeof(struct r8152));

	/*
	* We are expecting a minimum of 3 endpoints - in, out (bulk), and
	* int. We will ignore any others.
	*/
	for (i = 0; i < iface_desc->bNumEndpoints; i++) {
		/* is it an BULK endpoint? */
		if ((iface->ep_desc[i].bmAttributes &
			USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
			u8 ep_addr = iface->ep_desc[i].bEndpointAddress;
			if ((ep_addr & USB_DIR_IN) && !ep_in_found) {
				ss->ep_in = ep_addr &
					USB_ENDPOINT_NUMBER_MASK;
				ep_in_found = 1;
			}
			else {
				if (!ep_out_found) {
					ss->ep_out = ep_addr &
						USB_ENDPOINT_NUMBER_MASK;
					ep_out_found = 1;
				}
			}
		}

		/* is it an interrupt endpoint? */
		if ((iface->ep_desc[i].bmAttributes &
			USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
			ss->ep_int = iface->ep_desc[i].bEndpointAddress &
				USB_ENDPOINT_NUMBER_MASK;
			ss->irqinterval = iface->ep_desc[i].bInterval;
		}
	}

	debug("Endpoints In %d Out %d Int %d\n", ss->ep_in, ss->ep_out, ss->ep_int);

	/* Do some basic sanity checks, and bail if we find a problem */
	if (usb_set_interface(dev, iface_desc->bInterfaceNumber, 0) ||
		!ss->ep_in || !ss->ep_out || !ss->ep_int) {
		debug("Problems with device\n");
		goto __TERMINAL;
	}

	/* Establish data structure's relationship. */
	dev->privptr = (void *)ss;
	tp = ss->dev_priv;
	tp->udev = dev;
	tp->intf = iface;

	r8152b_get_version(tp);

	if (rtl_ops_init(tp))
	{
		_hx_printf("%s: failed to init r8152 device.\r\n", __func__);
		goto __TERMINAL;
	}

	tp->rtl_ops.init(tp);
	tp->rtl_ops.up(tp);

	rtl8152_set_speed(tp, AUTONEG_ENABLE,
		tp->supports_gmii ? SPEED_1000 : SPEED_100,
		DUPLEX_FULL);

	/* Assign a index value to this USB ethernet interface. */
	ss->ef_idx = ef_idx++;

	/* Initialization seems OK,now register the R8152 device into
	* HelloX kernel.
	*/
	if (!Register_R8152(dev, ss))
	{
		_hx_printf("Failed to register R8152 into system.\r\n");
		goto __TERMINAL;
	}

	/*
	* Create the recv and send buffer.These 2 buffers
	* will be released when the corresponding rx/tx thread exit.
	*/
	ss->rx_buff = (char*)_hx_aligned_malloc(RTL8152_AGG_BUF_SZ, USB_DMA_MINALIGN);
	if (NULL == ss->rx_buff)
	{
		goto __TERMINAL;
	}
	ss->tx_buff = (char*)_hx_aligned_malloc(RTL8152_AGG_BUF_SZ, USB_DMA_MINALIGN);
	if (NULL == ss->tx_buff)
	{
		goto __TERMINAL;
	}

	/*
	* Create the rx and tx bulk transfer descriptor,which is used
	* by the corresponding rx/tx thread.
	* These 2 descriptors will be destroyed by the rx/tx thread before
	* exit.
	*/
	ss->pTxDesc = usbCreateAsyncDescriptor(
		ss->pusb_dev, usb_sndbulkpipe(ss->pusb_dev, ss->ep_out),
		ss->tx_buff, RTL8152_AGG_BUF_SZ, NULL);
	if (NULL == ss->pTxDesc)
	{
		goto __TERMINAL;
	}
	ss->pRxDesc = usbCreateAsyncDescriptor(
		ss->pusb_dev, usb_rcvbulkpipe(ss->pusb_dev, ss->ep_in),
		ss->rx_buff, RTL8152_AGG_BUF_SZ, NULL);
	if (NULL == ss->pRxDesc)
	{
		_hx_printf("%s: create rx desc failed.\r\n", __func__);
		goto __TERMINAL;
	}

	/*
	* Create the dedicated receiving kernel thread.
	*/
	_hx_sprintf(recv_name, "%s%d", R8152_RECV_NAME_BASE, ss->ef_idx);
	ss->pRxThread = KernelThreadManager.CreateKernelThread(
		(__COMMON_OBJECT*)&KernelThreadManager,
		0,
		KERNEL_THREAD_STATUS_SUSPENDED,
		PRIORITY_LEVEL_NORMAL,
		__R8152_Recv,
		(LPVOID)ss,
		NULL,
		recv_name);
	if (NULL == ss->pRxThread)
	{
		goto __TERMINAL;
	}

	/*
	* Create the dedicated sending kernel thread.
	*/
	_hx_sprintf(recv_name, "%s%d", R8152_SEND_NAME_BASE, ss->ef_idx);
	ss->pTxThread = KernelThreadManager.CreateKernelThread(
		(__COMMON_OBJECT*)&KernelThreadManager,
		0,
		KERNEL_THREAD_STATUS_SUSPENDED,
		PRIORITY_LEVEL_NORMAL,
		__R8152_Send,
		(LPVOID)ss,
		NULL,
		recv_name);
	if (NULL == ss->pTxThread)
	{
		goto __TERMINAL;
	}

	/* Link the management data structure into global list. */
	ss->pNext = global_list;
	global_list = ss;

	/* Resume the corresponding thread to run. */
	/*KernelThreadManager.ResumeKernelThread(
		(__COMMON_OBJECT*)&KernelThreadManager,
		(__COMMON_OBJECT*)ss->pRxThread);
	KernelThreadManager.ResumeKernelThread(
		(__COMMON_OBJECT*)&KernelThreadManager,
		(__COMMON_OBJECT*)ss->pTxThread);*/

	/* Mark all things in place. */
	ret = 1;

__TERMINAL:
	if (0 == ret)  /* Failed,should release all resources allocated. */
	{
		if (ss)
		{
			Unregister_R8152(dev, ss);
			if (ss->pRxThread)  //Shoud destroy it.
			{
				WaitForThisObject((HANDLE)ss->pRxThread);
				KernelThreadManager.DestroyKernelThread(
					(__COMMON_OBJECT*)&KernelThreadManager,
					(__COMMON_OBJECT*)ss->pRxThread);
			}
			if (ss->pTxThread)
			{
				WaitForThisObject((HANDLE)ss->pTxThread);
				KernelThreadManager.DestroyKernelThread(
					(__COMMON_OBJECT*)&KernelThreadManager,
					(__COMMON_OBJECT*)ss->pTxThread);
			}
			if (ss->dev_priv)
			{
				_hx_free(ss->dev_priv);
			}
			if (ss->rx_buff)
			{
				_hx_free(ss->rx_buff);
			}
			if (ss->tx_buff)
			{
				_hx_free(ss->tx_buff);
			}
			if (ss->pRxDesc)
			{
				usbStopAsyncXfer(ss->pRxDesc);
				usbDestroyAsyncDescriptor(ss->pRxDesc);
			}
			if (ss->pTxDesc)
			{
				usbStopAsyncXfer(ss->pTxDesc);
				usbDestroyAsyncDescriptor(ss->pTxDesc);
			}
			_hx_free(ss);
		}
		/* Reset USB device's private pointer since it maybe changed in
		* above process.
		*/
		dev->privptr = NULL;
	}
	return ret;
}
示例#10
0
//Delivery a Ethernet Frame to this protocol,a dedicated L3 interface is also provided.
BOOL pppoeDeliveryFrame(__ETHERNET_BUFFER* pEthBuff, LPVOID pL3Interface)
{
	__PPPOE_ETHIF_BINDING* pBinding = (__PPPOE_ETHIF_BINDING*)pL3Interface;
	__PPPOE_POSTFRAME_BLOCK* pBlock = NULL;
	struct pbuf *p = NULL, *q = NULL;
	int i = 0;
	BOOL bResult = FALSE;

	BUG_ON(NULL == pEthBuff);
	BUG_ON(NULL == pBinding);
	
	/* Make sure the frame type is PPPoE discovery or session. */
	if ((pEthBuff->frame_type != ETH_FRAME_TYPE_PPPOE_S) &&
		(pEthBuff->frame_type != ETH_FRAME_TYPE_PPPOE_D))
	{
		LINK_STATS_INC(link.proterr);
		goto __TERMINAL;
	}

	if (NULL == pBinding->pInstance) /* No PPPoE instance yet. */
	{
		//_hx_printf("PPPoE frame received but no PPPoE session yet.\r\n");
		goto __TERMINAL;
	}
	/* Only started instance is available to receive frame. */
	if (pBinding->pInstance->status != SESSION_RUNNING)
	{
		goto __TERMINAL;
	}

	/* Allocate post frame block object. */
	pBlock = (__PPPOE_POSTFRAME_BLOCK*)_hx_malloc(sizeof(__PPPOE_POSTFRAME_BLOCK));
	if (NULL == pBlock)
	{
		goto __TERMINAL;
	}
	pBlock->pInstance = pBinding->pInstance;
	pBlock->pEthInt = pEthBuff->pInInterface;
	pBlock->frame_type = pEthBuff->frame_type;
	pBlock->p = NULL;
	pBlock->pNext = NULL;

	p = pbuf_alloc(PBUF_RAW, pEthBuff->act_length, PBUF_RAM);
	if (NULL == p)
	{
		_hx_printf("  %s:allocate pbuf object failed.\r\n", __func__);
		goto __TERMINAL;
	}
	i = 0;
	for (q = p; q != NULL; q = q->next)
	{
		memcpy((u8_t*)q->payload, &pEthBuff->Buffer[i], q->len);
		i = i + q->len;
	}
	pBlock->p = p;

	//Delivery the frame to PPPoE main thread.
	bResult = pppoeManager.PostFrame(pBlock);

__TERMINAL:
	/* 
	 * pBlock and pbuf object should be released if delivery failed.
	 * They will be released in upper module if delivery success.
	 */
	if (!bResult)
	{
		if (p)
		{
			pbuf_free(p);
		}
		if (pBlock)
		{
			_hx_free(pBlock);
			LINK_STATS_INC(link.drop);
		}
	}
	else
	{
		LINK_STATS_INC(link.recv);
	}
	return bResult;
}