Пример #1
0
//
//	Description: 
//		This routine deal with the Power Configuration CMDs parsing for RTL8723/RTL8188E Series IC.
//
//	Assumption:
//		We should follow specific format which was released from HW SD. 
//
//	2011.07.07, added by Roger.
//
unsigned int HalPwrSeqCmdParsing(struct rtl8192cd_priv *priv, unsigned char CutVersion, unsigned char FabVersion, 
							 unsigned char InterfaceType, WLAN_PWR_CFG PwrSeqCmd[])
{
		
	WLAN_PWR_CFG 	PwrCfgCmd = {0};
	unsigned int 		bPollingBit = FALSE;
	unsigned int		AryIdx=0;
	unsigned char		value = 0;
	unsigned int		offset = 0;
	unsigned int 		pollingCount = 0; // polling autoload done.
	unsigned int		maxPollingCnt = 5000;
	
	do {
		PwrCfgCmd=PwrSeqCmd[AryIdx];

		DEBUG_INFO("%s %d, ENTRY, offset:0x%x, cut_msk:0x%x, fab_msk:0x%x, if_msk:0x%x, base:0x%x, cmd:0x%x, msk:0x%x, value:0x%x\n", 
			__FUNCTION__, __LINE__, GET_PWR_CFG_OFFSET(PwrCfgCmd), GET_PWR_CFG_CUT_MASK(PwrCfgCmd), 
			GET_PWR_CFG_FAB_MASK(PwrCfgCmd), GET_PWR_CFG_INTF_MASK(PwrCfgCmd), GET_PWR_CFG_BASE(PwrCfgCmd), 
			GET_PWR_CFG_CMD(PwrCfgCmd), GET_PWR_CFG_MASK(PwrCfgCmd), GET_PWR_CFG_VALUE(PwrCfgCmd));

		//2 Only Handle the command whose FAB, CUT, and Interface are matched
		if((GET_PWR_CFG_FAB_MASK(PwrCfgCmd)&FabVersion)&&
			(GET_PWR_CFG_CUT_MASK(PwrCfgCmd)&CutVersion)&&
			(GET_PWR_CFG_INTF_MASK(PwrCfgCmd)&InterfaceType)) {
			switch(GET_PWR_CFG_CMD(PwrCfgCmd))
			{
			case PWR_CMD_READ:
				DEBUG_INFO("%s %d, PWR_CMD_READ\n", __FUNCTION__, __LINE__);
				break;

			case PWR_CMD_WRITE:
				DEBUG_INFO("%s %d, PWR_CMD_WRITE\n", __FUNCTION__, __LINE__);
				offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);

#ifdef CONFIG_SDIO_HCI
				//
				// <Roger_Notes> We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface
				// 2011.07.07.
				//
				if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
				{
					// Read Back SDIO Local value
					value = SdioLocalCmd52Read1Byte(priv, offset);

					value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd));
					value |= (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd));

					// Write Back SDIO Local value
					SdioLocalCmd52Write1Byte(priv, offset, value);
				}
				else
#endif
				{
					//Read the value from system register		
					value = RTL_R8(offset);
					value = value&(~(GET_PWR_CFG_MASK(PwrCfgCmd)));
					value = value|(GET_PWR_CFG_VALUE(PwrCfgCmd)&GET_PWR_CFG_MASK(PwrCfgCmd));

					//Write the value back to sytem register
					RTL_W8(offset, value);
				}
				break;

			case PWR_CMD_POLLING:
				DEBUG_INFO("%s %d, PWR_CMD_POLLING\n", __FUNCTION__, __LINE__);
				bPollingBit = FALSE;					
				offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);				

				do {
#ifdef CONFIG_SDIO_HCI
					if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
						value = SdioLocalCmd52Read1Byte(priv, offset);
					else
#endif
					value = RTL_R8(offset);
					value=value&GET_PWR_CFG_MASK(PwrCfgCmd);
					if(value==(GET_PWR_CFG_VALUE(PwrCfgCmd)&GET_PWR_CFG_MASK(PwrCfgCmd)))
						bPollingBit=TRUE;
					else	
						delay_us(10);
					
					if(pollingCount++ > maxPollingCnt){
						DEBUG_WARN("%s %d, PWR_CMD_POLLING, Fail to polling Offset[0x%x]\n", __FUNCTION__, __LINE__, offset);
						return FALSE;
					}
				}while(!bPollingBit);

				break;

			case PWR_CMD_DELAY:
				DEBUG_INFO("%s %d, PWR_CMD_DELAY\n", __FUNCTION__, __LINE__);
				if(GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US)
					delay_us(GET_PWR_CFG_OFFSET(PwrCfgCmd));
				else
					delay_us(GET_PWR_CFG_OFFSET(PwrCfgCmd)*1000);
				break; 

			case PWR_CMD_END:
				// When this command is parsed, end the process
				DEBUG_INFO("%s %d, PWR_CMD_END\n", __FUNCTION__, __LINE__);
				return TRUE;
				break;

			default:
				DEBUG_ERR("%s %d, Unknown CMD!!\n", __FUNCTION__, __LINE__);
				break;
			}

		}
		
		AryIdx++;//Add Array Index
	}while(1);

	return TRUE;
}
Пример #2
0
/**************************************************************************
SEND - Transmit a frame
***************************************************************************/
static int rtl_send(struct eth_device *dev, void *packet, int length)
{
	/* send the packet to destination */

	u32 to;
	u8 *ptxb;
	int entry = tpc->cur_tx % NUM_TX_DESC;
	u32 len = length;
	int ret;

#ifdef DEBUG_RTL8169_TX
	int stime = currticks();
	printf ("%s\n", __FUNCTION__);
	printf("sending %d bytes\n", len);
#endif

	ioaddr = dev->iobase;

	/* point to the current txb incase multiple tx_rings are used */
	ptxb = tpc->Tx_skbuff[entry * MAX_ETH_FRAME_SIZE];
	memcpy(ptxb, (char *)packet, (int)length);
	rtl_flush_buffer(ptxb, length);

	while (len < ETH_ZLEN)
		ptxb[len++] = '\0';

	tpc->TxDescArray[entry].buf_Haddr = 0;
	tpc->TxDescArray[entry].buf_addr = cpu_to_le32(bus_to_phys(ptxb));
	if (entry != (NUM_TX_DESC - 1)) {
		tpc->TxDescArray[entry].status =
			cpu_to_le32((OWNbit | FSbit | LSbit) |
				    ((len > ETH_ZLEN) ? len : ETH_ZLEN));
	} else {
		tpc->TxDescArray[entry].status =
			cpu_to_le32((OWNbit | EORbit | FSbit | LSbit) |
				    ((len > ETH_ZLEN) ? len : ETH_ZLEN));
	}
	rtl_flush_tx_desc(&tpc->TxDescArray[entry]);
	RTL_W8(TxPoll, 0x40);	/* set polling bit */

	tpc->cur_tx++;
	to = currticks() + TX_TIMEOUT;
	do {
		rtl_inval_tx_desc(&tpc->TxDescArray[entry]);
	} while ((le32_to_cpu(tpc->TxDescArray[entry].status) & OWNbit)
				&& (currticks() < to));	/* wait */

	if (currticks() >= to) {
#ifdef DEBUG_RTL8169_TX
		puts("tx timeout/error\n");
		printf("%s elapsed time : %lu\n", __func__, currticks()-stime);
#endif
		ret = 0;
	} else {
#ifdef DEBUG_RTL8169_TX
		puts("tx done\n");
#endif
		ret = length;
	}
	/* Delay to make net console (nc) work properly */
	udelay(20);
	return ret;
}
Пример #3
0
static void rtl8169_hw_start(struct eth_device *dev)
{
	u32 i;

#ifdef DEBUG_RTL8169
	int stime = currticks();
	printf ("%s\n", __FUNCTION__);
#endif

#if 0
	/* Soft reset the chip. */
	RTL_W8(ChipCmd, CmdReset);

	/* Check that the chip has finished the reset. */
	for (i = 1000; i > 0; i--) {
		if ((RTL_R8(ChipCmd) & CmdReset) == 0)
			break;
		else
			udelay(10);
	}
#endif

	RTL_W8(Cfg9346, Cfg9346_Unlock);

	/* RTL-8169sb/8110sb or previous version */
	if (tpc->chipset <= 5)
		RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);

	RTL_W8(EarlyTxThres, EarlyTxThld);

	/* For gigabit rtl8169 */
	RTL_W16(RxMaxSize, RxPacketMaxSize);

	/* Set Rx Config register */
	i = rtl8169_rx_config | (RTL_R32(RxConfig) &
				 rtl_chip_info[tpc->chipset].RxConfigMask);
	RTL_W32(RxConfig, i);

	/* Set DMA burst size and Interframe Gap Time */
	RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) |
				(InterFrameGap << TxInterFrameGapShift));


	tpc->cur_rx = 0;

	RTL_W32(TxDescStartAddrLow, bus_to_phys(tpc->TxDescArray));
	RTL_W32(TxDescStartAddrHigh, (unsigned long)0);
	RTL_W32(RxDescStartAddrLow, bus_to_phys(tpc->RxDescArray));
	RTL_W32(RxDescStartAddrHigh, (unsigned long)0);

	/* RTL-8169sc/8110sc or later version */
	if (tpc->chipset > 5)
		RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);

	RTL_W8(Cfg9346, Cfg9346_Lock);
	udelay(10);

	RTL_W32(RxMissed, 0);

	rtl8169_set_rx_mode(dev);

	/* no early-rx interrupts */
	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);

#ifdef DEBUG_RTL8169
	printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime);
#endif
}
Пример #4
0
void rtl_raise_clock(u8 *x, void __iomem *ioaddr)
{
    *x = *x | Cfg9346_EESK;
    RTL_W8(Cfg9346, *x);
    udelay(RTL_CLOCK_RATE);
}
Пример #5
0
static int
OOB_set_ip_mac(struct rtl8168_private *tp, struct sockaddr_in *sa, u8 *mac)
{
    u32 data;

    if (tp->mcfg == CFG_METHOD_13) {
        OCP_write(tp, 0xF, 0xd0, be32_to_cpu(sa->sin_addr.s_addr));

        memcpy(&data, mac, 4);
        OCP_write(tp, 0xF, 0x00, le32_to_cpu(data));
        data = 0;
        memcpy(&data, mac + 4, 2);
        OCP_write(tp, 0x3, 0x04, le32_to_cpu(data));

        OOB_notify(tp, OOB_CMD_SET_IPMAC);
    } else if (tp->mcfg == CFG_METHOD_17) {
        void __iomem *ioaddr = tp->mmio_addr;
        struct net_device *dev = tp->dev;
        u32 rx_mode;

        rx_mode = RTL_R32(RxConfig);
        if (netif_running(dev)) {
            netif_stop_queue(dev);
            RTL_W32(RxConfig, rx_mode & ~0x3f);
            while ((RTL_R8(0xd3) & (BIT_5 | BIT_4)) != ((BIT_5 | BIT_4)))
                udelay(20);
            RTL_W8(ChipCmd, RTL_R8(ChipCmd) & ~(CmdTxEnb | CmdRxEnb));
//		} else {
//			unsigned long flags;
//
//			spin_lock_irqsave(&tp->phy_lock, flags);
//			mdio_write(tp, 0x1f, 0x0000);
//			data = mdio_read(tp, MII_CTRL1000);
//			data &=	~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
//			mdio_write(tp, MII_CTRL1000, data);
//			mdio_write(tp, 0x00, 0x9200);
//			spin_unlock_irqrestore(&tp->phy_lock, flags);
//
//			ssleep(3);
//			RTL_W16(IntrStatus, RTL_R16(IntrStatus));
//
//			RTL_W32(MAR0, 0);
//			RTL_W32(MAR0 + 4, 0);
//			RTL_W16(RxMaxSize, 0x05f3);
        }
        RTL_W8(0xD3, RTL_R8(0xD3) & ~BIT_7);
        rtl8168_eri_write(ioaddr, 0x180, 4, 0x06080888, ERIAR_ExGMAC);
        rtl8168_eri_write(ioaddr, 0x184, 4, 0xdd860008, ERIAR_ExGMAC);

        memcpy(&data, mac, 2);
        rtl8168_eri_write(ioaddr, 0xf0, 4, (le32_to_cpu(data) << 16), ERIAR_ExGMAC);
        memcpy(&data, mac + 2, 4);
        rtl8168_eri_write(ioaddr, 0xf4, 4, le32_to_cpu(data), ERIAR_ExGMAC);

        rtl8168_eri_write(ioaddr, 0x190, 4, 0x3c110600, ERIAR_ExGMAC);
        rtl8168_eri_write(ioaddr, 0x194, 4, 0x2c32332b, ERIAR_ExGMAC);
        rtl8168_eri_write(ioaddr, 0x198, 4, 0x003a0201, ERIAR_ExGMAC);
        rtl8168_eri_write(ioaddr, 0x19c, 4, 0x00000000, ERIAR_ExGMAC);

        rtl8168_eri_write(ioaddr, 0x1f0, 4, cpu_to_le32(sa->sin_addr.s_addr), ERIAR_ExGMAC);

        memcpy(&data, mac, 4);
        rtl8168_eri_write(ioaddr, 0x258, 4, le32_to_cpu(data), ERIAR_ExGMAC);
        memcpy(&data, mac + 4, 2);
        rtl8168_eri_write(ioaddr, 0x25c, 2, le32_to_cpu(data), ERIAR_ExGMAC);

        RTL_W8(0xe0, RTL_R8(0xe0) | BIT_6);
        while (!(RTL_R8(0xd3) & BIT_1))
            udelay(20);

        RTL_W32(0xb0, 0x9800e035);
        RTL_W32(0xb0, 0x9801e034);
        RTL_W32(0xb0, 0x9802e019);
        RTL_W32(0xb0, 0x98039918);
        RTL_W32(0xb0, 0x9804c011);
        RTL_W32(0xb0, 0x98057100);
        RTL_W32(0xb0, 0x9806499f);
        RTL_W32(0xb0, 0x9807f011);
        RTL_W32(0xb0, 0x9808c00e);
        RTL_W32(0xb0, 0x98097100);
        RTL_W32(0xb0, 0x980A4995);
        RTL_W32(0xb0, 0x980Bf00d);
        RTL_W32(0xb0, 0x980C4895);
        RTL_W32(0xb0, 0x980D9900);
        RTL_W32(0xb0, 0x980Ec009);
        RTL_W32(0xb0, 0x980F7100);
        RTL_W32(0xb0, 0x98104890);
        RTL_W32(0xb0, 0x98119900);
        RTL_W32(0xb0, 0x98124810);
        RTL_W32(0xb0, 0x98139900);
        RTL_W32(0xb0, 0x9814e004);
        RTL_W32(0xb0, 0x9815d44e);
        RTL_W32(0xb0, 0x9816d506);
        RTL_W32(0xb0, 0x9817c0b4);
        RTL_W32(0xb0, 0x9818c002);
        RTL_W32(0xb0, 0x9819b800);
        RTL_W32(0xb0, 0x981A0500);
        RTL_W32(0xb0, 0x981B1a26);
        RTL_W32(0xb0, 0x981Ca4ca);
        RTL_W32(0xb0, 0x981D21bc);
        RTL_W32(0xb0, 0x981E25bc);
        RTL_W32(0xb0, 0x981F1305);
        RTL_W32(0xb0, 0x9820f00d);
        RTL_W32(0xb0, 0x9821c213);
        RTL_W32(0xb0, 0x98227340);
        RTL_W32(0xb0, 0x982349b0);
        RTL_W32(0xb0, 0x9824f009);
        RTL_W32(0xb0, 0x98251a3a);
        RTL_W32(0xb0, 0x9826a4ca);
        RTL_W32(0xb0, 0x982721b9);
        RTL_W32(0xb0, 0x982825b9);
        RTL_W32(0xb0, 0x98291303);
        RTL_W32(0xb0, 0x982Af006);
        RTL_W32(0xb0, 0x982B1309);
        RTL_W32(0xb0, 0x982Cf004);
        RTL_W32(0xb0, 0x982Dc306);
        RTL_W32(0xb0, 0x982E1a26);
        RTL_W32(0xb0, 0x982Fbb00);
        RTL_W32(0xb0, 0x9830c302);
        RTL_W32(0xb0, 0x9831bb00);
        RTL_W32(0xb0, 0x98320f3e);
        RTL_W32(0xb0, 0x98330f4e);
        RTL_W32(0xb0, 0x9834c0ae);
        RTL_W32(0xb0, 0x98351800);
        RTL_W32(0xb0, 0x9836b800);
        RTL_W32(0xb0, 0xfe173000);
        RTL_W32(0xb0, 0xfe1604ff);
        RTL_W32(0xb0, 0xfe150f4d);
        data = rtl8168_eri_read(ioaddr, 0xd6, 1, ERIAR_ExGMAC);
        rtl8168_eri_write(ioaddr, 0xd6, 1, data | BIT_0, ERIAR_ExGMAC);

        if (netif_running(dev)) {
            rtl8168_init_ring_indexes(tp);
            RTL_W8(ChipCmd, CmdRxEnb | CmdTxEnb);
            RTL_W32(RxConfig, rx_mode);
            netif_wake_queue(dev);
        } else {
            RTL_W8(0xD3, RTL_R8(0xD3) | BIT_7);

//			data = rtl8168_eri_read(ioaddr, 0xDC, 1, ERIAR_ExGMAC);
//			data &= ~BIT_0;
//			rtl8168_eri_write( ioaddr, 0xDC, 1, data, ERIAR_ExGMAC);
//			data |= BIT_0;
//			rtl8168_eri_write( ioaddr, 0xDC, 1, data, ERIAR_ExGMAC);

            RTL_W32(RxConfig, rx_mode | 0x0e);
        }
    } else {
        return -EFAULT;
    }
    return 0;
}
Пример #6
0
void Scan_BB_PSD(
	IN PDM_ODM_T	pDM_Odm,
	int *PSD_report_right,
	int *PSD_report_left,
	int len,
	int initial_gain)
{
	struct rtl8192cd_priv *priv=pDM_Odm->priv;
	pDIG_T  pDM_DigTable = &pDM_Odm->DM_DigTable;
	u1Byte  ST_TH_origin;
	u1Byte	idx[20]={//96,99,102,106,109,112,115,118,122,125,
	                     224,227,230,234,237,240,243,246,250,253,
					0,3,6,10,13,16,19,22,26,29};
	int tone_idx, channel_org, channel, i;

	// set DFS ST_TH to max value
	ST_TH_origin = RTL_R8(0x91c);
	RTL_W8(0x91c, 0x4e);
	
	// Turn off CCK
	ODM_SetBBReg(pDM_Odm, 0x808, BIT28, 0);   //808[28]

	// Turn off TX
	// Pause TX Queue
	if (!priv->pmib->dot11DFSEntry.disable_tx)
		ODM_Write1Byte(pDM_Odm, 0x522, 0xFF); //REG_TXPAUSE 改為0x522

	// Turn off CCA
	if(GET_CHIP_VER(priv) == VERSION_8814A){
		ODM_SetBBReg(pDM_Odm, 0x838, BIT1, 0x1); //838[1] 設為1
	}
	else{
		ODM_SetBBReg(pDM_Odm, 0x838, BIT3, 0x1); //838[3] 設為1
	}
	
	// PHYTXON while loop
	PHY_SetBBReg(priv, 0x8fc, 0xfff, 0);
	i = 0;
	while (ODM_GetBBReg(pDM_Odm, 0xfa0, BIT18)) {
		i++;
		if (i > 1000000) {
			panic_printk("Wait in %s() more than %d times!\n", __FUNCTION__, i);
			break;
		}
	}

	// backup IGI_origin , set IGI = 0x3e;
	pDM_DigTable->bPSDInProgress = TRUE;
	odm_PauseDIG(pDM_Odm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_7, initial_gain);

	// Turn off 3-wire
	ODM_SetBBReg(pDM_Odm, 0xC00, BIT1|BIT0, 0x0); //c00[1:0] 寫0

	// pts value = 128, 256, 512, 1024
	ODM_SetBBReg(pDM_Odm, 0x910, BIT14|BIT15, 0x1); //910[15:14]設為1, 用256點
	ODM_SetBBReg(pDM_Odm, 0x910, BIT12|BIT13, 0x1); //910[13:12]設為1, avg 8 次

	// scan in-band PSD
	channel_org = ODM_GetRFReg(pDM_Odm, RF_PATH_A, RF_CHNLBW, 0x3FF);
	if(priv, priv->pshare->CurrentChannelBW != HT_CHANNEL_WIDTH_20){
		priv->pshare->No_RF_Write = 0;
		SwBWMode(priv, HT_CHANNEL_WIDTH_20, 0);
		priv->pshare->No_RF_Write = 1;
	}
	
	if (priv->pshare->rf_ft_var.dfs_scan_inband) {
		int PSD_report_inband[20];
		for (tone_idx=0;tone_idx<len;tone_idx++)
			PSD_report_inband[tone_idx] = GetPSDData_8812(pDM_Odm, idx[tone_idx], initial_gain);
		panic_printk("PSD inband: ");
		for (i=0; i<len; i++)
			panic_printk("%d ", PSD_report_inband[i]);
		panic_printk("\n");
	}

	// scan right(higher) neighbor channel
	if (priv->pshare->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
		channel = channel_org + 4;
	else if (priv->pshare->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
		channel = channel_org + 6;
	else
		channel = channel_org + 10;
	delay_us(300);  // for idle 20M, it will  emit signal in right 20M channel
	priv->pshare->No_RF_Write = 0;
	ODM_SetRFReg(pDM_Odm, RF_PATH_A, RF_CHNLBW, 0x3FF, channel);
	priv->pshare->No_RF_Write = 1;

	for (tone_idx=0;tone_idx<len;tone_idx++)
		PSD_report_right[tone_idx] = GetPSDData_8812(pDM_Odm, idx[tone_idx], initial_gain);
	
	// scan left(lower) neighbor channel
	if (priv->pshare->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
		channel = channel_org - 4;
	else if (priv->pshare->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
		channel = channel_org - 6;
	else
		channel = channel_org - 10;
	priv->pshare->No_RF_Write = 0;
	ODM_SetRFReg(pDM_Odm, RF_PATH_A, RF_CHNLBW, 0x3FF, channel);
	priv->pshare->No_RF_Write = 1;

	for (tone_idx=0;tone_idx<len;tone_idx++)
		PSD_report_left[tone_idx] = GetPSDData_8812(pDM_Odm, idx[tone_idx], initial_gain);
	

	// restore originl center frequency
	if(priv, priv->pshare->CurrentChannelBW != HT_CHANNEL_WIDTH_20){
		priv->pshare->No_RF_Write = 0;
		SwBWMode(priv, priv->pshare->CurrentChannelBW, priv->pshare->offset_2nd_chan);
		priv->pshare->No_RF_Write = 1;
	}
	priv->pshare->No_RF_Write = 0;
	ODM_SetRFReg(pDM_Odm, RF_PATH_A, RF_CHNLBW, 0x3FF, channel_org);
	priv->pshare->No_RF_Write = 1;

	// Turn on 3-wire
	ODM_SetBBReg(pDM_Odm, 0xc00, BIT1|BIT0, 0x3); //c00[1:0] 寫3

	// Restore Current Settings
	// Resume DIG
	pDM_DigTable->bPSDInProgress = FALSE;
	odm_PauseDIG(pDM_Odm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_7, NONE);

	//Turn on CCA
	if(GET_CHIP_VER(priv) == VERSION_8814A){
		ODM_SetBBReg(pDM_Odm, 0x838, BIT1, 0); //838[1] 設為0
	}
	else{
		ODM_SetBBReg(pDM_Odm, 0x838, BIT3, 0); //838[3] 設為0
	}
	

	// Turn on TX
	// Resume TX Queue
	if (!priv->pmib->dot11DFSEntry.disable_tx)
		ODM_Write1Byte(pDM_Odm, 0x522, 0x00); //REG_TXPAUSE 改為0x522

	// CCK on
	if (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_2G)
	ODM_SetBBReg(pDM_Odm, 0x808, BIT28, 1); //808[28]	
	
	// Resume DFS ST_TH
	RTL_W8(0x91c, ST_TH_origin);
}
Пример #7
0
static int __devinit
rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
    struct net_device *dev = NULL;
    struct rtl8169_private *tp = NULL;
    void *ioaddr = NULL;
    static int board_idx = -1;
    static int printed_version = 0;
    int i, rc;
    int option = -1, Cap10_100 = 0, Cap1000 = 0;

    assert(pdev != NULL);
    assert(ent != NULL);

    board_idx++;

    if (!printed_version) {
        printk(KERN_INFO RTL8169_DRIVER_NAME " loaded\n");
        printed_version = 1;
    }

    rc = rtl8169_init_board(pdev, &dev, &ioaddr);
    if (rc)
        return rc;

    tp = dev->priv;
    assert(ioaddr != NULL);
    assert(dev != NULL);
    assert(tp != NULL);

    // Get MAC address.  FIXME: read EEPROM
    for (i = 0; i < MAC_ADDR_LEN; i++)
        dev->dev_addr[i] = RTL_R8(MAC0 + i);

    dev->open = rtl8169_open;
    dev->hard_start_xmit = rtl8169_start_xmit;
    dev->get_stats = rtl8169_get_stats;
    dev->ethtool_ops = &rtl8169_ethtool_ops;
    dev->stop = rtl8169_close;
    dev->tx_timeout = rtl8169_tx_timeout;
    dev->set_multicast_list = rtl8169_set_rx_mode;
    dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
    dev->irq = pdev->irq;
    dev->base_addr = (unsigned long) ioaddr;
//      dev->do_ioctl           = mii_ioctl;

    tp = dev->priv;		// private data //
    tp->pci_dev = pdev;
    tp->mmio_addr = ioaddr;

    spin_lock_init(&tp->lock);

    rc = register_netdev(dev);
    if (rc) {
        iounmap(ioaddr);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
        free_netdev(dev);
        return rc;
    }

    printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n", dev->name,
           rtl_chip_info[tp->chipset].name);

    pci_set_drvdata(pdev, dev);

    printk(KERN_INFO "%s: %s at 0x%lx, "
           "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
           "IRQ %d\n",
           dev->name,
           rtl_chip_info[ent->driver_data].name,
           dev->base_addr,
           dev->dev_addr[0], dev->dev_addr[1],
           dev->dev_addr[2], dev->dev_addr[3],
           dev->dev_addr[4], dev->dev_addr[5], dev->irq);

    rtl8169_hw_phy_config(dev);

    dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
    RTL_W8(0x82, 0x01);

    if (tp->mac_version < RTL_GIGA_MAC_VER_E) {
        dprintk("Set PCI Latency=0x40\n");
        pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
    }

    if (tp->mac_version == RTL_GIGA_MAC_VER_D) {
        dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
        RTL_W8(0x82, 0x01);
        dprintk("Set PHY Reg 0x0bh = 0x00h\n");
        mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0
    }

    // if TBI is not endbled
    if (!(RTL_R8(PHYstatus) & TBI_Enable)) {
        int val = mdio_read(ioaddr, PHY_AUTO_NEGO_REG);

        option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx];
        // Force RTL8169 in 10/100/1000 Full/Half mode.
        if (option > 0) {
            printk(KERN_INFO "%s: Force-mode Enabled.\n",
                   dev->name);
            Cap10_100 = 0, Cap1000 = 0;
            switch (option) {
            case _10_Half:
                Cap10_100 = PHY_Cap_10_Half_Or_Less;
                Cap1000 = PHY_Cap_Null;
                break;
            case _10_Full:
                Cap10_100 = PHY_Cap_10_Full_Or_Less;
                Cap1000 = PHY_Cap_Null;
                break;
            case _100_Half:
                Cap10_100 = PHY_Cap_100_Half_Or_Less;
                Cap1000 = PHY_Cap_Null;
                break;
            case _100_Full:
                Cap10_100 = PHY_Cap_100_Full_Or_Less;
                Cap1000 = PHY_Cap_Null;
                break;
            case _1000_Full:
                Cap10_100 = PHY_Cap_100_Full_Or_Less;
                Cap1000 = PHY_Cap_1000_Full;
                break;
            default:
                break;
            }
            mdio_write(ioaddr, PHY_AUTO_NEGO_REG, Cap10_100 | (val & 0x1F));	//leave PHY_AUTO_NEGO_REG bit4:0 unchanged
            mdio_write(ioaddr, PHY_1000_CTRL_REG, Cap1000);
        } else {
            printk(KERN_INFO "%s: Auto-negotiation Enabled.\n",
                   dev->name);

            // enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged
            mdio_write(ioaddr, PHY_AUTO_NEGO_REG,
                       PHY_Cap_100_Full_Or_Less | (val & 0x1f));

            // enable 1000 Full Mode
            mdio_write(ioaddr, PHY_1000_CTRL_REG,
                       PHY_Cap_1000_Full);

        }

        // Enable auto-negotiation and restart auto-nigotiation
        mdio_write(ioaddr, PHY_CTRL_REG,
                   PHY_Enable_Auto_Nego | PHY_Restart_Auto_Nego);
        udelay(100);

        // wait for auto-negotiation process
        for (i = 10000; i > 0; i--) {
            //check if auto-negotiation complete
            if (mdio_read(ioaddr, PHY_STAT_REG) &
                    PHY_Auto_Neco_Comp) {
                udelay(100);
                option = RTL_R8(PHYstatus);
                if (option & _1000bpsF) {
                    printk(KERN_INFO
                           "%s: 1000Mbps Full-duplex operation.\n",
                           dev->name);
                } else {
                    printk(KERN_INFO
                           "%s: %sMbps %s-duplex operation.\n",
                           dev->name,
                           (option & _100bps) ? "100" :
                           "10",
                           (option & FullDup) ? "Full" :
                           "Half");
                }
                break;
            } else {
                udelay(100);
            }
        }		// end for-loop to wait for auto-negotiation process

    } else {
        udelay(100);
        printk(KERN_INFO
               "%s: 1000Mbps Full-duplex operation, TBI Link %s!\n",
               dev->name,
               (RTL_R32(TBICSR) & TBILinkOK) ? "OK" : "Failed");

    }

    return 0;
}
Пример #8
0
static int __devinit
rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
                   void **ioaddr_out)
{
    void *ioaddr = NULL;
    struct net_device *dev;
    struct rtl8169_private *tp;
    unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
    int rc, i, acpi_idle_state = 0, pm_cap;


    assert(pdev != NULL);
    assert(ioaddr_out != NULL);

    *ioaddr_out = NULL;
    *dev_out = NULL;

    // dev zeroed in alloc_etherdev
    dev = alloc_etherdev(sizeof (*tp));
    if (dev == NULL) {
        printk(KERN_ERR PFX "unable to alloc new ethernet\n");
        return -ENOMEM;
    }

    SET_MODULE_OWNER(dev);
    SET_NETDEV_DEV(dev, &pdev->dev);
    tp = dev->priv;

    // enable device (incl. PCI PM wakeup and hotplug setup)
    rc = pci_enable_device(pdev);
    if (rc) {
        printk(KERN_ERR PFX "%s: unable to enable device\n", pdev->slot_name);
        goto err_out;
    }

    /* save power state before pci_enable_device overwrites it */
    pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
    if (pm_cap) {
        u16 pwr_command;

        pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command);
        acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
    } else {
        printk(KERN_ERR PFX "Cannot find PowerManagement capability, aborting.\n");
        goto err_out_free_res;
    }

    mmio_start = pci_resource_start(pdev, 1);
    mmio_end = pci_resource_end(pdev, 1);
    mmio_flags = pci_resource_flags(pdev, 1);
    mmio_len = pci_resource_len(pdev, 1);

    // make sure PCI base addr 1 is MMIO
    if (!(mmio_flags & IORESOURCE_MEM)) {
        printk(KERN_ERR PFX
               "region #1 not an MMIO resource, aborting\n");
        rc = -ENODEV;
        goto err_out_disable;
    }
    // check for weird/broken PCI region reporting
    if (mmio_len < RTL_MIN_IO_SIZE) {
        printk(KERN_ERR PFX "Invalid PCI region size(s), aborting\n");
        rc = -ENODEV;
        goto err_out_disable;
    }

    rc = pci_request_regions(pdev, dev->name);
    if (rc) {
        printk(KERN_ERR PFX "%s: Could not request regions.\n", pdev->slot_name);
        goto err_out_disable;
    }

    tp->cp_cmd = PCIMulRW | RxChkSum;

    if ((sizeof(dma_addr_t) > 32) &&
            !pci_set_dma_mask(pdev, DMA_64BIT_MASK))
        tp->cp_cmd |= PCIDAC;
    else {
        rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
        if (rc < 0) {
            printk(KERN_ERR PFX "DMA configuration failed.\n");
            goto err_out_free_res;
        }
    }


    // enable PCI bus-mastering
    pci_set_master(pdev);

    // ioremap MMIO region
    ioaddr = ioremap(mmio_start, mmio_len);
    if (ioaddr == NULL) {
        printk(KERN_ERR PFX "cannot remap MMIO, aborting\n");
        rc = -EIO;
        goto err_out_free_res;
    }

    // Soft reset the chip.
    RTL_W8(ChipCmd, CmdReset);

    // Check that the chip has finished the reset.
    for (i = 1000; i > 0; i--) {
        if ((RTL_R8(ChipCmd) & CmdReset) == 0)
            break;
        udelay(10);
    }

    // Identify chip attached to board
    rtl8169_get_mac_version(tp, ioaddr);
    rtl8169_get_phy_version(tp, ioaddr);

    rtl8169_print_mac_version(tp);
    rtl8169_print_phy_version(tp);

    for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) {
        if (tp->mac_version == rtl_chip_info[i].mac_version)
            break;
    }
    if (i < 0) {
        /* Unknown chip: assume array element #0, original RTL-8169 */
        printk(KERN_DEBUG PFX
               "PCI device %s: unknown chip version, assuming %s\n",
               pci_name(pdev), rtl_chip_info[0].name);
        i++;
    }
    tp->chipset = i;

    *ioaddr_out = ioaddr;
    *dev_out = dev;
    return 0;

err_out_free_res:
    pci_release_regions(pdev);

err_out_disable:
    pci_disable_device(pdev);

err_out:
    free_netdev(dev);
    return rc;
}
Пример #9
0
static void
rtl8169_hw_start(struct net_device *dev)
{
    struct rtl8169_private *tp = dev->priv;
    void *ioaddr = tp->mmio_addr;
    u32 i;

    /* Soft reset the chip. */
    RTL_W8(ChipCmd, CmdReset);

    /* Check that the chip has finished the reset. */
    for (i = 1000; i > 0; i--) {
        if ((RTL_R8(ChipCmd) & CmdReset) == 0)
            break;
        else
            udelay(10);
    }

    RTL_W8(Cfg9346, Cfg9346_Unlock);
    RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
    RTL_W8(EarlyTxThres, EarlyTxThld);

    // For gigabit rtl8169
    RTL_W16(RxMaxSize, RxPacketMaxSize);

    // Set Rx Config register
    i = rtl8169_rx_config | (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].
                             RxConfigMask);
    RTL_W32(RxConfig, i);

    /* Set DMA burst size and Interframe Gap Time */
    RTL_W32(TxConfig,
            (TX_DMA_BURST << TxDMAShift) | (InterFrameGap <<
                                            TxInterFrameGapShift));
    tp->cp_cmd |= RTL_R16(CPlusCmd);
    RTL_W16(CPlusCmd, tp->cp_cmd);

    if (tp->mac_version == RTL_GIGA_MAC_VER_D) {
        dprintk(KERN_INFO PFX "Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14 MUST be 1\n");
        tp->cp_cmd |= (1 << 14) | PCIMulRW;
        RTL_W16(CPlusCmd, tp->cp_cmd);
    }

    tp->cur_rx = 0;

    RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr & DMA_32BIT_MASK));
    RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32));
    RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK));
    RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32));
    RTL_W8(Cfg9346, Cfg9346_Lock);
    udelay(10);

    RTL_W32(RxMissed, 0);

    rtl8169_set_rx_mode(dev);

    /* no early-rx interrupts */
    RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);

    /* Enable all known interrupts by setting the interrupt mask. */
    RTL_W16(IntrMask, rtl8169_intr_mask);

    netif_start_queue(dev);

}