📄 via-velocity.h
字号:
* the rest of the logic from the result of sleep/wakeup */inline static void mac_wol_reset(struct mac_regs * regs){ /* Turn off SWPTAG right after leaving power mode */ BYTE_REG_BITS_OFF(STICKHW_SWPTAG, ®s->STICKHW); /* clear sticky bits */ BYTE_REG_BITS_OFF((STICKHW_DS1 | STICKHW_DS0), ®s->STICKHW); BYTE_REG_BITS_OFF(CHIPGCR_FCGMII, ®s->CHIPGCR); BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, ®s->CHIPGCR); /* disable force PME-enable */ writeb(WOLCFG_PMEOVR, ®s->WOLCFGClr); /* disable power-event config bit */ writew(0xFFFF, ®s->WOLCRClr); /* clear power status */ writew(0xFFFF, ®s->WOLSRClr);}/* * Header for WOL definitions. Used to compute hashes */typedef u8 MCAM_ADDR[ETH_ALEN];struct arp_packet { u8 dest_mac[ETH_ALEN]; u8 src_mac[ETH_ALEN]; u16 type; u16 ar_hrd; u16 ar_pro; u8 ar_hln; u8 ar_pln; u16 ar_op; u8 ar_sha[ETH_ALEN]; u8 ar_sip[4]; u8 ar_tha[ETH_ALEN]; u8 ar_tip[4];} __attribute__ ((__packed__));struct _magic_packet { u8 dest_mac[6]; u8 src_mac[6]; u16 type; u8 MAC[16][6]; u8 password[6];} __attribute__ ((__packed__));/* * Store for chip context when saving and restoring status. Not * all fields are saved/restored currently. */struct velocity_context { u8 mac_reg[256]; MCAM_ADDR cam_addr[MCAM_SIZE]; u16 vcam[VCAM_SIZE]; u32 cammask[2]; u32 patcrc[2]; u32 pattern[8];};/* * MII registers. *//* * Registers in the MII (offset unit is WORD) */#define MII_REG_BMCR 0x00 // physical address#define MII_REG_BMSR 0x01 //#define MII_REG_PHYID1 0x02 // OUI#define MII_REG_PHYID2 0x03 // OUI + Module ID + REV ID#define MII_REG_ANAR 0x04 //#define MII_REG_ANLPAR 0x05 //#define MII_REG_G1000CR 0x09 //#define MII_REG_G1000SR 0x0A //#define MII_REG_MODCFG 0x10 //#define MII_REG_TCSR 0x16 //#define MII_REG_PLED 0x1B //// NS, MYSON only#define MII_REG_PCR 0x17 //// ESI only#define MII_REG_PCSR 0x17 //#define MII_REG_AUXCR 0x1C //// Marvell 88E1000/88E1000S#define MII_REG_PSCR 0x10 // PHY specific control register//// Bits in the BMCR register//#define BMCR_RESET 0x8000 //#define BMCR_LBK 0x4000 //#define BMCR_SPEED100 0x2000 //#define BMCR_AUTO 0x1000 //#define BMCR_PD 0x0800 //#define BMCR_ISO 0x0400 //#define BMCR_REAUTO 0x0200 //#define BMCR_FDX 0x0100 //#define BMCR_SPEED1G 0x0040 ////// Bits in the BMSR register//#define BMSR_AUTOCM 0x0020 //#define BMSR_LNK 0x0004 ////// Bits in the ANAR register//#define ANAR_ASMDIR 0x0800 // Asymmetric PAUSE support#define ANAR_PAUSE 0x0400 // Symmetric PAUSE Support#define ANAR_T4 0x0200 //#define ANAR_TXFD 0x0100 //#define ANAR_TX 0x0080 //#define ANAR_10FD 0x0040 //#define ANAR_10 0x0020 ////// Bits in the ANLPAR register//#define ANLPAR_ASMDIR 0x0800 // Asymmetric PAUSE support#define ANLPAR_PAUSE 0x0400 // Symmetric PAUSE Support#define ANLPAR_T4 0x0200 //#define ANLPAR_TXFD 0x0100 //#define ANLPAR_TX 0x0080 //#define ANLPAR_10FD 0x0040 //#define ANLPAR_10 0x0020 ////// Bits in the G1000CR register//#define G1000CR_1000FD 0x0200 // PHY is 1000-T Full-duplex capable#define G1000CR_1000 0x0100 // PHY is 1000-T Half-duplex capable//// Bits in the G1000SR register//#define G1000SR_1000FD 0x0800 // LP PHY is 1000-T Full-duplex capable#define G1000SR_1000 0x0400 // LP PHY is 1000-T Half-duplex capable#define TCSR_ECHODIS 0x2000 //#define AUXCR_MDPPS 0x0004 //// Bits in the PLED register#define PLED_LALBE 0x0004 //// Marvell 88E1000/88E1000S Bits in the PHY specific control register (10h)#define PSCR_ACRSTX 0x0800 // Assert CRS on Transmit#define PHYID_CICADA_CS8201 0x000FC410UL#define PHYID_VT3216_32BIT 0x000FC610UL#define PHYID_VT3216_64BIT 0x000FC600UL#define PHYID_MARVELL_1000 0x01410C50UL#define PHYID_MARVELL_1000S 0x01410C40UL#define PHYID_REV_ID_MASK 0x0000000FUL#define PHYID_GET_PHY_REV_ID(i) ((i) & PHYID_REV_ID_MASK)#define PHYID_GET_PHY_ID(i) ((i) & ~PHYID_REV_ID_MASK)#define MII_REG_BITS_ON(x,i,p) do {\ u16 w;\ velocity_mii_read((p),(i),&(w));\ (w)|=(x);\ velocity_mii_write((p),(i),(w));\} while (0)#define MII_REG_BITS_OFF(x,i,p) do {\ u16 w;\ velocity_mii_read((p),(i),&(w));\ (w)&=(~(x));\ velocity_mii_write((p),(i),(w));\} while (0)#define MII_REG_BITS_IS_ON(x,i,p) ({\ u16 w;\ velocity_mii_read((p),(i),&(w));\ ((int) ((w) & (x)));})#define MII_GET_PHY_ID(p) ({\ u32 id;\ velocity_mii_read((p),MII_REG_PHYID2,(u16 *) &id);\ velocity_mii_read((p),MII_REG_PHYID1,((u16 *) &id)+1);\ (id);})/* * Inline debug routine */enum velocity_msg_level { MSG_LEVEL_ERR = 0, //Errors that will cause abnormal operation. MSG_LEVEL_NOTICE = 1, //Some errors need users to be notified. MSG_LEVEL_INFO = 2, //Normal message. MSG_LEVEL_VERBOSE = 3, //Will report all trival errors. MSG_LEVEL_DEBUG = 4 //Only for debug purpose.};#ifdef VELOCITY_DEBUG#define ASSERT(x) { \ if (!(x)) { \ printk(KERN_ERR "assertion %s failed: file %s line %d\n", #x,\ __FUNCTION__, __LINE__);\ BUG(); \ }\}#define VELOCITY_DBG(p,args...) printk(p, ##args)#else#define ASSERT(x)#define VELOCITY_DBG(x)#endif#define VELOCITY_PRT(l, p, args...) do {if (l<=msglevel) printk( p ,##args);} while (0)#define VELOCITY_PRT_CAMMASK(p,t) {\ int i;\ if ((t)==VELOCITY_MULTICAST_CAM) {\ for (i=0;i<(MCAM_SIZE/8);i++)\ printk("%02X",(p)->mCAMmask[i]);\ }\ else {\ for (i=0;i<(VCAM_SIZE/8);i++)\ printk("%02X",(p)->vCAMmask[i]);\ }\ printk("\n");\}#define VELOCITY_WOL_MAGIC 0x00000000UL#define VELOCITY_WOL_PHY 0x00000001UL#define VELOCITY_WOL_ARP 0x00000002UL#define VELOCITY_WOL_UCAST 0x00000004UL#define VELOCITY_WOL_BCAST 0x00000010UL#define VELOCITY_WOL_MCAST 0x00000020UL#define VELOCITY_WOL_MAGIC_SEC 0x00000040UL/* * Flags for options */#define VELOCITY_FLAGS_TAGGING 0x00000001UL#define VELOCITY_FLAGS_TX_CSUM 0x00000002UL#define VELOCITY_FLAGS_RX_CSUM 0x00000004UL#define VELOCITY_FLAGS_IP_ALIGN 0x00000008UL#define VELOCITY_FLAGS_VAL_PKT_LEN 0x00000010UL#define VELOCITY_FLAGS_FLOW_CTRL 0x01000000UL/* * Flags for driver status */#define VELOCITY_FLAGS_OPENED 0x00010000UL#define VELOCITY_FLAGS_VMNS_CONNECTED 0x00020000UL#define VELOCITY_FLAGS_VMNS_COMMITTED 0x00040000UL#define VELOCITY_FLAGS_WOL_ENABLED 0x00080000UL/* * Flags for MII status */#define VELOCITY_LINK_FAIL 0x00000001UL#define VELOCITY_SPEED_10 0x00000002UL#define VELOCITY_SPEED_100 0x00000004UL#define VELOCITY_SPEED_1000 0x00000008UL#define VELOCITY_DUPLEX_FULL 0x00000010UL#define VELOCITY_AUTONEG_ENABLE 0x00000020UL#define VELOCITY_FORCED_BY_EEPROM 0x00000040UL/* * For velocity_set_media_duplex */#define VELOCITY_LINK_CHANGE 0x00000001ULenum speed_opt { SPD_DPX_AUTO = 0, SPD_DPX_100_HALF = 1, SPD_DPX_100_FULL = 2, SPD_DPX_10_HALF = 3, SPD_DPX_10_FULL = 4};enum velocity_init_type { VELOCITY_INIT_COLD = 0, VELOCITY_INIT_RESET, VELOCITY_INIT_WOL};enum velocity_flow_cntl_type { FLOW_CNTL_DEFAULT = 1, FLOW_CNTL_TX, FLOW_CNTL_RX, FLOW_CNTL_TX_RX, FLOW_CNTL_DISABLE,};struct velocity_opt { int numrx; /* Number of RX descriptors */ int numtx; /* Number of TX descriptors */ enum speed_opt spd_dpx; /* Media link mode */ int vid; /* vlan id */ int DMA_length; /* DMA length */ int rx_thresh; /* RX_THRESH */ int flow_cntl; int wol_opts; /* Wake on lan options */ int td_int_count; int int_works; int rx_bandwidth_hi; int rx_bandwidth_lo; int rx_bandwidth_en; u32 flags;};struct velocity_info { struct list_head list; struct pci_dev *pdev; struct net_device *dev; struct net_device_stats stats;#ifdef CONFIG_PM u32 pci_state[16];#endif dma_addr_t rd_pool_dma; dma_addr_t td_pool_dma[TX_QUEUE_NO]; dma_addr_t tx_bufs_dma; u8 *tx_bufs; u8 ip_addr[4]; enum chip_type chip_id; struct mac_regs * mac_regs; unsigned long memaddr; unsigned long ioaddr; u32 io_size; u8 rev_id;#define AVAIL_TD(p,q) ((p)->options.numtx-((p)->td_used[(q)])) int num_txq; volatile int td_used[TX_QUEUE_NO]; int td_curr[TX_QUEUE_NO]; int td_tail[TX_QUEUE_NO]; struct tx_desc *td_rings[TX_QUEUE_NO]; struct velocity_td_info *td_infos[TX_QUEUE_NO]; int rd_curr; int rd_dirty; u32 rd_filled; struct rx_desc *rd_ring; struct velocity_rd_info *rd_info; /* It's an array */#define GET_RD_BY_IDX(vptr, idx) (vptr->rd_ring[idx]) u32 mib_counter[MAX_HW_MIB_COUNTER]; struct velocity_opt options; u32 int_mask; u32 flags; int rx_buf_sz; u32 mii_status; u32 phy_id; int multicast_limit; u8 vCAMmask[(VCAM_SIZE / 8)]; u8 mCAMmask[(MCAM_SIZE / 8)]; spinlock_t lock; int wol_opts; u8 wol_passwd[6]; struct velocity_context context; u32 ticks; u32 rx_bytes;};/** * velocity_get_ip - find an IP address for the device * @vptr: Velocity to query * * Dig out an IP address for this interface so that we can * configure wakeup with WOL for ARP. If there are multiple IP * addresses on this chain then we use the first - multi-IP WOL is not * supported. * * CHECK ME: locking */inline static int velocity_get_ip(struct velocity_info *vptr){ struct in_device *in_dev = (struct in_device *) vptr->dev->ip_ptr; struct in_ifaddr *ifa; if (in_dev != NULL) { ifa = (struct in_ifaddr *) in_dev->ifa_list; if (ifa != NULL) { memcpy(vptr->ip_addr, &ifa->ifa_address, 4); return 0; } } return -ENOENT;}/** * velocity_update_hw_mibs - fetch MIB counters from chip * @vptr: velocity to update * * The velocity hardware keeps certain counters in the hardware * side. We need to read these when the user asks for statistics * or when they overflow (causing an interrupt). The read of the * statistic clears it, so we keep running master counters in user * space. */static inline void velocity_update_hw_mibs(struct velocity_info *vptr){ u32 tmp; int i; BYTE_REG_BITS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR)); while (BYTE_REG_BITS_IS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR))); BYTE_REG_BITS_ON(MIBCR_MPTRINI, &(vptr->mac_regs->MIBCR)); for (i = 0; i < HW_MIB_SIZE; i++) { tmp = readl(&(vptr->mac_regs->MIBData)) & 0x00FFFFFFUL; vptr->mib_counter[i] += tmp; }}/** * init_flow_control_register - set up flow control * @vptr: velocity to configure * * Configure the flow control registers for this velocity device. */static inline void init_flow_control_register(struct velocity_info *vptr){ struct mac_regs * regs = vptr->mac_regs; /* Set {XHITH1, XHITH0, XLTH1, XLTH0} in FlowCR1 to {1, 0, 1, 1} depend on RD=64, and Turn on XNOEN in FlowCR1 */ writel((CR0_XONEN | CR0_XHITH1 | CR0_XLTH1 | CR0_XLTH0), ®s->CR0Set); writel((CR0_FDXTFCEN | CR0_FDXRFCEN | CR0_HDXFCEN | CR0_XHITH0), ®s->CR0Clr); /* Set TxPauseTimer to 0xFFFF */ writew(0xFFFF, ®s->tx_pause_timer); /* Initialize RBRDU to Rx buffer count. */ writew(vptr->options.numrx, ®s->RBRDU);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -