1/* 2 * Atheros AR71xx built-in ethernet mac driver 3 * 4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> 5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 6 * 7 * Based on Atheros' AG7100 driver 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License version 2 as published 11 * by the Free Software Foundation. 12 */ 13 14#ifndef __AG71XX_H 15#define __AG71XX_H 16 17#include <linux/kernel.h> 18#include <linux/version.h> 19#include <linux/module.h> 20#include <linux/init.h> 21#include <linux/types.h> 22#include <linux/random.h> 23#include <linux/spinlock.h> 24#include <linux/interrupt.h> 25#include <linux/platform_device.h> 26#include <linux/ethtool.h> 27#include <linux/etherdevice.h> 28#include <linux/if_vlan.h> 29#include <linux/phy.h> 30#include <linux/skbuff.h> 31#include <linux/dma-mapping.h> 32#include <linux/workqueue.h> 33 34#include <linux/bitops.h> 35 36#include <asm/mach-ath79/ar71xx_regs.h> 37#include <asm/mach-ath79/ath79.h> 38#include <asm/mach-ath79/ag71xx_platform.h> 39 40#define AG71XX_DRV_NAME "ag71xx" 41#define AG71XX_DRV_VERSION "0.5.35" 42 43#define AG71XX_NAPI_WEIGHT 64 44#define AG71XX_OOM_REFILL (1 + HZ/10) 45 46#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE) 47#define AG71XX_INT_TX (AG71XX_INT_TX_PS) 48#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF) 49 50#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX) 51#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL) 52 53#define AG71XX_TX_MTU_LEN 1540 54 55#define AG71XX_TX_RING_SPLIT 512 56#define AG71XX_TX_RING_DS_PER_PKT DIV_ROUND_UP(AG71XX_TX_MTU_LEN, \ 57 AG71XX_TX_RING_SPLIT) 58#define AG71XX_TX_RING_SIZE_DEFAULT 128 59#define AG71XX_RX_RING_SIZE_DEFAULT 256 60 61#define AG71XX_TX_RING_SIZE_MAX 128 62#define AG71XX_RX_RING_SIZE_MAX 256 63 64#ifdef CONFIG_AG71XX_DEBUG 65#define DBG(fmt, args...) pr_debug(fmt, ## args) 66#else 67#define DBG(fmt, args...) do {} while (0) 68#endif 69 70#define ag71xx_assert(_cond) \ 71do { \ 72 if (_cond) \ 73 break; \ 74 printk("%s,%d: assertion failed\n", __FILE__, __LINE__); \ 75 BUG(); \ 76} while (0) 77 78struct ag71xx_desc { 79 u32 data; 80 u32 ctrl; 81#define DESC_EMPTY BIT(31) 82#define DESC_MORE BIT(24) 83#define DESC_PKTLEN_M 0xfff 84 u32 next; 85 u32 pad; 86} __attribute__((aligned(4))); 87 88#define AG71XX_DESC_SIZE roundup(sizeof(struct ag71xx_desc), \ 89 L1_CACHE_BYTES) 90 91struct ag71xx_buf { 92 union { 93 struct sk_buff *skb; 94 void *rx_buf; 95 }; 96 union { 97 dma_addr_t dma_addr; 98 unsigned long timestamp; 99 }; 100 unsigned int len; 101}; 102 103struct ag71xx_ring { 104 struct ag71xx_buf *buf; 105 u8 *descs_cpu; 106 dma_addr_t descs_dma; 107 u16 desc_split; 108 u16 order; 109 unsigned int curr; 110 unsigned int dirty; 111}; 112 113struct ag71xx_mdio { 114 struct mii_bus *mii_bus; 115 int mii_irq[PHY_MAX_ADDR]; 116 void __iomem *mdio_base; 117 struct ag71xx_mdio_platform_data *pdata; 118}; 119 120struct ag71xx_int_stats { 121 unsigned long rx_pr; 122 unsigned long rx_be; 123 unsigned long rx_of; 124 unsigned long tx_ps; 125 unsigned long tx_be; 126 unsigned long tx_ur; 127 unsigned long total; 128}; 129 130struct ag71xx_napi_stats { 131 unsigned long napi_calls; 132 unsigned long rx_count; 133 unsigned long rx_packets; 134 unsigned long rx_packets_max; 135 unsigned long tx_count; 136 unsigned long tx_packets; 137 unsigned long tx_packets_max; 138 139 unsigned long rx[AG71XX_NAPI_WEIGHT + 1]; 140 unsigned long tx[AG71XX_NAPI_WEIGHT + 1]; 141}; 142 143struct ag71xx_debug { 144 struct dentry *debugfs_dir; 145 146 struct ag71xx_int_stats int_stats; 147 struct ag71xx_napi_stats napi_stats; 148}; 149 150struct ag71xx { 151 void __iomem *mac_base; 152 153 spinlock_t lock; 154 struct platform_device *pdev; 155 struct net_device *dev; 156 struct napi_struct napi; 157 u32 msg_enable; 158 159 struct ag71xx_desc *stop_desc; 160 dma_addr_t stop_desc_dma; 161 162 struct ag71xx_ring rx_ring; 163 struct ag71xx_ring tx_ring; 164 165 struct mii_bus *mii_bus; 166 struct phy_device *phy_dev; 167 void *phy_priv; 168 169 unsigned int link; 170 unsigned int speed; 171 int duplex; 172 173 unsigned int max_frame_len; 174 unsigned int desc_pktlen_mask; 175 unsigned int rx_buf_size; 176 177 struct work_struct restart_work; 178 struct delayed_work link_work; 179 struct timer_list oom_timer; 180 181#ifdef CONFIG_AG71XX_DEBUG_FS 182 struct ag71xx_debug debug; 183#endif 184}; 185 186extern struct ethtool_ops ag71xx_ethtool_ops; 187void ag71xx_link_adjust(struct ag71xx *ag); 188 189int ag71xx_mdio_driver_init(void) __init; 190void ag71xx_mdio_driver_exit(void); 191 192int ag71xx_phy_connect(struct ag71xx *ag); 193void ag71xx_phy_disconnect(struct ag71xx *ag); 194void ag71xx_phy_start(struct ag71xx *ag); 195void ag71xx_phy_stop(struct ag71xx *ag); 196 197static inline struct ag71xx_platform_data *ag71xx_get_pdata(struct ag71xx *ag) 198{ 199 return ag->pdev->dev.platform_data; 200} 201 202static inline int ag71xx_desc_empty(struct ag71xx_desc *desc) 203{ 204 return (desc->ctrl & DESC_EMPTY) != 0; 205} 206 207static inline struct ag71xx_desc * 208ag71xx_ring_desc(struct ag71xx_ring *ring, int idx) 209{ 210 return (struct ag71xx_desc *) &ring->descs_cpu[idx * AG71XX_DESC_SIZE]; 211} 212 213static inline int 214ag71xx_ring_size_order(int size) 215{ 216 return fls(size - 1); 217} 218 219/* Register offsets */ 220#define AG71XX_REG_MAC_CFG1 0x0000 221#define AG71XX_REG_MAC_CFG2 0x0004 222#define AG71XX_REG_MAC_IPG 0x0008 223#define AG71XX_REG_MAC_HDX 0x000c 224#define AG71XX_REG_MAC_MFL 0x0010 225#define AG71XX_REG_MII_CFG 0x0020 226#define AG71XX_REG_MII_CMD 0x0024 227#define AG71XX_REG_MII_ADDR 0x0028 228#define AG71XX_REG_MII_CTRL 0x002c 229#define AG71XX_REG_MII_STATUS 0x0030 230#define AG71XX_REG_MII_IND 0x0034 231#define AG71XX_REG_MAC_IFCTL 0x0038 232#define AG71XX_REG_MAC_ADDR1 0x0040 233#define AG71XX_REG_MAC_ADDR2 0x0044 234#define AG71XX_REG_FIFO_CFG0 0x0048 235#define AG71XX_REG_FIFO_CFG1 0x004c 236#define AG71XX_REG_FIFO_CFG2 0x0050 237#define AG71XX_REG_FIFO_CFG3 0x0054 238#define AG71XX_REG_FIFO_CFG4 0x0058 239#define AG71XX_REG_FIFO_CFG5 0x005c 240#define AG71XX_REG_FIFO_RAM0 0x0060 241#define AG71XX_REG_FIFO_RAM1 0x0064 242#define AG71XX_REG_FIFO_RAM2 0x0068 243#define AG71XX_REG_FIFO_RAM3 0x006c 244#define AG71XX_REG_FIFO_RAM4 0x0070 245#define AG71XX_REG_FIFO_RAM5 0x0074 246#define AG71XX_REG_FIFO_RAM6 0x0078 247#define AG71XX_REG_FIFO_RAM7 0x007c 248 249#define AG71XX_REG_TX_CTRL 0x0180 250#define AG71XX_REG_TX_DESC 0x0184 251#define AG71XX_REG_TX_STATUS 0x0188 252#define AG71XX_REG_RX_CTRL 0x018c 253#define AG71XX_REG_RX_DESC 0x0190 254#define AG71XX_REG_RX_STATUS 0x0194 255#define AG71XX_REG_INT_ENABLE 0x0198 256#define AG71XX_REG_INT_STATUS 0x019c 257 258#define AG71XX_REG_FIFO_DEPTH 0x01a8 259#define AG71XX_REG_RX_SM 0x01b0 260#define AG71XX_REG_TX_SM 0x01b4 261 262#define MAC_CFG1_TXE BIT(0) /* Tx Enable */ 263#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */ 264#define MAC_CFG1_RXE BIT(2) /* Rx Enable */ 265#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */ 266#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */ 267#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */ 268#define MAC_CFG1_LB BIT(8) /* Loopback mode */ 269#define MAC_CFG1_SR BIT(31) /* Soft Reset */ 270 271#define MAC_CFG2_FDX BIT(0) 272#define MAC_CFG2_CRC_EN BIT(1) 273#define MAC_CFG2_PAD_CRC_EN BIT(2) 274#define MAC_CFG2_LEN_CHECK BIT(4) 275#define MAC_CFG2_HUGE_FRAME_EN BIT(5) 276#define MAC_CFG2_IF_1000 BIT(9) 277#define MAC_CFG2_IF_10_100 BIT(8) 278 279#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */ 280#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */ 281#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */ 282#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */ 283#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */ 284#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \ 285 | FIFO_CFG0_TXS | FIFO_CFG0_TXF) 286 287#define FIFO_CFG0_ENABLE_SHIFT 8 288 289#define FIFO_CFG4_DE BIT(0) /* Drop Event */ 290#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */ 291#define FIFO_CFG4_FC BIT(2) /* False Carrier */ 292#define FIFO_CFG4_CE BIT(3) /* Code Error */ 293#define FIFO_CFG4_CR BIT(4) /* CRC error */ 294#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */ 295#define FIFO_CFG4_LO BIT(6) /* Length out of range */ 296#define FIFO_CFG4_OK BIT(7) /* Packet is OK */ 297#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */ 298#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */ 299#define FIFO_CFG4_DR BIT(10) /* Dribble */ 300#define FIFO_CFG4_LE BIT(11) /* Long Event */ 301#define FIFO_CFG4_CF BIT(12) /* Control Frame */ 302#define FIFO_CFG4_PF BIT(13) /* Pause Frame */ 303#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */ 304#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */ 305#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */ 306#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */ 307 308#define FIFO_CFG5_DE BIT(0) /* Drop Event */ 309#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */ 310#define FIFO_CFG5_FC BIT(2) /* False Carrier */ 311#define FIFO_CFG5_CE BIT(3) /* Code Error */ 312#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */ 313#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */ 314#define FIFO_CFG5_OK BIT(6) /* Packet is OK */ 315#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */ 316#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */ 317#define FIFO_CFG5_DR BIT(9) /* Dribble */ 318#define FIFO_CFG5_CF BIT(10) /* Control Frame */ 319#define FIFO_CFG5_PF BIT(11) /* Pause Frame */ 320#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */ 321#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */ 322#define FIFO_CFG5_LE BIT(14) /* Long Event */ 323#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */ 324#define FIFO_CFG5_16 BIT(16) /* unknown */ 325#define FIFO_CFG5_17 BIT(17) /* unknown */ 326#define FIFO_CFG5_SF BIT(18) /* Short Frame */ 327#define FIFO_CFG5_BM BIT(19) /* Byte Mode */ 328 329#define AG71XX_INT_TX_PS BIT(0) 330#define AG71XX_INT_TX_UR BIT(1) 331#define AG71XX_INT_TX_BE BIT(3) 332#define AG71XX_INT_RX_PR BIT(4) 333#define AG71XX_INT_RX_OF BIT(6) 334#define AG71XX_INT_RX_BE BIT(7) 335 336#define MAC_IFCTL_SPEED BIT(16) 337 338#define MII_CFG_CLK_DIV_4 0 339#define MII_CFG_CLK_DIV_6 2 340#define MII_CFG_CLK_DIV_8 3 341#define MII_CFG_CLK_DIV_10 4 342#define MII_CFG_CLK_DIV_14 5 343#define MII_CFG_CLK_DIV_20 6 344#define MII_CFG_CLK_DIV_28 7 345#define MII_CFG_CLK_DIV_34 8 346#define MII_CFG_CLK_DIV_42 9 347#define MII_CFG_CLK_DIV_50 10 348#define MII_CFG_CLK_DIV_58 11 349#define MII_CFG_CLK_DIV_66 12 350#define MII_CFG_CLK_DIV_74 13 351#define MII_CFG_CLK_DIV_82 14 352#define MII_CFG_CLK_DIV_98 15 353#define MII_CFG_RESET BIT(31) 354 355#define MII_CMD_WRITE 0x0 356#define MII_CMD_READ 0x1 357#define MII_ADDR_SHIFT 8 358#define MII_IND_BUSY BIT(0) 359#define MII_IND_INVALID BIT(2) 360 361#define TX_CTRL_TXE BIT(0) /* Tx Enable */ 362 363#define TX_STATUS_PS BIT(0) /* Packet Sent */ 364#define TX_STATUS_UR BIT(1) /* Tx Underrun */ 365#define TX_STATUS_BE BIT(3) /* Bus Error */ 366 367#define RX_CTRL_RXE BIT(0) /* Rx Enable */ 368 369#define RX_STATUS_PR BIT(0) /* Packet Received */ 370#define RX_STATUS_OF BIT(2) /* Rx Overflow */ 371#define RX_STATUS_BE BIT(3) /* Bus Error */ 372 373static inline void ag71xx_check_reg_offset(struct ag71xx *ag, unsigned reg) 374{ 375 switch (reg) { 376 case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL: 377 case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_TX_SM: 378 case AG71XX_REG_MII_CFG: 379 break; 380 381 default: 382 BUG(); 383 } 384} 385 386static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value) 387{ 388 ag71xx_check_reg_offset(ag, reg); 389 390 __raw_writel(value, ag->mac_base + reg); 391 /* flush write */ 392 (void) __raw_readl(ag->mac_base + reg); 393} 394 395static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg) 396{ 397 ag71xx_check_reg_offset(ag, reg); 398 399 return __raw_readl(ag->mac_base + reg); 400} 401 402static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask) 403{ 404 void __iomem *r; 405 406 ag71xx_check_reg_offset(ag, reg); 407 408 r = ag->mac_base + reg; 409 __raw_writel(__raw_readl(r) | mask, r); 410 /* flush write */ 411 (void)__raw_readl(r); 412} 413 414static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask) 415{ 416 void __iomem *r; 417 418 ag71xx_check_reg_offset(ag, reg); 419 420 r = ag->mac_base + reg; 421 __raw_writel(__raw_readl(r) & ~mask, r); 422 /* flush write */ 423 (void) __raw_readl(r); 424} 425 426static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints) 427{ 428 ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints); 429} 430 431static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints) 432{ 433 ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints); 434} 435 436#ifdef CONFIG_AG71XX_AR8216_SUPPORT 437void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb); 438int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb, 439 int pktlen); 440static inline int ag71xx_has_ar8216(struct ag71xx *ag) 441{ 442 return ag71xx_get_pdata(ag)->has_ar8216; 443} 444#else 445static inline void ag71xx_add_ar8216_header(struct ag71xx *ag, 446 struct sk_buff *skb) 447{ 448} 449 450static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag, 451 struct sk_buff *skb, 452 int pktlen) 453{ 454 return 0; 455} 456static inline int ag71xx_has_ar8216(struct ag71xx *ag) 457{ 458 return 0; 459} 460#endif 461 462#ifdef CONFIG_AG71XX_DEBUG_FS 463int ag71xx_debugfs_root_init(void); 464void ag71xx_debugfs_root_exit(void); 465int ag71xx_debugfs_init(struct ag71xx *ag); 466void ag71xx_debugfs_exit(struct ag71xx *ag); 467void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status); 468void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx); 469#else 470static inline int ag71xx_debugfs_root_init(void) { return 0; } 471static inline void ag71xx_debugfs_root_exit(void) {} 472static inline int ag71xx_debugfs_init(struct ag71xx *ag) { return 0; } 473static inline void ag71xx_debugfs_exit(struct ag71xx *ag) {} 474static inline void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, 475 u32 status) {} 476static inline void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, 477 int rx, int tx) {} 478#endif /* CONFIG_AG71XX_DEBUG_FS */ 479 480void ag71xx_ar7240_start(struct ag71xx *ag); 481void ag71xx_ar7240_stop(struct ag71xx *ag); 482int ag71xx_ar7240_init(struct ag71xx *ag); 483void ag71xx_ar7240_cleanup(struct ag71xx *ag); 484 485int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg); 486void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val); 487 488u16 ar7240sw_phy_read(struct mii_bus *mii, unsigned phy_addr, 489 unsigned reg_addr); 490int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr, 491 unsigned reg_addr, u16 reg_val); 492 493#endif /* _AG71XX_H */ 494