vsc7326.c 19 KB

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