ixf1010.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. /* $Date: 2005/11/12 02:13:49 $ $RCSfile: ixf1010.c,v $ $Revision: 1.36 $ */
  2. #include "gmac.h"
  3. #include "elmer0.h"
  4. /* Update fast changing statistics every 15 seconds */
  5. #define STATS_TICK_SECS 15
  6. /* 30 minutes for full statistics update */
  7. #define MAJOR_UPDATE_TICKS (1800 / STATS_TICK_SECS)
  8. /*
  9. * The IXF1010 can handle frames up to 16383 bytes but it's optimized for
  10. * frames up to 9831 (0x2667) bytes, so we limit jumbo frame size to this.
  11. * This length includes ethernet header and FCS.
  12. */
  13. #define MAX_FRAME_SIZE 0x2667
  14. /* MAC registers */
  15. enum {
  16. /* Per-port registers */
  17. REG_MACADDR_LOW = 0,
  18. REG_MACADDR_HIGH = 0x4,
  19. REG_FDFC_TYPE = 0xC,
  20. REG_FC_TX_TIMER_VALUE = 0x1c,
  21. REG_IPG_RX_TIME1 = 0x28,
  22. REG_IPG_RX_TIME2 = 0x2c,
  23. REG_IPG_TX_TIME = 0x30,
  24. REG_PAUSE_THRES = 0x38,
  25. REG_MAX_FRAME_SIZE = 0x3c,
  26. REG_RGMII_SPEED = 0x40,
  27. REG_FC_ENABLE = 0x48,
  28. REG_DISCARD_CTRL_FRAMES = 0x54,
  29. REG_DIVERSE_CONFIG = 0x60,
  30. REG_RX_FILTER = 0x64,
  31. REG_MC_ADDR_LOW = 0x68,
  32. REG_MC_ADDR_HIGH = 0x6c,
  33. REG_RX_OCTETS_OK = 0x80,
  34. REG_RX_OCTETS_BAD = 0x84,
  35. REG_RX_UC_PKTS = 0x88,
  36. REG_RX_MC_PKTS = 0x8c,
  37. REG_RX_BC_PKTS = 0x90,
  38. REG_RX_FCS_ERR = 0xb0,
  39. REG_RX_TAGGED = 0xb4,
  40. REG_RX_DATA_ERR = 0xb8,
  41. REG_RX_ALIGN_ERR = 0xbc,
  42. REG_RX_LONG_ERR = 0xc0,
  43. REG_RX_JABBER_ERR = 0xc4,
  44. REG_RX_PAUSE_FRAMES = 0xc8,
  45. REG_RX_UNKNOWN_CTRL_FRAMES = 0xcc,
  46. REG_RX_VERY_LONG_ERR = 0xd0,
  47. REG_RX_RUNT_ERR = 0xd4,
  48. REG_RX_SHORT_ERR = 0xd8,
  49. REG_RX_SYMBOL_ERR = 0xe4,
  50. REG_TX_OCTETS_OK = 0x100,
  51. REG_TX_OCTETS_BAD = 0x104,
  52. REG_TX_UC_PKTS = 0x108,
  53. REG_TX_MC_PKTS = 0x10c,
  54. REG_TX_BC_PKTS = 0x110,
  55. REG_TX_EXCESSIVE_LEN_DROP = 0x14c,
  56. REG_TX_UNDERRUN = 0x150,
  57. REG_TX_TAGGED = 0x154,
  58. REG_TX_PAUSE_FRAMES = 0x15C,
  59. /* Global registers */
  60. REG_PORT_ENABLE = 0x1400,
  61. REG_JTAG_ID = 0x1430,
  62. RX_FIFO_HIGH_WATERMARK_BASE = 0x1600,
  63. RX_FIFO_LOW_WATERMARK_BASE = 0x1628,
  64. RX_FIFO_FRAMES_REMOVED_BASE = 0x1650,
  65. REG_RX_ERR_DROP = 0x167c,
  66. REG_RX_FIFO_OVERFLOW_EVENT = 0x1680,
  67. TX_FIFO_HIGH_WATERMARK_BASE = 0x1800,
  68. TX_FIFO_LOW_WATERMARK_BASE = 0x1828,
  69. TX_FIFO_XFER_THRES_BASE = 0x1850,
  70. REG_TX_FIFO_OVERFLOW_EVENT = 0x1878,
  71. REG_TX_FIFO_OOS_EVENT = 0x1884,
  72. TX_FIFO_FRAMES_REMOVED_BASE = 0x1888,
  73. REG_SPI_RX_BURST = 0x1c00,
  74. REG_SPI_RX_TRAINING = 0x1c04,
  75. REG_SPI_RX_CALENDAR = 0x1c08,
  76. REG_SPI_TX_SYNC = 0x1c0c
  77. };
  78. enum { /* RMON registers */
  79. REG_RxOctetsTotalOK = 0x80,
  80. REG_RxOctetsBad = 0x84,
  81. REG_RxUCPkts = 0x88,
  82. REG_RxMCPkts = 0x8c,
  83. REG_RxBCPkts = 0x90,
  84. REG_RxJumboPkts = 0xac,
  85. REG_RxFCSErrors = 0xb0,
  86. REG_RxDataErrors = 0xb8,
  87. REG_RxAlignErrors = 0xbc,
  88. REG_RxLongErrors = 0xc0,
  89. REG_RxJabberErrors = 0xc4,
  90. REG_RxPauseMacControlCounter = 0xc8,
  91. REG_RxVeryLongErrors = 0xd0,
  92. REG_RxRuntErrors = 0xd4,
  93. REG_RxShortErrors = 0xd8,
  94. REG_RxSequenceErrors = 0xe0,
  95. REG_RxSymbolErrors = 0xe4,
  96. REG_TxOctetsTotalOK = 0x100,
  97. REG_TxOctetsBad = 0x104,
  98. REG_TxUCPkts = 0x108,
  99. REG_TxMCPkts = 0x10c,
  100. REG_TxBCPkts = 0x110,
  101. REG_TxJumboPkts = 0x12C,
  102. REG_TxTotalCollisions = 0x134,
  103. REG_TxExcessiveLengthDrop = 0x14c,
  104. REG_TxUnderrun = 0x150,
  105. REG_TxCRCErrors = 0x158,
  106. REG_TxPauseFrames = 0x15c
  107. };
  108. enum {
  109. DIVERSE_CONFIG_PAD_ENABLE = 0x80,
  110. DIVERSE_CONFIG_CRC_ADD = 0x40
  111. };
  112. #define MACREG_BASE 0
  113. #define MACREG(mac, mac_reg) ((mac)->instance->mac_base + (mac_reg))
  114. struct _cmac_instance {
  115. u32 mac_base;
  116. u32 index;
  117. u32 version;
  118. u32 ticks;
  119. };
  120. static void disable_port(struct cmac *mac)
  121. {
  122. u32 val;
  123. t1_tpi_read(mac->adapter, REG_PORT_ENABLE, &val);
  124. val &= ~(1 << mac->instance->index);
  125. t1_tpi_write(mac->adapter, REG_PORT_ENABLE, val);
  126. }
  127. /*
  128. * Read the current values of the RMON counters and add them to the cumulative
  129. * port statistics. The HW RMON counters are cleared by this operation.
  130. */
  131. static void port_stats_update(struct cmac *mac)
  132. {
  133. static struct {
  134. unsigned int reg;
  135. unsigned int offset;
  136. } hw_stats[] = {
  137. #define HW_STAT(name, stat_name) \
  138. { REG_##name, \
  139. (&((struct cmac_statistics *)NULL)->stat_name) - (u64 *)NULL }
  140. /* Rx stats */
  141. HW_STAT(RxOctetsTotalOK, RxOctetsOK),
  142. HW_STAT(RxOctetsBad, RxOctetsBad),
  143. HW_STAT(RxUCPkts, RxUnicastFramesOK),
  144. HW_STAT(RxMCPkts, RxMulticastFramesOK),
  145. HW_STAT(RxBCPkts, RxBroadcastFramesOK),
  146. HW_STAT(RxJumboPkts, RxJumboFramesOK),
  147. HW_STAT(RxFCSErrors, RxFCSErrors),
  148. HW_STAT(RxAlignErrors, RxAlignErrors),
  149. HW_STAT(RxLongErrors, RxFrameTooLongErrors),
  150. HW_STAT(RxVeryLongErrors, RxFrameTooLongErrors),
  151. HW_STAT(RxPauseMacControlCounter, RxPauseFrames),
  152. HW_STAT(RxDataErrors, RxDataErrors),
  153. HW_STAT(RxJabberErrors, RxJabberErrors),
  154. HW_STAT(RxRuntErrors, RxRuntErrors),
  155. HW_STAT(RxShortErrors, RxRuntErrors),
  156. HW_STAT(RxSequenceErrors, RxSequenceErrors),
  157. HW_STAT(RxSymbolErrors, RxSymbolErrors),
  158. /* Tx stats (skip collision stats as we are full-duplex only) */
  159. HW_STAT(TxOctetsTotalOK, TxOctetsOK),
  160. HW_STAT(TxOctetsBad, TxOctetsBad),
  161. HW_STAT(TxUCPkts, TxUnicastFramesOK),
  162. HW_STAT(TxMCPkts, TxMulticastFramesOK),
  163. HW_STAT(TxBCPkts, TxBroadcastFramesOK),
  164. HW_STAT(TxJumboPkts, TxJumboFramesOK),
  165. HW_STAT(TxPauseFrames, TxPauseFrames),
  166. HW_STAT(TxExcessiveLengthDrop, TxLengthErrors),
  167. HW_STAT(TxUnderrun, TxUnderrun),
  168. HW_STAT(TxCRCErrors, TxFCSErrors)
  169. }, *p = hw_stats;
  170. u64 *stats = (u64 *) &mac->stats;
  171. unsigned int i;
  172. for (i = 0; i < ARRAY_SIZE(hw_stats); i++) {
  173. u32 val;
  174. t1_tpi_read(mac->adapter, MACREG(mac, p->reg), &val);
  175. stats[p->offset] += val;
  176. }
  177. }
  178. /* No-op interrupt operation as this MAC does not support interrupts */
  179. static int mac_intr_op(struct cmac *mac)
  180. {
  181. return 0;
  182. }
  183. /* Expect MAC address to be in network byte order. */
  184. static int mac_set_address(struct cmac *mac, u8 addr[6])
  185. {
  186. u32 addr_lo, addr_hi;
  187. addr_lo = addr[2];
  188. addr_lo = (addr_lo << 8) | addr[3];
  189. addr_lo = (addr_lo << 8) | addr[4];
  190. addr_lo = (addr_lo << 8) | addr[5];
  191. addr_hi = addr[0];
  192. addr_hi = (addr_hi << 8) | addr[1];
  193. t1_tpi_write(mac->adapter, MACREG(mac, REG_MACADDR_LOW), addr_lo);
  194. t1_tpi_write(mac->adapter, MACREG(mac, REG_MACADDR_HIGH), addr_hi);
  195. return 0;
  196. }
  197. static int mac_get_address(struct cmac *mac, u8 addr[6])
  198. {
  199. u32 addr_lo, addr_hi;
  200. t1_tpi_read(mac->adapter, MACREG(mac, REG_MACADDR_LOW), &addr_lo);
  201. t1_tpi_read(mac->adapter, MACREG(mac, REG_MACADDR_HIGH), &addr_hi);
  202. addr[0] = (u8) (addr_hi >> 8);
  203. addr[1] = (u8) addr_hi;
  204. addr[2] = (u8) (addr_lo >> 24);
  205. addr[3] = (u8) (addr_lo >> 16);
  206. addr[4] = (u8) (addr_lo >> 8);
  207. addr[5] = (u8) addr_lo;
  208. return 0;
  209. }
  210. /* This is intended to reset a port, not the whole MAC */
  211. static int mac_reset(struct cmac *mac)
  212. {
  213. return 0;
  214. }
  215. static int mac_set_rx_mode(struct cmac *mac, struct t1_rx_mode *rm)
  216. {
  217. u32 val, new_mode;
  218. adapter_t *adapter = mac->adapter;
  219. u32 addr_lo, addr_hi;
  220. u8 *addr;
  221. t1_tpi_read(adapter, MACREG(mac, REG_RX_FILTER), &val);
  222. new_mode = val & ~7;
  223. if (!t1_rx_mode_promisc(rm) && mac->instance->version > 0)
  224. new_mode |= 1; /* only set if version > 0 due to erratum */
  225. if (!t1_rx_mode_promisc(rm) && !t1_rx_mode_allmulti(rm)
  226. && t1_rx_mode_mc_cnt(rm) <= 1)
  227. new_mode |= 2;
  228. if (new_mode != val)
  229. t1_tpi_write(adapter, MACREG(mac, REG_RX_FILTER), new_mode);
  230. switch (t1_rx_mode_mc_cnt(rm)) {
  231. case 0:
  232. t1_tpi_write(adapter, MACREG(mac, REG_MC_ADDR_LOW), 0);
  233. t1_tpi_write(adapter, MACREG(mac, REG_MC_ADDR_HIGH), 0);
  234. break;
  235. case 1:
  236. addr = t1_get_next_mcaddr(rm);
  237. addr_lo = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) |
  238. addr[5];
  239. addr_hi = (addr[0] << 8) | addr[1];
  240. t1_tpi_write(adapter, MACREG(mac, REG_MC_ADDR_LOW), addr_lo);
  241. t1_tpi_write(adapter, MACREG(mac, REG_MC_ADDR_HIGH), addr_hi);
  242. break;
  243. default:
  244. break;
  245. }
  246. return 0;
  247. }
  248. static int mac_set_mtu(struct cmac *mac, int mtu)
  249. {
  250. /* MAX_FRAME_SIZE inludes header + FCS, mtu doesn't */
  251. if (mtu > (MAX_FRAME_SIZE - 14 - 4))
  252. return -EINVAL;
  253. t1_tpi_write(mac->adapter, MACREG(mac, REG_MAX_FRAME_SIZE),
  254. mtu + 14 + 4);
  255. return 0;
  256. }
  257. static int mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex,
  258. int fc)
  259. {
  260. u32 val;
  261. if (speed >= 0 && speed != SPEED_100 && speed != SPEED_1000)
  262. return -1;
  263. if (duplex >= 0 && duplex != DUPLEX_FULL)
  264. return -1;
  265. if (speed >= 0) {
  266. val = speed == SPEED_100 ? 1 : 2;
  267. t1_tpi_write(mac->adapter, MACREG(mac, REG_RGMII_SPEED), val);
  268. }
  269. t1_tpi_read(mac->adapter, MACREG(mac, REG_FC_ENABLE), &val);
  270. val &= ~3;
  271. if (fc & PAUSE_RX)
  272. val |= 1;
  273. if (fc & PAUSE_TX)
  274. val |= 2;
  275. t1_tpi_write(mac->adapter, MACREG(mac, REG_FC_ENABLE), val);
  276. return 0;
  277. }
  278. static int mac_get_speed_duplex_fc(struct cmac *mac, int *speed, int *duplex,
  279. int *fc)
  280. {
  281. u32 val;
  282. if (duplex)
  283. *duplex = DUPLEX_FULL;
  284. if (speed) {
  285. t1_tpi_read(mac->adapter, MACREG(mac, REG_RGMII_SPEED),
  286. &val);
  287. *speed = (val & 2) ? SPEED_1000 : SPEED_100;
  288. }
  289. if (fc) {
  290. t1_tpi_read(mac->adapter, MACREG(mac, REG_FC_ENABLE), &val);
  291. *fc = 0;
  292. if (val & 1)
  293. *fc |= PAUSE_RX;
  294. if (val & 2)
  295. *fc |= PAUSE_TX;
  296. }
  297. return 0;
  298. }
  299. static void enable_port(struct cmac *mac)
  300. {
  301. u32 val;
  302. u32 index = mac->instance->index;
  303. adapter_t *adapter = mac->adapter;
  304. t1_tpi_read(adapter, MACREG(mac, REG_DIVERSE_CONFIG), &val);
  305. val |= DIVERSE_CONFIG_CRC_ADD | DIVERSE_CONFIG_PAD_ENABLE;
  306. t1_tpi_write(adapter, MACREG(mac, REG_DIVERSE_CONFIG), val);
  307. if (mac->instance->version > 0)
  308. t1_tpi_write(adapter, MACREG(mac, REG_RX_FILTER), 3);
  309. else /* Don't enable unicast address filtering due to IXF1010 bug */
  310. t1_tpi_write(adapter, MACREG(mac, REG_RX_FILTER), 2);
  311. t1_tpi_read(adapter, REG_RX_ERR_DROP, &val);
  312. val |= (1 << index);
  313. t1_tpi_write(adapter, REG_RX_ERR_DROP, val);
  314. /*
  315. * Clear the port RMON registers by adding their current values to the
  316. * cumulatice port stats and then clearing the stats. Really.
  317. */
  318. port_stats_update(mac);
  319. memset(&mac->stats, 0, sizeof(struct cmac_statistics));
  320. mac->instance->ticks = 0;
  321. t1_tpi_read(adapter, REG_PORT_ENABLE, &val);
  322. val |= (1 << index);
  323. t1_tpi_write(adapter, REG_PORT_ENABLE, val);
  324. index <<= 2;
  325. if (is_T2(adapter)) {
  326. /* T204: set the Fifo water level & threshold */
  327. t1_tpi_write(adapter, RX_FIFO_HIGH_WATERMARK_BASE + index, 0x740);
  328. t1_tpi_write(adapter, RX_FIFO_LOW_WATERMARK_BASE + index, 0x730);
  329. t1_tpi_write(adapter, TX_FIFO_HIGH_WATERMARK_BASE + index, 0x600);
  330. t1_tpi_write(adapter, TX_FIFO_LOW_WATERMARK_BASE + index, 0x1d0);
  331. t1_tpi_write(adapter, TX_FIFO_XFER_THRES_BASE + index, 0x1100);
  332. } else {
  333. /*
  334. * Set the TX Fifo Threshold to 0x400 instead of 0x100 to work around
  335. * Underrun problem. Intel has blessed this solution.
  336. */
  337. t1_tpi_write(adapter, TX_FIFO_XFER_THRES_BASE + index, 0x400);
  338. }
  339. }
  340. /* IXF1010 ports do not have separate enables for TX and RX */
  341. static int mac_enable(struct cmac *mac, int which)
  342. {
  343. if (which & (MAC_DIRECTION_RX | MAC_DIRECTION_TX))
  344. enable_port(mac);
  345. return 0;
  346. }
  347. static int mac_disable(struct cmac *mac, int which)
  348. {
  349. if (which & (MAC_DIRECTION_RX | MAC_DIRECTION_TX))
  350. disable_port(mac);
  351. return 0;
  352. }
  353. #define RMON_UPDATE(mac, name, stat_name) \
  354. t1_tpi_read((mac)->adapter, MACREG(mac, REG_##name), &val); \
  355. (mac)->stats.stat_name += val;
  356. /*
  357. * This function is called periodically to accumulate the current values of the
  358. * RMON counters into the port statistics. Since the counters are only 32 bits
  359. * some of them can overflow in less than a minute at GigE speeds, so this
  360. * function should be called every 30 seconds or so.
  361. *
  362. * To cut down on reading costs we update only the octet counters at each tick
  363. * and do a full update at major ticks, which can be every 30 minutes or more.
  364. */
  365. static const struct cmac_statistics *mac_update_statistics(struct cmac *mac,
  366. int flag)
  367. {
  368. if (flag == MAC_STATS_UPDATE_FULL ||
  369. MAJOR_UPDATE_TICKS <= mac->instance->ticks) {
  370. port_stats_update(mac);
  371. mac->instance->ticks = 0;
  372. } else {
  373. u32 val;
  374. RMON_UPDATE(mac, RxOctetsTotalOK, RxOctetsOK);
  375. RMON_UPDATE(mac, TxOctetsTotalOK, TxOctetsOK);
  376. mac->instance->ticks++;
  377. }
  378. return &mac->stats;
  379. }
  380. static void mac_destroy(struct cmac *mac)
  381. {
  382. kfree(mac);
  383. }
  384. static struct cmac_ops ixf1010_ops = {
  385. .destroy = mac_destroy,
  386. .reset = mac_reset,
  387. .interrupt_enable = mac_intr_op,
  388. .interrupt_disable = mac_intr_op,
  389. .interrupt_clear = mac_intr_op,
  390. .enable = mac_enable,
  391. .disable = mac_disable,
  392. .set_mtu = mac_set_mtu,
  393. .set_rx_mode = mac_set_rx_mode,
  394. .set_speed_duplex_fc = mac_set_speed_duplex_fc,
  395. .get_speed_duplex_fc = mac_get_speed_duplex_fc,
  396. .statistics_update = mac_update_statistics,
  397. .macaddress_get = mac_get_address,
  398. .macaddress_set = mac_set_address,
  399. };
  400. static int ixf1010_mac_reset(adapter_t *adapter)
  401. {
  402. u32 val;
  403. t1_tpi_read(adapter, A_ELMER0_GPO, &val);
  404. if ((val & 1) != 0) {
  405. val &= ~1;
  406. t1_tpi_write(adapter, A_ELMER0_GPO, val);
  407. udelay(2);
  408. }
  409. val |= 1;
  410. t1_tpi_write(adapter, A_ELMER0_GPO, val);
  411. udelay(2);
  412. t1_tpi_write(adapter, REG_PORT_ENABLE, 0);
  413. return 0;
  414. }
  415. static struct cmac *ixf1010_mac_create(adapter_t *adapter, int index)
  416. {
  417. struct cmac *mac;
  418. u32 val;
  419. if (index > 9)
  420. return NULL;
  421. mac = kzalloc(sizeof(*mac) + sizeof(cmac_instance), GFP_KERNEL);
  422. if (!mac)
  423. return NULL;
  424. mac->ops = &ixf1010_ops;
  425. mac->instance = (cmac_instance *)(mac + 1);
  426. mac->instance->mac_base = MACREG_BASE + (index * 0x200);
  427. mac->instance->index = index;
  428. mac->adapter = adapter;
  429. mac->instance->ticks = 0;
  430. t1_tpi_read(adapter, REG_JTAG_ID, &val);
  431. mac->instance->version = val >> 28;
  432. return mac;
  433. }
  434. struct gmac t1_ixf1010_ops = {
  435. STATS_TICK_SECS,
  436. ixf1010_mac_create,
  437. ixf1010_mac_reset
  438. };