vsc7326.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. /* $Date: 2006/04/28 19:20:06 $ $RCSfile: vsc7326.c,v $ $Revision: 1.19 $ */
  2. /* Driver for Vitesse VSC7326 (Schaumburg) MAC */
  3. #include "gmac.h"
  4. #include "elmer0.h"
  5. #include "vsc7326_reg.h"
  6. /* Update fast changing statistics every 15 seconds */
  7. #define STATS_TICK_SECS 15
  8. /* 30 minutes for full statistics update */
  9. #define MAJOR_UPDATE_TICKS (1800 / STATS_TICK_SECS)
  10. /* The egress WM value 0x01a01fff should be used only when the
  11. * interface is down (MAC port disabled). This is a workaround
  12. * for disabling the T2/MAC flow-control. When the interface is
  13. * enabled, the WM value should be set to 0x014a03F0.
  14. */
  15. #define WM_DISABLE 0x01a01fff
  16. #define WM_ENABLE 0x014a03F0
  17. struct init_table {
  18. u32 addr;
  19. u32 data;
  20. };
  21. struct _cmac_instance {
  22. u32 index;
  23. u32 ticks;
  24. };
  25. #define INITBLOCK_SLEEP 0xffffffff
  26. static void vsc_read(adapter_t *adapter, u32 addr, u32 *val)
  27. {
  28. u32 status, vlo, vhi;
  29. int i;
  30. spin_lock_bh(&adapter->mac_lock);
  31. t1_tpi_read(adapter, (addr << 2) + 4, &vlo);
  32. i = 0;
  33. do {
  34. t1_tpi_read(adapter, (REG_LOCAL_STATUS << 2) + 4, &vlo);
  35. t1_tpi_read(adapter, REG_LOCAL_STATUS << 2, &vhi);
  36. status = (vhi << 16) | vlo;
  37. i++;
  38. } while (((status & 1) == 0) && (i < 50));
  39. if (i == 50)
  40. pr_err("Invalid tpi read from MAC, breaking loop.\n");
  41. t1_tpi_read(adapter, (REG_LOCAL_DATA << 2) + 4, &vlo);
  42. t1_tpi_read(adapter, REG_LOCAL_DATA << 2, &vhi);
  43. *val = (vhi << 16) | vlo;
  44. /* pr_err("rd: block: 0x%x sublock: 0x%x reg: 0x%x data: 0x%x\n",
  45. ((addr&0xe000)>>13), ((addr&0x1e00)>>9),
  46. ((addr&0x01fe)>>1), *val); */
  47. spin_unlock_bh(&adapter->mac_lock);
  48. }
  49. static void vsc_write(adapter_t *adapter, u32 addr, u32 data)
  50. {
  51. spin_lock_bh(&adapter->mac_lock);
  52. t1_tpi_write(adapter, (addr << 2) + 4, data & 0xFFFF);
  53. t1_tpi_write(adapter, addr << 2, (data >> 16) & 0xFFFF);
  54. /* pr_err("wr: block: 0x%x sublock: 0x%x reg: 0x%x data: 0x%x\n",
  55. ((addr&0xe000)>>13), ((addr&0x1e00)>>9),
  56. ((addr&0x01fe)>>1), data); */
  57. spin_unlock_bh(&adapter->mac_lock);
  58. }
  59. /* Hard reset the MAC. This wipes out *all* configuration. */
  60. static void vsc7326_full_reset(adapter_t* adapter)
  61. {
  62. u32 val;
  63. u32 result = 0xffff;
  64. t1_tpi_read(adapter, A_ELMER0_GPO, &val);
  65. val &= ~1;
  66. t1_tpi_write(adapter, A_ELMER0_GPO, val);
  67. udelay(2);
  68. val |= 0x1; /* Enable mac MAC itself */
  69. val |= 0x800; /* Turn off the red LED */
  70. t1_tpi_write(adapter, A_ELMER0_GPO, val);
  71. mdelay(1);
  72. vsc_write(adapter, REG_SW_RESET, 0x80000001);
  73. do {
  74. mdelay(1);
  75. vsc_read(adapter, REG_SW_RESET, &result);
  76. } while (result != 0x0);
  77. }
  78. static struct init_table vsc7326_reset[] = {
  79. { REG_IFACE_MODE, 0x00000000 },
  80. { REG_CRC_CFG, 0x00000020 },
  81. { REG_PLL_CLK_SPEED, 0x00050c00 },
  82. { REG_PLL_CLK_SPEED, 0x00050c00 },
  83. { REG_MSCH, 0x00002f14 },
  84. { REG_SPI4_MISC, 0x00040409 },
  85. { REG_SPI4_DESKEW, 0x00080000 },
  86. { REG_SPI4_ING_SETUP2, 0x08080004 },
  87. { REG_SPI4_ING_SETUP0, 0x04111004 },
  88. { REG_SPI4_EGR_SETUP0, 0x80001a04 },
  89. { REG_SPI4_ING_SETUP1, 0x02010000 },
  90. { REG_AGE_INC(0), 0x00000000 },
  91. { REG_AGE_INC(1), 0x00000000 },
  92. { REG_ING_CONTROL, 0x0a200011 },
  93. { REG_EGR_CONTROL, 0xa0010091 },
  94. };
  95. static struct init_table vsc7326_portinit[4][22] = {
  96. { /* Port 0 */
  97. /* FIFO setup */
  98. { REG_DBG(0), 0x000004f0 },
  99. { REG_HDX(0), 0x00073101 },
  100. { REG_TEST(0,0), 0x00000022 },
  101. { REG_TEST(1,0), 0x00000022 },
  102. { REG_TOP_BOTTOM(0,0), 0x003f0000 },
  103. { REG_TOP_BOTTOM(1,0), 0x00120000 },
  104. { REG_HIGH_LOW_WM(0,0), 0x07460757 },
  105. { REG_HIGH_LOW_WM(1,0), WM_DISABLE },
  106. { REG_CT_THRHLD(0,0), 0x00000000 },
  107. { REG_CT_THRHLD(1,0), 0x00000000 },
  108. { REG_BUCKE(0), 0x0002ffff },
  109. { REG_BUCKI(0), 0x0002ffff },
  110. { REG_TEST(0,0), 0x00000020 },
  111. { REG_TEST(1,0), 0x00000020 },
  112. /* Port config */
  113. { REG_MAX_LEN(0), 0x00002710 },
  114. { REG_PORT_FAIL(0), 0x00000002 },
  115. { REG_NORMALIZER(0), 0x00000a64 },
  116. { REG_DENORM(0), 0x00000010 },
  117. { REG_STICK_BIT(0), 0x03baa370 },
  118. { REG_DEV_SETUP(0), 0x00000083 },
  119. { REG_DEV_SETUP(0), 0x00000082 },
  120. { REG_MODE_CFG(0), 0x0200259f },
  121. },
  122. { /* Port 1 */
  123. /* FIFO setup */
  124. { REG_DBG(1), 0x000004f0 },
  125. { REG_HDX(1), 0x00073101 },
  126. { REG_TEST(0,1), 0x00000022 },
  127. { REG_TEST(1,1), 0x00000022 },
  128. { REG_TOP_BOTTOM(0,1), 0x007e003f },
  129. { REG_TOP_BOTTOM(1,1), 0x00240012 },
  130. { REG_HIGH_LOW_WM(0,1), 0x07460757 },
  131. { REG_HIGH_LOW_WM(1,1), WM_DISABLE },
  132. { REG_CT_THRHLD(0,1), 0x00000000 },
  133. { REG_CT_THRHLD(1,1), 0x00000000 },
  134. { REG_BUCKE(1), 0x0002ffff },
  135. { REG_BUCKI(1), 0x0002ffff },
  136. { REG_TEST(0,1), 0x00000020 },
  137. { REG_TEST(1,1), 0x00000020 },
  138. /* Port config */
  139. { REG_MAX_LEN(1), 0x00002710 },
  140. { REG_PORT_FAIL(1), 0x00000002 },
  141. { REG_NORMALIZER(1), 0x00000a64 },
  142. { REG_DENORM(1), 0x00000010 },
  143. { REG_STICK_BIT(1), 0x03baa370 },
  144. { REG_DEV_SETUP(1), 0x00000083 },
  145. { REG_DEV_SETUP(1), 0x00000082 },
  146. { REG_MODE_CFG(1), 0x0200259f },
  147. },
  148. { /* Port 2 */
  149. /* FIFO setup */
  150. { REG_DBG(2), 0x000004f0 },
  151. { REG_HDX(2), 0x00073101 },
  152. { REG_TEST(0,2), 0x00000022 },
  153. { REG_TEST(1,2), 0x00000022 },
  154. { REG_TOP_BOTTOM(0,2), 0x00bd007e },
  155. { REG_TOP_BOTTOM(1,2), 0x00360024 },
  156. { REG_HIGH_LOW_WM(0,2), 0x07460757 },
  157. { REG_HIGH_LOW_WM(1,2), WM_DISABLE },
  158. { REG_CT_THRHLD(0,2), 0x00000000 },
  159. { REG_CT_THRHLD(1,2), 0x00000000 },
  160. { REG_BUCKE(2), 0x0002ffff },
  161. { REG_BUCKI(2), 0x0002ffff },
  162. { REG_TEST(0,2), 0x00000020 },
  163. { REG_TEST(1,2), 0x00000020 },
  164. /* Port config */
  165. { REG_MAX_LEN(2), 0x00002710 },
  166. { REG_PORT_FAIL(2), 0x00000002 },
  167. { REG_NORMALIZER(2), 0x00000a64 },
  168. { REG_DENORM(2), 0x00000010 },
  169. { REG_STICK_BIT(2), 0x03baa370 },
  170. { REG_DEV_SETUP(2), 0x00000083 },
  171. { REG_DEV_SETUP(2), 0x00000082 },
  172. { REG_MODE_CFG(2), 0x0200259f },
  173. },
  174. { /* Port 3 */
  175. /* FIFO setup */
  176. { REG_DBG(3), 0x000004f0 },
  177. { REG_HDX(3), 0x00073101 },
  178. { REG_TEST(0,3), 0x00000022 },
  179. { REG_TEST(1,3), 0x00000022 },
  180. { REG_TOP_BOTTOM(0,3), 0x00fc00bd },
  181. { REG_TOP_BOTTOM(1,3), 0x00480036 },
  182. { REG_HIGH_LOW_WM(0,3), 0x07460757 },
  183. { REG_HIGH_LOW_WM(1,3), WM_DISABLE },
  184. { REG_CT_THRHLD(0,3), 0x00000000 },
  185. { REG_CT_THRHLD(1,3), 0x00000000 },
  186. { REG_BUCKE(3), 0x0002ffff },
  187. { REG_BUCKI(3), 0x0002ffff },
  188. { REG_TEST(0,3), 0x00000020 },
  189. { REG_TEST(1,3), 0x00000020 },
  190. /* Port config */
  191. { REG_MAX_LEN(3), 0x00002710 },
  192. { REG_PORT_FAIL(3), 0x00000002 },
  193. { REG_NORMALIZER(3), 0x00000a64 },
  194. { REG_DENORM(3), 0x00000010 },
  195. { REG_STICK_BIT(3), 0x03baa370 },
  196. { REG_DEV_SETUP(3), 0x00000083 },
  197. { REG_DEV_SETUP(3), 0x00000082 },
  198. { REG_MODE_CFG(3), 0x0200259f },
  199. },
  200. };
  201. static void run_table(adapter_t *adapter, struct init_table *ib, int len)
  202. {
  203. int i;
  204. for (i = 0; i < len; i++) {
  205. if (ib[i].addr == INITBLOCK_SLEEP) {
  206. udelay( ib[i].data );
  207. pr_err("sleep %d us\n",ib[i].data);
  208. } else
  209. vsc_write( adapter, ib[i].addr, ib[i].data );
  210. }
  211. }
  212. static int bist_rd(adapter_t *adapter, int moduleid, int address)
  213. {
  214. int data = 0;
  215. u32 result = 0;
  216. if ((address != 0x0) &&
  217. (address != 0x1) &&
  218. (address != 0x2) &&
  219. (address != 0xd) &&
  220. (address != 0xe))
  221. pr_err("No bist address: 0x%x\n", address);
  222. data = ((0x00 << 24) | ((address & 0xff) << 16) | (0x00 << 8) |
  223. ((moduleid & 0xff) << 0));
  224. vsc_write(adapter, REG_RAM_BIST_CMD, data);
  225. udelay(10);
  226. vsc_read(adapter, REG_RAM_BIST_RESULT, &result);
  227. if ((result & (1 << 9)) != 0x0)
  228. pr_err("Still in bist read: 0x%x\n", result);
  229. else if ((result & (1 << 8)) != 0x0)
  230. pr_err("bist read error: 0x%x\n", result);
  231. return result & 0xff;
  232. }
  233. static int bist_wr(adapter_t *adapter, int moduleid, int address, int value)
  234. {
  235. int data = 0;
  236. u32 result = 0;
  237. if ((address != 0x0) &&
  238. (address != 0x1) &&
  239. (address != 0x2) &&
  240. (address != 0xd) &&
  241. (address != 0xe))
  242. pr_err("No bist address: 0x%x\n", address);
  243. if (value > 255)
  244. pr_err("Suspicious write out of range value: 0x%x\n", value);
  245. data = ((0x01 << 24) | ((address & 0xff) << 16) | (value << 8) |
  246. ((moduleid & 0xff) << 0));
  247. vsc_write(adapter, REG_RAM_BIST_CMD, data);
  248. udelay(5);
  249. vsc_read(adapter, REG_RAM_BIST_CMD, &result);
  250. if ((result & (1 << 27)) != 0x0)
  251. pr_err("Still in bist write: 0x%x\n", result);
  252. else if ((result & (1 << 26)) != 0x0)
  253. pr_err("bist write error: 0x%x\n", result);
  254. return 0;
  255. }
  256. static int run_bist(adapter_t *adapter, int moduleid)
  257. {
  258. /*run bist*/
  259. (void) bist_wr(adapter,moduleid, 0x00, 0x02);
  260. (void) bist_wr(adapter,moduleid, 0x01, 0x01);
  261. return 0;
  262. }
  263. static int check_bist(adapter_t *adapter, int moduleid)
  264. {
  265. int result=0;
  266. int column=0;
  267. /*check bist*/
  268. result = bist_rd(adapter,moduleid, 0x02);
  269. column = ((bist_rd(adapter,moduleid, 0x0e)<<8) +
  270. (bist_rd(adapter,moduleid, 0x0d)));
  271. if ((result & 3) != 0x3)
  272. pr_err("Result: 0x%x BIST error in ram %d, column: 0x%04x\n",
  273. result, moduleid, column);
  274. return 0;
  275. }
  276. static int enable_mem(adapter_t *adapter, int moduleid)
  277. {
  278. /*enable mem*/
  279. (void) bist_wr(adapter,moduleid, 0x00, 0x00);
  280. return 0;
  281. }
  282. static int run_bist_all(adapter_t *adapter)
  283. {
  284. int port = 0;
  285. u32 val = 0;
  286. vsc_write(adapter, REG_MEM_BIST, 0x5);
  287. vsc_read(adapter, REG_MEM_BIST, &val);
  288. for (port = 0; port < 12; port++)
  289. vsc_write(adapter, REG_DEV_SETUP(port), 0x0);
  290. udelay(300);
  291. vsc_write(adapter, REG_SPI4_MISC, 0x00040409);
  292. udelay(300);
  293. (void) run_bist(adapter,13);
  294. (void) run_bist(adapter,14);
  295. (void) run_bist(adapter,20);
  296. (void) run_bist(adapter,21);
  297. mdelay(200);
  298. (void) check_bist(adapter,13);
  299. (void) check_bist(adapter,14);
  300. (void) check_bist(adapter,20);
  301. (void) check_bist(adapter,21);
  302. udelay(100);
  303. (void) enable_mem(adapter,13);
  304. (void) enable_mem(adapter,14);
  305. (void) enable_mem(adapter,20);
  306. (void) enable_mem(adapter,21);
  307. udelay(300);
  308. vsc_write(adapter, REG_SPI4_MISC, 0x60040400);
  309. udelay(300);
  310. for (port = 0; port < 12; port++)
  311. vsc_write(adapter, REG_DEV_SETUP(port), 0x1);
  312. udelay(300);
  313. vsc_write(adapter, REG_MEM_BIST, 0x0);
  314. mdelay(10);
  315. return 0;
  316. }
  317. static int mac_intr_handler(struct cmac *mac)
  318. {
  319. return 0;
  320. }
  321. static int mac_intr_enable(struct cmac *mac)
  322. {
  323. return 0;
  324. }
  325. static int mac_intr_disable(struct cmac *mac)
  326. {
  327. return 0;
  328. }
  329. static int mac_intr_clear(struct cmac *mac)
  330. {
  331. return 0;
  332. }
  333. /* Expect MAC address to be in network byte order. */
  334. static int mac_set_address(struct cmac* mac, u8 addr[6])
  335. {
  336. u32 val;
  337. int port = mac->instance->index;
  338. vsc_write(mac->adapter, REG_MAC_LOW_ADDR(port),
  339. (addr[3] << 16) | (addr[4] << 8) | addr[5]);
  340. vsc_write(mac->adapter, REG_MAC_HIGH_ADDR(port),
  341. (addr[0] << 16) | (addr[1] << 8) | addr[2]);
  342. vsc_read(mac->adapter, REG_ING_FFILT_UM_EN, &val);
  343. val &= ~0xf0000000;
  344. vsc_write(mac->adapter, REG_ING_FFILT_UM_EN, val | (port << 28));
  345. vsc_write(mac->adapter, REG_ING_FFILT_MASK0,
  346. 0xffff0000 | (addr[4] << 8) | addr[5]);
  347. vsc_write(mac->adapter, REG_ING_FFILT_MASK1,
  348. 0xffff0000 | (addr[2] << 8) | addr[3]);
  349. vsc_write(mac->adapter, REG_ING_FFILT_MASK2,
  350. 0xffff0000 | (addr[0] << 8) | addr[1]);
  351. return 0;
  352. }
  353. static int mac_get_address(struct cmac *mac, u8 addr[6])
  354. {
  355. u32 addr_lo, addr_hi;
  356. int port = mac->instance->index;
  357. vsc_read(mac->adapter, REG_MAC_LOW_ADDR(port), &addr_lo);
  358. vsc_read(mac->adapter, REG_MAC_HIGH_ADDR(port), &addr_hi);
  359. addr[0] = (u8) (addr_hi >> 16);
  360. addr[1] = (u8) (addr_hi >> 8);
  361. addr[2] = (u8) addr_hi;
  362. addr[3] = (u8) (addr_lo >> 16);
  363. addr[4] = (u8) (addr_lo >> 8);
  364. addr[5] = (u8) addr_lo;
  365. return 0;
  366. }
  367. /* This is intended to reset a port, not the whole MAC */
  368. static int mac_reset(struct cmac *mac)
  369. {
  370. int index = mac->instance->index;
  371. run_table(mac->adapter, vsc7326_portinit[index],
  372. ARRAY_SIZE(vsc7326_portinit[index]));
  373. return 0;
  374. }
  375. static int mac_set_rx_mode(struct cmac *mac, struct t1_rx_mode *rm)
  376. {
  377. u32 v;
  378. int port = mac->instance->index;
  379. vsc_read(mac->adapter, REG_ING_FFILT_UM_EN, &v);
  380. v |= 1 << 12;
  381. if (t1_rx_mode_promisc(rm))
  382. v &= ~(1 << (port + 16));
  383. else
  384. v |= 1 << (port + 16);
  385. vsc_write(mac->adapter, REG_ING_FFILT_UM_EN, v);
  386. return 0;
  387. }
  388. static int mac_set_mtu(struct cmac *mac, int mtu)
  389. {
  390. int port = mac->instance->index;
  391. /* max_len includes header and FCS */
  392. vsc_write(mac->adapter, REG_MAX_LEN(port), mtu + 14 + 4);
  393. return 0;
  394. }
  395. static int mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex,
  396. int fc)
  397. {
  398. u32 v;
  399. int enable, port = mac->instance->index;
  400. if (speed >= 0 && speed != SPEED_10 && speed != SPEED_100 &&
  401. speed != SPEED_1000)
  402. return -1;
  403. if (duplex > 0 && duplex != DUPLEX_FULL)
  404. return -1;
  405. if (speed >= 0) {
  406. vsc_read(mac->adapter, REG_MODE_CFG(port), &v);
  407. enable = v & 3; /* save tx/rx enables */
  408. v &= ~0xf;
  409. v |= 4; /* full duplex */
  410. if (speed == SPEED_1000)
  411. v |= 8; /* GigE */
  412. enable |= v;
  413. vsc_write(mac->adapter, REG_MODE_CFG(port), v);
  414. if (speed == SPEED_1000)
  415. v = 0x82;
  416. else if (speed == SPEED_100)
  417. v = 0x84;
  418. else /* SPEED_10 */
  419. v = 0x86;
  420. vsc_write(mac->adapter, REG_DEV_SETUP(port), v | 1); /* reset */
  421. vsc_write(mac->adapter, REG_DEV_SETUP(port), v);
  422. vsc_read(mac->adapter, REG_DBG(port), &v);
  423. v &= ~0xff00;
  424. if (speed == SPEED_1000)
  425. v |= 0x400;
  426. else if (speed == SPEED_100)
  427. v |= 0x2000;
  428. else /* SPEED_10 */
  429. v |= 0xff00;
  430. vsc_write(mac->adapter, REG_DBG(port), v);
  431. vsc_write(mac->adapter, REG_TX_IFG(port),
  432. speed == SPEED_1000 ? 5 : 0x11);
  433. if (duplex == DUPLEX_HALF)
  434. enable = 0x0; /* 100 or 10 */
  435. else if (speed == SPEED_1000)
  436. enable = 0xc;
  437. else /* SPEED_100 or 10 */
  438. enable = 0x4;
  439. enable |= 0x9 << 10; /* IFG1 */
  440. enable |= 0x6 << 6; /* IFG2 */
  441. enable |= 0x1 << 4; /* VLAN */
  442. enable |= 0x3; /* RX/TX EN */
  443. vsc_write(mac->adapter, REG_MODE_CFG(port), enable);
  444. }
  445. vsc_read(mac->adapter, REG_PAUSE_CFG(port), &v);
  446. v &= 0xfff0ffff;
  447. v |= 0x20000; /* xon/xoff */
  448. if (fc & PAUSE_RX)
  449. v |= 0x40000;
  450. if (fc & PAUSE_TX)
  451. v |= 0x80000;
  452. if (fc == (PAUSE_RX | PAUSE_TX))
  453. v |= 0x10000;
  454. vsc_write(mac->adapter, REG_PAUSE_CFG(port), v);
  455. return 0;
  456. }
  457. static int mac_enable(struct cmac *mac, int which)
  458. {
  459. u32 val;
  460. int port = mac->instance->index;
  461. /* Write the correct WM value when the port is enabled. */
  462. vsc_write(mac->adapter, REG_HIGH_LOW_WM(1,port), WM_ENABLE);
  463. vsc_read(mac->adapter, REG_MODE_CFG(port), &val);
  464. if (which & MAC_DIRECTION_RX)
  465. val |= 0x2;
  466. if (which & MAC_DIRECTION_TX)
  467. val |= 1;
  468. vsc_write(mac->adapter, REG_MODE_CFG(port), val);
  469. return 0;
  470. }
  471. static int mac_disable(struct cmac *mac, int which)
  472. {
  473. u32 val;
  474. int i, port = mac->instance->index;
  475. /* Reset the port, this also writes the correct WM value */
  476. mac_reset(mac);
  477. vsc_read(mac->adapter, REG_MODE_CFG(port), &val);
  478. if (which & MAC_DIRECTION_RX)
  479. val &= ~0x2;
  480. if (which & MAC_DIRECTION_TX)
  481. val &= ~0x1;
  482. vsc_write(mac->adapter, REG_MODE_CFG(port), val);
  483. vsc_read(mac->adapter, REG_MODE_CFG(port), &val);
  484. /* Clear stats */
  485. for (i = 0; i <= 0x3a; ++i)
  486. vsc_write(mac->adapter, CRA(4, port, i), 0);
  487. /* Clear software counters */
  488. memset(&mac->stats, 0, sizeof(struct cmac_statistics));
  489. return 0;
  490. }
  491. static void rmon_update(struct cmac *mac, unsigned int addr, u64 *stat)
  492. {
  493. u32 v, lo;
  494. vsc_read(mac->adapter, addr, &v);
  495. lo = *stat;
  496. *stat = *stat - lo + v;
  497. if (v == 0)
  498. return;
  499. if (v < lo)
  500. *stat += (1ULL << 32);
  501. }
  502. static void port_stats_update(struct cmac *mac)
  503. {
  504. struct {
  505. unsigned int reg;
  506. unsigned int offset;
  507. } hw_stats[] = {
  508. #define HW_STAT(reg, stat_name) \
  509. { reg, (&((struct cmac_statistics *)NULL)->stat_name) - (u64 *)NULL }
  510. /* Rx stats */
  511. HW_STAT(RxUnicast, RxUnicastFramesOK),
  512. HW_STAT(RxMulticast, RxMulticastFramesOK),
  513. HW_STAT(RxBroadcast, RxBroadcastFramesOK),
  514. HW_STAT(Crc, RxFCSErrors),
  515. HW_STAT(RxAlignment, RxAlignErrors),
  516. HW_STAT(RxOversize, RxFrameTooLongErrors),
  517. HW_STAT(RxPause, RxPauseFrames),
  518. HW_STAT(RxJabbers, RxJabberErrors),
  519. HW_STAT(RxFragments, RxRuntErrors),
  520. HW_STAT(RxUndersize, RxRuntErrors),
  521. HW_STAT(RxSymbolCarrier, RxSymbolErrors),
  522. HW_STAT(RxSize1519ToMax, RxJumboFramesOK),
  523. /* Tx stats (skip collision stats as we are full-duplex only) */
  524. HW_STAT(TxUnicast, TxUnicastFramesOK),
  525. HW_STAT(TxMulticast, TxMulticastFramesOK),
  526. HW_STAT(TxBroadcast, TxBroadcastFramesOK),
  527. HW_STAT(TxPause, TxPauseFrames),
  528. HW_STAT(TxUnderrun, TxUnderrun),
  529. HW_STAT(TxSize1519ToMax, TxJumboFramesOK),
  530. }, *p = hw_stats;
  531. unsigned int port = mac->instance->index;
  532. u64 *stats = (u64 *)&mac->stats;
  533. unsigned int i;
  534. for (i = 0; i < ARRAY_SIZE(hw_stats); i++)
  535. rmon_update(mac, CRA(0x4, port, p->reg), stats + p->offset);
  536. rmon_update(mac, REG_TX_OK_BYTES(port), &mac->stats.TxOctetsOK);
  537. rmon_update(mac, REG_RX_OK_BYTES(port), &mac->stats.RxOctetsOK);
  538. rmon_update(mac, REG_RX_BAD_BYTES(port), &mac->stats.RxOctetsBad);
  539. }
  540. /*
  541. * This function is called periodically to accumulate the current values of the
  542. * RMON counters into the port statistics. Since the counters are only 32 bits
  543. * some of them can overflow in less than a minute at GigE speeds, so this
  544. * function should be called every 30 seconds or so.
  545. *
  546. * To cut down on reading costs we update only the octet counters at each tick
  547. * and do a full update at major ticks, which can be every 30 minutes or more.
  548. */
  549. static const struct cmac_statistics *mac_update_statistics(struct cmac *mac,
  550. int flag)
  551. {
  552. if (flag == MAC_STATS_UPDATE_FULL ||
  553. mac->instance->ticks >= MAJOR_UPDATE_TICKS) {
  554. port_stats_update(mac);
  555. mac->instance->ticks = 0;
  556. } else {
  557. int port = mac->instance->index;
  558. rmon_update(mac, REG_RX_OK_BYTES(port),
  559. &mac->stats.RxOctetsOK);
  560. rmon_update(mac, REG_RX_BAD_BYTES(port),
  561. &mac->stats.RxOctetsBad);
  562. rmon_update(mac, REG_TX_OK_BYTES(port),
  563. &mac->stats.TxOctetsOK);
  564. mac->instance->ticks++;
  565. }
  566. return &mac->stats;
  567. }
  568. static void mac_destroy(struct cmac *mac)
  569. {
  570. kfree(mac);
  571. }
  572. static const struct cmac_ops vsc7326_ops = {
  573. .destroy = mac_destroy,
  574. .reset = mac_reset,
  575. .interrupt_handler = mac_intr_handler,
  576. .interrupt_enable = mac_intr_enable,
  577. .interrupt_disable = mac_intr_disable,
  578. .interrupt_clear = mac_intr_clear,
  579. .enable = mac_enable,
  580. .disable = mac_disable,
  581. .set_mtu = mac_set_mtu,
  582. .set_rx_mode = mac_set_rx_mode,
  583. .set_speed_duplex_fc = mac_set_speed_duplex_fc,
  584. .statistics_update = mac_update_statistics,
  585. .macaddress_get = mac_get_address,
  586. .macaddress_set = mac_set_address,
  587. };
  588. static struct cmac *vsc7326_mac_create(adapter_t *adapter, int index)
  589. {
  590. struct cmac *mac;
  591. u32 val;
  592. int i;
  593. mac = kzalloc(sizeof(*mac) + sizeof(cmac_instance), GFP_KERNEL);
  594. if (!mac)
  595. return NULL;
  596. mac->ops = &vsc7326_ops;
  597. mac->instance = (cmac_instance *)(mac + 1);
  598. mac->adapter = adapter;
  599. mac->instance->index = index;
  600. mac->instance->ticks = 0;
  601. i = 0;
  602. do {
  603. u32 vhi, vlo;
  604. vhi = vlo = 0;
  605. t1_tpi_read(adapter, (REG_LOCAL_STATUS << 2) + 4, &vlo);
  606. udelay(1);
  607. t1_tpi_read(adapter, REG_LOCAL_STATUS << 2, &vhi);
  608. udelay(5);
  609. val = (vhi << 16) | vlo;
  610. } while ((++i < 10000) && (val == 0xffffffff));
  611. return mac;
  612. }
  613. static int vsc7326_mac_reset(adapter_t *adapter)
  614. {
  615. vsc7326_full_reset(adapter);
  616. (void) run_bist_all(adapter);
  617. run_table(adapter, vsc7326_reset, ARRAY_SIZE(vsc7326_reset));
  618. return 0;
  619. }
  620. const struct gmac t1_vsc7326_ops = {
  621. .stats_update_period = STATS_TICK_SECS,
  622. .create = vsc7326_mac_create,
  623. .reset = vsc7326_mac_reset,
  624. };