SylixOS MII总线层解析

1.原理概述

1.1 网卡驱动概述

一块以太网网卡包括OSI模型的两个层:物理层和数据链路层。数据链路层的芯片简称为MAC控制器,物理层的芯片简称为PHY。

MAC主要负责控制与连接物理层的物理介质。在发送数据时,MAC先判断是否可以发送数据,如果可以发送,给数据加上控制信息,最终将数据及控制信息按规定的格式发送到物理层;在接收数据的时候,MAC先判断信息是否发生传输错误,如果没有错误,去掉控制信息发送至LLC层。该层协议由IEEE-802.3以太网标准定义。

PHY是物理接口收发器,它实现物理层。IEEE-802.3标准定义了以太网PHY。在发送数据时,收到MAC数据,把并行数据转化为串行流数据,再按照物理层的编码规则编码,再变为模拟信号发送数据。收数据时流程反之。PHY还有个重要的功能是实现CSMA/CD的部分功能。

PHY和MAC之间的关系是PCI总线接MAC总线,MAC接PHY,PHY接网线。

在以太网网卡驱动中,完全可以将PHY芯片的驱动抽象,做成通用接口。(IEEE802.3定义PHY芯片地址0-15寄存器的功能,地址16-31寄存器留给芯片制造商自由定义)。

2.技术实现

2.1 PHY驱动目录

PHY芯片驱动在SylixOS的Base中已经给出,如图 3.1所示。

图 3.1 PHY驱动目录

SylixOS提供的PHY芯片驱动能支持10Mb,100Mb,1000Mb的链接能力。

2.2 PHY驱动框架

PHY驱动大致流程为:

初始化组件库(信号量,定时器)。

选择自动查找/指定查找PHY设备。

选择自动协商/指定链接模式。

启用定时器每隔一段时间查询链接状态。

如图 3.2所示。

图 3.2 PHY驱动框架

在网卡驱动中,先对程序清单 3.1进行传参,再调用API_MiiPhyInit接口就能完成PHY芯片初始化。

程序清单 3.1传参

    pmiidrv->MIID_phydev.PHY_pPhyDrvFunc->PHYF_pfuncWrite    = (FUNCPTR)__miiPhyWrite;
    pmiidrv->MIID_phydev.PHY_pPhyDrvFunc->PHYF_pfuncRead     = (FUNCPTR)__miiPhyRead;
    pmiidrv->MIID_phydev.PHY_pPhyDrvFunc->PHYF_pfuncLinkDown = (FUNCPTR)__miiLinkStatus;
    pmiidrv->MIID_phydev.PHY_pvMacDrv       = pmiidrv;
    pmiidrv->MIID_phydev.PHY_ucPhyAddr      = ENET_PHYADDR;
    pmiidrv->MIID_phydev.PHY_uiPhyID        = FEC_ENET_PHYID;
    pmiidrv->MIID_phydev.PHY_uiPhyIDMask    =0x00000000;               /*  同系列芯片不同信号识别    */
    pmiidrv->MIID_phydev.PHY_uiTryMax       = 100;
    pmiidrv->MIID_phydev.PHY_uiLinkDelay    = 100;                      /*  延时100毫秒自动协商过程   */
    pmiidrv->MIID_phydev.PHY_uiPhyFlags     = MII_PHY_AUTO |            /*  自动协商标志              */
                                              MII_PHY_FD   |            /*  全双工模式                */
                                              MII_PHY_100  |            /*  100Mbit                   */
                                              MII_PHY_10   |            /*  10Mbit                    */
                                              MII_PHY_HD   |            /*  半双工模式                */
                                              MII_PHY_MONITOR;         /*  启用自动监视功能          */

MAC能对PHY芯片进行读写操作(miiPhyWrite函数,miiPhyRead函数)。

链接状态变化函数(miiLinkStatus函数,打印链接信息并进行相关操作)。

控制参数传参(PHY驱动会根据传入参数进行不同操作,如是否开启自动协商,选择速度/双工模式,开启自动监视功能)。

2.3 具体实现

2.3.1 API_MiiPhyInit函数实现

API_MiiPhyInit函数会根据传入参数分别执行初始化组件库,查找PHY设备,设置链接能力。

PHY驱动提供链表将有效PHY设备加入到MII链表,能对多个PHY芯片进行操作。

如程序清单 3.2所示。

程序清单 3.2 API_MiiPhyInit函数实现

INTAPI_MiiPhyInit (PHY_DEV *pPhyDev)
{
……
    if (API_MiiLibInit() == MII_ERROR) {
        return  (MII_ERROR);
    }
    if (pPhyDev->PHY_ucPhyAddr == 0) {                                  /*  Auto scan phydevice        */
        if (API_MiiPhyScan(pPhyDev) == MII_ERROR) {
            _DebugHandle(__ERRORMESSAGE_LEVEL, "can notfind phy device.\r\n");
            return  (MII_ERROR);
        }
    } else {                                                           /*  Test specific phy device    */
        if (API_MiiPhyProbe(pPhyDev) != MII_OK) {
            MII_DEBUG_ADDR("can notfind phy device. addr[%02x]\r\n",
                          pPhyDev->PHY_ucPhyAddr);
            return  (MII_ERROR);
        }
        if (API_MiiPhyDiagnostic(pPhyDev) != MII_OK) {
            return  (MII_ERROR);
        }
    }
……
    if (API_MiiPhyLinkSet(pPhyDev) != MII_OK) {
        MII_DEBUG_ADDR("mii:found phy [%02x], but Link-Down.\r\n",
                      pPhyDev->PHY_ucPhyAddr);
    }
      usPhyStatus = pPhyDev->PHY_usPhyStatus;                                 /* Remember Link Status         */
                                                                        /* Get The New Status          */
……
    return  (iRet);                                                     /*  MII_ERROR orMII_OK         */
}

2.3.2 API_MiiLibInit函数实现

API_MiiLibInit函数初始化组件库。大致为创建信号量,定时器,并开启定时器,检测链接能力。(__miiPhyMonitor函数主要读取PHY芯片状态,更新状态信息)。

如程序清单 3.3所示。

程序清单 3.3 API_MiiLibInit函数实现

INTAPI_MiiLibInit (VOID)
{
 ……
    _G_hMiiMSem = API_SemaphoreMCreate("mii_lock", LW_PRIO_DEF_CEILING,
                                       LW_OPTION_WAIT_PRIORITY | LW_OPTION_DELETE_SAFE |
                                       LW_OPTION_INHERIT_PRIORITY | LW_OPTION_OBJECT_GLOBAL,
                                       LW_NULL);                       /* Create MIIMutex Semaphore   */
    _G_hMiiTimer = API_TimerCreate("mii_timer", LW_OPTION_ITIMER | LW_OPTION_OBJECT_GLOBAL, LW_NULL); 
    if (_G_hMiiTimer == 0) {                                            /* Create mii timer             */
        return  (MII_ERROR);
    }
……
    if (API_TimerStart(_G_hMiiTimer,                                    /* Start Phy Monitor            */
                      (MII_LINK_CHK_DELAY * LW_TICK_HZ),
                      LW_OPTION_AUTO_RESTART,
                      (PTIMER_CALLBACK_ROUTINE)__miiPhyMonitor,
                      LW_NULL)) {
        API_SemaphoreMDelete(&_G_hMiiMSem);
        return  (MII_ERROR);
    }
……
    return  (MII_OK);
}

2.3.3 API_MiiPhyScan函数实现

API_MiiPhyScan函数自动查找PHY设备。大致为从0-32对所有PHY设备地址进行查找,若存在设备,测试PHY是否有效。

如程序清单 3.4所示。

程序清单 3.4 API_MiiPhyScan函数实现

INTAPI_MiiPhyScan (PHY_DEV *pPhyDev)
{
……
    for (i = 0; i < MII_MAX_PHY_NUM; i++, pPhyDev->PHY_ucPhyAddr++) {
        iRet = API_MiiPhyProbe(pPhyDev);
        if (iRet != MII_OK) {
            continue;
        }
        if (API_MiiPhyDiagnostic(pPhyDev) != MII_OK) {
            return  (MII_ERROR);
        }
        return  (MII_OK);                                               /* Found aValid PHY            */
    }
    return  (MII_PHY_NULL);
}

2.3.4 API_MiiPhyProbe,API_MiiPhyDiagnostic函数实现

API_MiiPhyProbe函数检测PHY设备是否存在,大致为读取PHY寄存器ID,进行匹配,返回是否成功。如程序清单 3.5所示。

程序清单 3.5     API_MiiPhyProbe函数实现

INTAPI_MiiPhyProbe (PHY_DEV *pPhyDev)
{
……
    if (MII_READ(pPhyDev, MII_PHY_ID1_REG, &usID1) == MII_ERROR) {
        return  (MII_ERROR);
    }
    if (MII_READ(pPhyDev, MII_PHY_ID2_REG, &usID2) == MII_ERROR) {
        return  (MII_ERROR);
    }
    uiPhyID = usID1 | (usID2 << 16);
    if ((pPhyDev->PHY_uiPhyID & pPhyDev->PHY_uiPhyIDMask) !=
                     (uiPhyID & pPhyDev->PHY_uiPhyIDMask)) {
        return  (MII_PHY_NULL);                                         /* phyId不匹配                  */
    }
    return  (MII_OK);                                                  /* phyId匹配                    */
}

API_MiiPhyDiagnostic函数测试PHY是否有效,具体为复位PHY是否成功,检测PHY是否处于物理隔离状态。如程序清单 3.6所示。

程序清单 3.6 API_MiiPhyDiagnostic函数实现

INTAPI_MiiPhyDiagnostic (PHY_DEV *pPhyDev)
{
……
    iRet = MII_WRITE(pPhyDev, ucRegAddr, usData);                      /* Reset thePHY                */
    if (iRet != MII_OK) {
        return  (MII_ERROR);
    }
    for (i = 0; i < pPhyDev->PHY_uiTryMax; i++) {
        API_TimeMSleep(pPhyDev->PHY_uiLinkDelay);
        if (MII_READ(pPhyDev, ucRegAddr, &usData) == MII_ERROR) {
            return  (MII_ERROR);
        }
}
……
    usData = MII_CTRL_NORM_EN;                                          /* re-enable the chip           */
    if (MII_WRITE(pPhyDev, ucRegAddr, usData) == MII_ERROR) {
        return  (MII_ERROR);
    }
    for (i = 0; i < pPhyDev->PHY_uiTryMax; i++) {
        API_TimeMSleep(pPhyDev->PHY_uiLinkDelay);
        if (MII_READ(pPhyDev, ucRegAddr, &usData) == MII_ERROR) {
            return  (MII_ERROR);
        }
    return  (MII_OK);
}

2.3.5 API_MiiPhyLinkSet函数实现

API_MiiPhyLinkSet函数设置PHY链接模式。如程序清单 3.7所示。

程序清单 3.7 API_MiiPhyLinkSet函数实现

INTAPI_MiiPhyLinkSet (PHY_DEV *pPhyDev)
{
……
    if (__miiAbilFlagUpdate(pPhyDev) == MII_ERROR) {
        return  (MII_ERROR);
    }
……
    iRet = API_MiiPhyModeSet(pPhyDev);
……
    return  (MII_OK);
}

API_MiiPhyModeSet函数根据参数选择自动协商/手动设置。

如程序清单 3.8所示。

程序清单 3.8 API_MiiPhyModeSet函数实现

INTAPI_MiiPhyModeSet (PHY_DEV *pPhyDev)
{
    if (pPhyDev->PHY_uiPhyFlags & MII_PHY_AUTO) {                      /* AutoNegotiationenabled      */
       if (__miiAutoNegotiate(pPhyDev) == MII_OK) {
           return   (MII_OK);
       }
    } else {                                                           /* 未开启自动协商功能           */
        if (__miiModeForce(pPhyDev) == MII_OK) {
            if (__miiFlagsHandle(pPhyDev) == MII_OK) {                 /* handlesome flags            */
                return  (MII_OK);
            }
        }
    }
    return  (MII_ERROR);
}

__miiAutoNegotiate函数进行自动协商并检查协商是否成功。__miiBasicCheck用于检查是否link up/remote fault。如程序清单 3.9所示。

程序清单 3.9 __miiAutoNegotiate函数实现

staticINT__miiAutoNegotiate (PHY_DEV *pPhyDev)
{
……
    /*
     * start theauto-negotiation process: return
     * only in caseof fatal error.
     */
   iRet = __miiAutoNegStart(pPhyDev);
……
    /* check the negotiation was successful */
    if (!(pPhyDev->PHY_uiPhyFlags & MII_PHY_NWAIT_STAT)) {
        if (__miiAnCheck(pPhyDev) == MII_OK) {
            return  (MII_OK);
        }
    }
    
    return  (MII_ERROR);
}

__miiAutoNegStart函数开始自动协商。具体为开始自动协商并根据传入参数选择等待自动协商结束/立即返回。如程序清单 3.10所示。

程序清单 3.10 __miiAutoNegStart函数实现

staticINT__miiAutoNegStart (PHY_DEV *pPhyDev)
{
……
    /*
     * restart the auto-negotiation process
     */
    ucRegAddr = MII_CTRL_REG;
    usData    = (MII_CTRL_RESTART | MII_CTRL_AUTO_EN);
    if (MII_WRITE(pPhyDev, ucRegAddr, usData) != MII_OK) {
        return  (MII_ERROR);
    }
    /*
     * let‘s check the PHY status forcompletion
     */
    if (!(pPhyDev->PHY_uiPhyFlags & MII_PHY_NWAIT_STAT)) {
        ucRegAddr = MII_STAT_REG;
        do {                                                           /* spin until it is done        */
            API_TimeMSleep(pPhyDev->PHY_uiLinkDelay);
            if (i++ == pPhyDev->PHY_uiTryMax)
                break;
            if (MII_READ(pPhyDev, ucRegAddr, &usPhyStatus) != MII_OK) {
                return  (MII_ERROR);
            }
        } while ((usPhyStatus & MII_SR_AUTO_NEG) != MII_SR_AUTO_NEG);
……
    return  (MII_OK);
}

2.3.6 __miiModeForce函数实现

__miiModeForce函数根据传入参数,设成指定链接模式(若多个参数,指定最高链接模式)。如程序清单 3.11所示。

程序清单 3.11 __miiModeForce函数实现

staticINT__miiModeForce (PHY_DEV *pPhyDev)
{
……                                                                    /* 100Mb/s full                 */
    if (MII_PHY_FLAGS_JUDGE(MII_PHY_100) && MII_PHY_FLAGS_JUDGE(MII_PHY_FD)) {
        usData = MII_CTRL_NORM_EN;
        usData |= MII_CTRL_100;
        usData |= MII_CTRL_FDX;
        __miiForceAttempt(pPhyDev, usData);
        MII_PHY_ABILITY_FLAGS_SET(MII_PHY_100 | MII_PHY_FD);
        return  (MII_OK);
    }
……
    return  (MII_ERROR);
}

__miiForceAttempt函数设成指定链接模式,并检查PHY状态。__miiBasicCheck函数用于检查PHY状态是否正确。如程序清单 3.12所示。

程序清单 3.12 __miiForceAttempt函数实现

staticINT__miiForceAttempt (PHY_DEV *pPhyDev, UINT16  usData)
{ 
    if (MII_WRITE(pPhyDev, MII_CTRL_REG, usData) != MII_OK) {
        return  (MII_ERROR);
    }
    if (__miiBasicCheck(pPhyDev) != MII_OK) {
        return  (MII_ERROR);
    }
    return  (MII_OK);
}

2.3.7 __miiPhyMonitor函数实现

__miiPhyMonitor函数持续监测PHY状态。具体为每隔一段时间检测PHY链接状态并更新状态信息,当检测到为失去链接时调用PHYF_pfuncLinkDown函数(实际为之前的miiLinkStatus函数)。如程序清单 3.13所示。

程序清单 3.13 __miiPhyMonitor函数实现

staticINT__miiPhyMonitor (VOID)
{
……
            iRet = MII_READ(pPhyDev, MII_STAT_REG, &usPhyStatus);
            if (iRet == MII_ERROR) {
                goto    __mii_monitor_exit;
            }
            /*
             * is the PHY‘s status linkchanged?
             */
            if ((pPhyDev->PHY_usPhyStatus & MII_SR_LINK_STATUS) !=
                (usPhyStatus & MII_SR_LINK_STATUS)) {
                if (usPhyStatus & MII_SR_LINK_STATUS) {
                    if (pPhyDev->PHY_uiPhyFlags & MII_PHY_AUTO) {
                        __miiAbilFlagUpdate(pPhyDev);
                        __miiPhyUpdate(pPhyDev);
                    } else {
                        __miiFlagsHandle(pPhyDev);
                    }
                }
                if (pPhyDev->PHY_pPhyDrvFunc->PHYF_pfuncLinkDown != LW_NULL) {
                    API_NetJobAdd((VOIDFUNCPTR)(pPhyDev->PHY_pPhyDrvFunc->PHYF_pfuncLinkDown),
                                  (PVOID)(pPhyDev->PHY_pvMacDrv), 0, 0, 0, 0,0);
                    pPhyDev->PHY_usPhyStatus = usPhyStatus;
                }
……
    return  (iRet);
}

2.4 实际运用

__phyInit函数为在实际网卡驱动中编写的PHY芯片初始化驱动程序。具体为调用miiDrvInit函数写入参数,调用API_MiiPhyInit函数进行PHY芯片初始化。

如程序清单 3.14所示。

程序清单 3.14 __phyInit函数实现

staticINT__phyInit (struct netdev  *pNetDev)
{
……
    pEnet    = &_G_enetInfo;
    pnetdev = &pEnet->ENET_netdev;
    pmiidrv = miiDrvInit();
    if (!pmiidrv) {
        return  (PX_ERROR);
    }
    pEnet->ENET_miidrv = pmiidrv;
    pmiidrv->MIID_enet = pEnet;
    pnetdev->priv      = (PVOID)pEnet;
    iRet = API_MiiPhyInit(&(pEnet->ENET_miidrv->MIID_phydev));
    if (iRet == MII_OK) {
        pEnet->ENET_iMiiInit = 1;
    }
    return  (ERROR_NONE);
}

miiDrvInit函数将API_MiiPhyInit中需要用的参数进行传参。封装MAC对PHY的读写函数,指定工作模式。如程序清单 3.15所示。

程序清单 3.15 miiDrvInit函数实现

MII_DRV  *miiDrvInit (VOID)
{
……
    pmiidrv->MIID_phydev.PHY_pPhyDrvFunc->PHYF_pfuncWrite = (FUNCPTR)miiPhyWrite;
    pmiidrv->MIID_phydev.PHY_pPhyDrvFunc->PHYF_pfuncRead = (FUNCPTR)miiPhyRead;
    pmiidrv->MIID_phydev.PHY_pPhyDrvFunc->PHYF_pfuncLinkDown = (FUNCPTR)miiLinkStatus;
    pmiidrv->MIID_phydev.PHY_pvMacDrv       = pmiidrv;
    pmiidrv->MIID_phydev.PHY_ucPhyAddr      = ENET_PHYADDR;
    pmiidrv->MIID_phydev.PHY_uiPhyID        = FEC_ENET_PHYID;
    pmiidrv->MIID_phydev.PHY_uiPhyIDMask    =0x00000000;               /*  同系列芯片不同信号识别    */
    pmiidrv->MIID_phydev.PHY_uiTryMax       = 100;
    pmiidrv->MIID_phydev.PHY_uiLinkDelay    = 100;                      /*  延时100毫秒自动协商过程   */
    pmiidrv->MIID_phydev.PHY_uiPhyFlags     = MII_PHY_AUTO |            /*  自动协商标志              */
                                              MII_PHY_FD   |            /*  全双工模式                */
                                              MII_PHY_100  |            /*  100Mbit                   */
                                              MII_PHY_10   |            /*  10Mbit                    */
                                              MII_PHY_HD   |            /*  半双工模式                */
                                              MII_PHY_MONITOR;          /*  启用自动监视功能          */
    return  (pmiidrv);
}
时间: 2024-10-01 00:55:49

SylixOS MII总线层解析的相关文章

SylixOS DSP upgrade命令解析

SylixOS DSP upgrade命令解析--SylixOS DSP6678平台下升级BSP一.适用范围 本升级方案,针对TI官方评估板(TMDSEVM6678LE),主要介绍如何将SylixOS BSP固化到Nor Flash中. 二.背景 1.upgrade命令介绍 在SylixOS DSP6678镜像烧录过程中, 需要使用TI CCS开发环境的调试方式对镜像烧录,单次烧录过程繁琐,需要切换启动模式.借助仿真器调试.传输镜像,不利于开发和产品阶段更新SylixOS镜像.因此,在Sylix

SylixOS 共用中断号机制

1.原理概述 SylixOS开发人员在编写中断驱动时经常会遇到多个中断源共用一个中断号的情况,但在驱动中为了保证代码独立性,各个外设的中断服务函数应该放在各自的C文件中编写,用统一的中断服务函数是不合理的.为了适应这种情况,SylixOS支持队列类型中断向量,即SylixOS内核将同一中断向量号的多个中断服务函数链接成队列,执行时依次执行. 2.技术实现 2.1应用举例 下面以at91sam9x25处理器为例,该处理器的调试串口,tick时钟等外设共用1号中断向量.如图2-1所示. 图2-1 中

SylixOS 中断系统分析

SylixOS中断系统分析 中断向量表 在SylixOS中,系统默认存在一张大小为256(可以手动配置)的中断向量表,用于管理SylixOS中的每一个中断向量.该向量表存在于k_globalvar.h文件中,其定义格式如程序清单1-1所示. 程序清单1-1 系统中断向量表定义 /*********************************************************************************************************   系统

查询软解析,硬解析百分比

--查询Oracle数据库的软解析硬解析视图 SQL> select * from v$sysstat where name like '%parse%'; STATISTIC# NAME                                CLASS      VALUE    STAT_ID ---------- ------------------------------ ---------- ---------- ---------- 264 ADG parselock X g

Qt高级——D-Bus快速入门

Qt高级--D-Bus快速入门 一.D-Bus简介 1.D-Bus简介 D-Bus是Desktop Bus的缩写,是针对桌面环境优化的IPC(InterProcess Communication)机制,用于进程间的通信或进程与内核的通信.D-Bus是为Linux系统开发的进程间通信(IPC)和远程过程调用(RPC)机制,使用统一的通信协议来代替现有的各种IPC解决方案.D-Bus允许系统级进程(如:打印机和硬件驱动服务)和普通用户进程进行通信.D-Bus使用一个快速的二进制消息传递协议,D-Bu

MSM8909+Android5.1.1键盘驱动------概述

采用SN7326带智能指扫描的键盘扩展芯片,通过I2C接口来读取其状态寄存器的值就可知道是单按键还是多按键按下,可知道具体是哪个按键按下.然后键盘驱动调用input_event()上报linux的扫描码,比如KEY_RIGHT,然后传递给android框架层,流程如下图: 图1 下面介绍要实现键盘驱动所涉及的主要方方面面 1.     Input子系统 Linux输入设备总类繁杂,常见的包括有按键.键盘.触摸屏.鼠标.摇杆等等,他们本身就是字符设备,而linux内核将这些设备的共同性抽象出来,简

基于platform驱动模型的LED驱动

上一篇博文<platform设备驱动框架搭建分析>主要是根据内核源码来分析platform驱动模型工作的原理,在实际的驱动开发中如何使用Linux的这么一种模型来管理这种类型的设备呢?把tq2440开发板上的LED1当做是平台设备注册到Linux系统中,让系统可以用这种platform驱动来管理他. ①总线层:代码不用我们自己去写,内核已经提供了 ②设备层:向platform总线层注册硬件相关的资源,一般是寄存器地址.内存空间.中断号(序号的一种代表)等等 led_dev.c #include

I2C驱动详解

I2C讲解: 在JZ2440开发板上,I2C是由两条数据线构成的SCL,SDA:SCL作为时钟总线,SDA作为数据总线:两条线上可挂载I2C设备,如:AT24C08 两条线连接ARM9 I2C控制器,通过控制来控制I2C设备的识别设备地址.读.写操作:如图所示 从中所知:I2C线上可以挂载很多个I2C设备:挂载简单,只需要一根数据线和一根时钟线就可以挂载上去,通过地址来去别每个设备的区别: I2C操作: 对I2C操作主要思想为:1.找到设备  2.进行读写操作 主要原理为: 1.发送开始信号S

wydomain

目标系统信息收集组件,完全模块化,脚本均可拆可并.可合可分的使用! 运行流程 利用FOFA插件获取兄弟域名,并透视获取到的子域名相关二级域名.IP信息 检查域名和兄弟域名是否存在域传送漏洞,存在就遍历zone记录,将结果集推到wydomians数据组 获取可以获取的公开信息 MX.DNS.SOA记录 子域名字典暴力穷举域名(60000条字典[domain_default.csv]) 利用第三方API查询子域名(links.alexa.bing.google.sitedossier.netcraf