📄 ax88180.c
字号:
if (pax88180_local->JumboFlag == ENABLE_JUMBO) { PRINTK(DRIVER_MSG, "ax88180: Enable Jumbo Frame function.\n"); maccfg1_val |= RXJUMBO_EN | JUMBO_LEN_15K; global_dev->mtu = MAX_JUMBO_MTU; } break; case MEDIA_1000HALF: PRINTK(DRIVER_MSG, "ax88180: Set to 1000Mbps Half-duplex mode.\n"); pax88180_local->LineSpeed = SPEED_1000; pax88180_local->DuplexMode = DUPLEX_HALF; rxcfg_val = DEFAULT_RXCFG; maccfg0_val = DEFAULT_MACCFG0; maccfg1_val = GIGA_MODE_EN | DEFAULT_MACCFG1; global_dev->mtu = DEFAULT_ETH_MTU; break; case MEDIA_100FULL: PRINTK(DRIVER_MSG, "ax88180: Set to 100Mbps Full-duplex mode.\n"); pax88180_local->LineSpeed = SPEED_100; pax88180_local->DuplexMode = DUPLEX_FULL; rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG; maccfg0_val = SPEED100 | TXFLOW_ENABLE | DEFAULT_MACCFG0; maccfg1_val = RXFLOW_EN | FULLDUPLEX | DEFAULT_MACCFG1; global_dev->mtu = DEFAULT_ETH_MTU; break; case MEDIA_100HALF: PRINTK(DRIVER_MSG, "ax88180: Set to 100Mbps Half-duplex mode.\n"); pax88180_local->LineSpeed = SPEED_100; pax88180_local->DuplexMode = DUPLEX_HALF; rxcfg_val = DEFAULT_RXCFG; maccfg0_val = SPEED100 | DEFAULT_MACCFG0; maccfg1_val = DEFAULT_MACCFG1; global_dev->mtu = DEFAULT_ETH_MTU; break; case MEDIA_10FULL: PRINTK(DRIVER_MSG, "ax88180: Set to 10Mbps Full-duplex mode.\n"); pax88180_local->LineSpeed = SPEED_10; pax88180_local->DuplexMode = DUPLEX_FULL; rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG; maccfg0_val = TXFLOW_ENABLE | DEFAULT_MACCFG0; maccfg1_val = RXFLOW_EN | FULLDUPLEX | DEFAULT_MACCFG1; global_dev->mtu = DEFAULT_ETH_MTU; break; case MEDIA_10HALF: PRINTK(DRIVER_MSG, "ax88180: Set to 10Mbps Half-duplex mode.\n"); pax88180_local->LineSpeed = SPEED_10; pax88180_local->DuplexMode = DUPLEX_HALF; rxcfg_val = DEFAULT_RXCFG; maccfg0_val = DEFAULT_MACCFG0; maccfg1_val = DEFAULT_MACCFG1; global_dev->mtu = DEFAULT_ETH_MTU; break; } } else { PRINTK(INIT_MSG, "ax88180: The cable is disconnected!!\n"); /* Set to default media mode (1000FULL) */ pax88180_local->LineSpeed = SPEED_1000; pax88180_local->DuplexMode = DUPLEX_FULL; rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG; maccfg0_val = TXFLOW_ENABLE | DEFAULT_MACCFG0; maccfg1_val = GIGA_MODE_EN | RXFLOW_EN | FULLDUPLEX | DEFAULT_MACCFG1; if (pax88180_local->JumboFlag == ENABLE_JUMBO) { maccfg1_val |= RXJUMBO_EN | JUMBO_LEN_15K; global_dev->mtu = MAX_JUMBO_MTU; } } WRITE_MACREG(RXCFG, rxcfg_val); WRITE_MACREG(MACCFG0, maccfg0_val); WRITE_MACREG(MACCFG1, maccfg1_val); PRINTK(INIT_MSG, "ax88180: ax88180_meida_config end ..........\n"); return;}/* ***************************************************************************** * get_MarvellPHY_meida_mode() * * Get real media mode of Marvell 88E1111 PHY. * ***************************************************************************** */static void get_MarvellPHY_meida_mode(struct net_device *global_dev){ struct _AX88180_PRIVATE *pax88180_local; unsigned long m88_ssr; int i; pax88180_local = (struct _AX88180_PRIVATE *) global_dev->priv; PRINTK(INIT_MSG, "ax88180: get_MarvellPHY_meida_mode beginning ..........\n"); /* Get the real media mode */ for (i = 0; i < 200; i++) { READ_PHYREG(pax88180_local->PhyAddr, M88_SSR, m88_ssr); if (m88_ssr & SSR_MEDIA_RESOLVED_OK) { break; } mdelay(1); } READ_PHYREG(pax88180_local->PhyAddr, M88_SSR, m88_ssr); switch (m88_ssr & SSR_MEDIA_MASK) { default: case SSR_1000FULL: pax88180_local->RealMediaMode = MEDIA_1000FULL; break; case SSR_1000HALF: pax88180_local->RealMediaMode = MEDIA_1000HALF; break; case SSR_100FULL: pax88180_local->RealMediaMode = MEDIA_100FULL; break; case SSR_100HALF: pax88180_local->RealMediaMode = MEDIA_100HALF; break; case SSR_10FULL: pax88180_local->RealMediaMode = MEDIA_10FULL; break; case SSR_10HALF: pax88180_local->RealMediaMode = MEDIA_10HALF; break; } PRINTK(INIT_MSG, "ax88180: get_MarvellPHY_meida_mode end ..........\n"); return;}/* ***************************************************************************** * get_CicadaPHY_meida_mode() * * Get real media mode of CICADA CIS8201 PHY. * ***************************************************************************** */static void get_CicadaPHY_meida_mode(struct net_device *global_dev){ struct _AX88180_PRIVATE *pax88180_local; unsigned long tmp_regval; pax88180_local = (struct _AX88180_PRIVATE *) global_dev->priv; PRINTK(INIT_MSG, "ax88180: get_CicadaPHY_meida_mode beginning ..........\n"); READ_PHYREG(pax88180_local->PhyAddr, CIS_AUX_CTRL_STATUS, tmp_regval); switch (tmp_regval & CIS_MEDIA_MASK) { default: case CIS_1000FULL: pax88180_local->RealMediaMode = MEDIA_1000FULL; break; case CIS_1000HALF: pax88180_local->RealMediaMode = MEDIA_1000HALF; break; case CIS_100FULL: pax88180_local->RealMediaMode = MEDIA_100FULL; break; case CIS_100HALF: pax88180_local->RealMediaMode = MEDIA_100HALF; break; case CIS_10FULL: pax88180_local->RealMediaMode = MEDIA_10FULL; break; case CIS_10HALF: pax88180_local->RealMediaMode = MEDIA_10HALF; break; } PRINTK(INIT_MSG, "ax88180: get_CicadaPHY_meida_mode end ..........\n"); return;}/* ***************************************************************************** * ax88180_rx_handler() * * Handle packets received completion interrupt event. * ***************************************************************************** */static void ax88180_rx_handler(struct net_device *global_dev){ struct _AX88180_PRIVATE *pax88180_local; struct sk_buff *skb; unsigned char *rxdata;// unsigned long tmp_data; unsigned long rx_packet_len; unsigned int data_size;// unsigned int dword_count, byte_count; unsigned long rxcurt_ptr, rxbound_ptr, next_ptr; int i;// int j; pax88180_local = (struct _AX88180_PRIVATE *) global_dev->priv; PRINTK(RX_MSG, "ax88180: ax88180_rx_handler beginning ..........\n");// spin_lock_irq(&pax88180_local->lock); READ_MACREG(RXCURT, rxcurt_ptr); READ_MACREG(RXBOUND, rxbound_ptr); next_ptr = (rxbound_ptr + 1) & RX_PAGE_NUM_MASK; PRINTK(RX_MSG, "ax88180: RX original RXBOUND=0x%08lx, RXCURT=0x%08lx\n", rxbound_ptr, rxcurt_ptr); while (next_ptr != rxcurt_ptr) { START_READ_RXBUFF; READ_RXBUF(rx_packet_len); if ( (rx_packet_len == 0) || (rx_packet_len > MAX_RX_SIZE) ) { pax88180_local->stats.rx_errors++; STOP_READ_RXBUFF; RESET_MAC; PRINTK(ERROR_MSG, "ax88180: Invalid Rx packet length!! (len=0x%08lx)\n", rx_packet_len); PRINTK(ERROR_MSG, "ax88180: RX RXBOUND=0x%08lx, RXCURT=0x%08lx\n", rxbound_ptr, rxcurt_ptr); PRINTK(RX_MSG, "ax88180: ax88180_rx_handler fail end ..........\n"); return; } data_size = (unsigned int)rx_packet_len; rxbound_ptr += (((data_size + 0xF) & 0xFFF0) >> 4) + 1; rxbound_ptr &= RX_PAGE_NUM_MASK; skb = dev_alloc_skb(data_size + 2); if (skb == NULL) { pax88180_local->stats.rx_dropped++; STOP_READ_RXBUFF; PRINTK(ERROR_MSG, "ax88180: No available memory space. Dropping RX packets!!\n"); PRINTK(RX_MSG, "ax88180: ax88180_rx_handler fail end ..........\n"); return; } skb->data = skb->head; skb->tail = skb->head; skb_reserve(skb, 2); skb->dev = global_dev; rxdata = skb_put(skb, data_size); memcpy (pax88180_local->rx_buf, (void *)(Log_MemBase + RXBUFFER_START), (data_size + 4 - data_size%4)); memcpy (rxdata, pax88180_local->rx_buf, data_size);/* dword_count = data_size >> 2; byte_count = data_size & 0x3; for (i = 0; i < dword_count; i++) { READ_RXBUF(tmp_data); *((unsigned long *)rxdata + i)= tmp_data; } if (byte_count != 0) { READ_RXBUF(tmp_data); for (j = 0; j < byte_count; j++) { *(rxdata + (dword_count * 4) + j) = (unsigned char)(tmp_data >> (j *8)); } }*/ STOP_READ_RXBUFF; skb->protocol = eth_type_trans(skb, global_dev); netif_rx(skb); global_dev->last_rx = jiffies; pax88180_local->stats.rx_packets++; pax88180_local->stats.rx_bytes += data_size; WRITE_MACREG(RXBOUND, rxbound_ptr); PRINTK(DEBUG_MSG, "ax88180: Rx data size = 0x%x\n", data_size); PRINTK(DEBUG_MSG, "["); for (i = 0; i < data_size; i++) { PRINTK(DEBUG_MSG, "0x%02x ", *(rxdata + i)); if ( (i & 0xF) == 0xF ) PRINTK(DEBUG_MSG, "\n"); } PRINTK(DEBUG_MSG, "]\n"); READ_MACREG(RXCURT, rxcurt_ptr); READ_MACREG(RXBOUND, rxbound_ptr); next_ptr = (rxbound_ptr + 1) & RX_PAGE_NUM_MASK; PRINTK(RX_MSG, "ax88180: RX updated RXBOUND=0x%08lx, RXCURT=0x%08lx\n", rxbound_ptr, rxcurt_ptr); } if (pax88180_local->rxbuf_overflow_count > 0) pax88180_local->rxbuf_overflow_count--;// spin_unlock_irq(&pax88180_local->lock); PRINTK(RX_MSG, "ax88180: ax88180_rx_handler end ..........\n"); return;}/* ***************************************************************************** * ax88180_tx_handler() * * Handle packets transmitted completion interrupt event. * ***************************************************************************** */static void ax88180_tx_handler(struct net_device *global_dev){ struct _AX88180_PRIVATE *pax88180_local; pax88180_local = (struct _AX88180_PRIVATE *) global_dev->priv; PRINTK(TX_MSG, "ax88180: ax88180_tx_handler beginning ..........\n"); /* Inform upper layer to send next queued packets now */ netif_wake_queue(global_dev); PRINTK(TX_MSG, "ax88180: ax88180_tx_handler end ..........\n"); return;}#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)/* ***************************************************************************** * ax88180_ioctl() * * Handle the ioctl commands like ethtool. * ***************************************************************************** */static int ax88180_ioctl(struct net_device *global_dev, struct ifreq *rq, int cmd){ PRINTK(OTHERS_MSG, "ax88180: ax88180_ioctl beginning ..........\n"); switch(cmd) { case SIOCETHTOOL: return ax88180_ethtool_ioctl(global_dev, (void*)rq->ifr_data); default: return -EOPNOTSUPP; } PRINTK(OTHERS_MSG, "ax88180: ax88180_ioctl end ..........\n");}/* ***************************************************************************** * ax88180_ethtool_ioctl() * * Handle the ethtool ioctl command. * ***************************************************************************** */static int ax88180_ethtool_ioctl(struct net_device *global_dev, void *useraddr){ struct _AX88180_PRIVATE *pax88180_local; u32 ethcmd; pax88180_local = (struct _AX88180_PRIVATE *) global_dev->priv; PRINTK(OTHERS_MSG, "ax88180: ax88180_ethtool_ioctl beginning ..........\n"); if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) return -EFAULT; switch (ethcmd) { case ETHTOOL_GDRVINFO: { struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; strcpy(info.driver, DRV_NAME); strcpy(info.version, DRV_VERSION); if (copy_to_user(useraddr, &info, sizeof(info))) return -EFAULT; return 0; } case ETHTOOL_GSET: { struct ethtool_cmd ecmd = { ETHTOOL_GSET }; spin_lock_irq(&pax88180_local->lock); mii_ethtool_gset(&pax88180_local->mii_if, &ecmd); spin_unlock_irq(&pax88180_local->lock); if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) return -EFAULT; return 0; } case ETHTOOL_SSET: { int r; struct ethtool_cmd ecmd; if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) return -EFAULT; spin_lock_irq(&pax88180_local->lock); r = mii_ethtool_sset(&pax88180_local->mii_if, &ecmd); spin_unlock_irq(&pax88180_local->lock); return r; } case ETHTOOL_NWAY_RST: { return mii_nway_restart(&pax88180_local->mii_if); } case ETHTOOL_GLINK: { struct ethtool_value edata = {ETHTOOL_GLINK}; edata.data = mii_link_ok(&pax88180_local->mii_if); if (copy_to_user(useraddr, &edata, sizeof(edata))) return -EFAULT; return 0; } default: break; } PRINTK(OTHERS_MSG, "ax88180: ax88180_ethtool_ioctl end ..........\n"); return -EOPNOTSUPP;}/* ***************************************************************************** * mdio_read() * * * ***************************************************************************** */static int mdio_read(struct net_device *global_dev, int phy_id, int regaddr){ unsigned int regval; READ_PHYREG(phy_id, regaddr, regval); PRINTK(DEBUG_MSG, "ax88180: mdio_read regval=0x%04x\n", regval); return regval;}/* ***************************************************************************** * mdio_write() * * * ***************************************************************************** */static void mdio_write(struct net_device *global_dev, int phy_id, int regaddr, int regval){ WRITE_PHYREG(phy_id, (unsigned long)regaddr, (unsigned long)regval); //allan9 add for debugging READ_PHYREG(phy_id, regaddr, regval); PRINTK(DEBUG_MSG, "ax88180: mdio_write regval=0x%04x\n", regval); return;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -