vsc7326.c 20 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. #define MAX_MTU 9600
  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. CH_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. /* CH_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. /* CH_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. CH_ERR("sleep %d us\n",ib[i].data);
  209. } else {
  210. vsc_write( adapter, ib[i].addr, ib[i].data );
  211. }
  212. }
  213. }
  214. static int bist_rd(adapter_t *adapter, int moduleid, int address)
  215. {
  216. int data=0;
  217. u32 result=0;
  218. if( (address != 0x0) &&
  219. (address != 0x1) &&
  220. (address != 0x2) &&
  221. (address != 0xd) &&
  222. (address != 0xe))
  223. CH_ERR("No bist address: 0x%x\n", address);
  224. data = ((0x00 << 24) | ((address & 0xff) << 16) | (0x00 << 8) |
  225. ((moduleid & 0xff) << 0));
  226. vsc_write(adapter, REG_RAM_BIST_CMD, data);
  227. udelay(10);
  228. vsc_read(adapter, REG_RAM_BIST_RESULT, &result);
  229. if((result & (1<<9)) != 0x0)
  230. CH_ERR("Still in bist read: 0x%x\n", result);
  231. else if((result & (1<<8)) != 0x0)
  232. CH_ERR("bist read error: 0x%x\n", result);
  233. return(result & 0xff);
  234. }
  235. static int bist_wr(adapter_t *adapter, int moduleid, int address, int value)
  236. {
  237. int data=0;
  238. u32 result=0;
  239. if( (address != 0x0) &&
  240. (address != 0x1) &&
  241. (address != 0x2) &&
  242. (address != 0xd) &&
  243. (address != 0xe))
  244. CH_ERR("No bist address: 0x%x\n", address);
  245. if( value>255 )
  246. CH_ERR("Suspicious write out of range value: 0x%x\n", value);
  247. data = ((0x01 << 24) | ((address & 0xff) << 16) | (value << 8) |
  248. ((moduleid & 0xff) << 0));
  249. vsc_write(adapter, REG_RAM_BIST_CMD, data);
  250. udelay(5);
  251. vsc_read(adapter, REG_RAM_BIST_CMD, &result);
  252. if((result & (1<<27)) != 0x0)
  253. CH_ERR("Still in bist write: 0x%x\n", result);
  254. else if((result & (1<<26)) != 0x0)
  255. CH_ERR("bist write error: 0x%x\n", result);
  256. return(0);
  257. }
  258. static int run_bist(adapter_t *adapter, int moduleid)
  259. {
  260. /*run bist*/
  261. (void) bist_wr(adapter,moduleid, 0x00, 0x02);
  262. (void) bist_wr(adapter,moduleid, 0x01, 0x01);
  263. return(0);
  264. }
  265. static int check_bist(adapter_t *adapter, int moduleid)
  266. {
  267. int result=0;
  268. int column=0;
  269. /*check bist*/
  270. result = bist_rd(adapter,moduleid, 0x02);
  271. column = ((bist_rd(adapter,moduleid, 0x0e)<<8) +
  272. (bist_rd(adapter,moduleid, 0x0d)));
  273. if ((result & 3) != 0x3)
  274. CH_ERR("Result: 0x%x BIST error in ram %d, column: 0x%04x\n",
  275. result, moduleid, column);
  276. return(0);
  277. }
  278. static int enable_mem(adapter_t *adapter, int moduleid)
  279. {
  280. /*enable mem*/
  281. (void) bist_wr(adapter,moduleid, 0x00, 0x00);
  282. return(0);
  283. }
  284. static int run_bist_all(adapter_t *adapter)
  285. {
  286. int port=0;
  287. u32 val=0;
  288. vsc_write(adapter, REG_MEM_BIST, 0x5);
  289. vsc_read(adapter, REG_MEM_BIST, &val);
  290. for(port=0; port<12; port++){
  291. vsc_write(adapter, REG_DEV_SETUP(port), 0x0);
  292. }
  293. udelay(300);
  294. vsc_write(adapter, REG_SPI4_MISC, 0x00040409);
  295. udelay(300);
  296. (void) run_bist(adapter,13);
  297. (void) run_bist(adapter,14);
  298. (void) run_bist(adapter,20);
  299. (void) run_bist(adapter,21);
  300. mdelay(200);
  301. (void) check_bist(adapter,13);
  302. (void) check_bist(adapter,14);
  303. (void) check_bist(adapter,20);
  304. (void) check_bist(adapter,21);
  305. udelay(100);
  306. (void) enable_mem(adapter,13);
  307. (void) enable_mem(adapter,14);
  308. (void) enable_mem(adapter,20);
  309. (void) enable_mem(adapter,21);
  310. udelay(300);
  311. vsc_write(adapter, REG_SPI4_MISC, 0x60040400);
  312. udelay(300);
  313. for(port=0; port<12; port++){
  314. vsc_write(adapter, REG_DEV_SETUP(port), 0x1);
  315. }
  316. udelay(300);
  317. vsc_write(adapter, REG_MEM_BIST, 0x0);
  318. mdelay(10);
  319. return(0);
  320. }
  321. static int mac_intr_handler(struct cmac *mac)
  322. {
  323. return 0;
  324. }
  325. static int mac_intr_enable(struct cmac *mac)
  326. {
  327. return 0;
  328. }
  329. static int mac_intr_disable(struct cmac *mac)
  330. {
  331. return 0;
  332. }
  333. static int mac_intr_clear(struct cmac *mac)
  334. {
  335. return 0;
  336. }
  337. /* Expect MAC address to be in network byte order. */
  338. static int mac_set_address(struct cmac* mac, u8 addr[6])
  339. {
  340. u32 val;
  341. int port = mac->instance->index;
  342. vsc_write(mac->adapter, REG_MAC_LOW_ADDR(port),
  343. (addr[3] << 16) | (addr[4] << 8) | addr[5]);
  344. vsc_write(mac->adapter, REG_MAC_HIGH_ADDR(port),
  345. (addr[0] << 16) | (addr[1] << 8) | addr[2]);
  346. vsc_read(mac->adapter, REG_ING_FFILT_UM_EN, &val);
  347. val &= ~0xf0000000;
  348. vsc_write(mac->adapter, REG_ING_FFILT_UM_EN, val | (port << 28));
  349. vsc_write(mac->adapter, REG_ING_FFILT_MASK0,
  350. 0xffff0000 | (addr[4] << 8) | addr[5]);
  351. vsc_write(mac->adapter, REG_ING_FFILT_MASK1,
  352. 0xffff0000 | (addr[2] << 8) | addr[3]);
  353. vsc_write(mac->adapter, REG_ING_FFILT_MASK2,
  354. 0xffff0000 | (addr[0] << 8) | addr[1]);
  355. return 0;
  356. }
  357. static int mac_get_address(struct cmac *mac, u8 addr[6])
  358. {
  359. u32 addr_lo, addr_hi;
  360. int port = mac->instance->index;
  361. vsc_read(mac->adapter, REG_MAC_LOW_ADDR(port), &addr_lo);
  362. vsc_read(mac->adapter, REG_MAC_HIGH_ADDR(port), &addr_hi);
  363. addr[0] = (u8) (addr_hi >> 16);
  364. addr[1] = (u8) (addr_hi >> 8);
  365. addr[2] = (u8) addr_hi;
  366. addr[3] = (u8) (addr_lo >> 16);
  367. addr[4] = (u8) (addr_lo >> 8);
  368. addr[5] = (u8) addr_lo;
  369. return 0;
  370. }
  371. /* This is intended to reset a port, not the whole MAC */
  372. static int mac_reset(struct cmac *mac)
  373. {
  374. int index = mac->instance->index;
  375. run_table(mac->adapter, vsc7326_portinit[index],
  376. ARRAY_SIZE(vsc7326_portinit[index]));
  377. return 0;
  378. }
  379. static int mac_set_rx_mode(struct cmac *mac, struct t1_rx_mode *rm)
  380. {
  381. u32 v;
  382. int port = mac->instance->index;
  383. vsc_read(mac->adapter, REG_ING_FFILT_UM_EN, &v);
  384. v |= 1 << 12;
  385. if (t1_rx_mode_promisc(rm))
  386. v &= ~(1 << (port + 16));
  387. else
  388. v |= 1 << (port + 16);
  389. vsc_write(mac->adapter, REG_ING_FFILT_UM_EN, v);
  390. return 0;
  391. }
  392. static int mac_set_mtu(struct cmac *mac, int mtu)
  393. {
  394. int port = mac->instance->index;
  395. if (mtu > MAX_MTU)
  396. return -EINVAL;
  397. /* max_len includes header and FCS */
  398. vsc_write(mac->adapter, REG_MAX_LEN(port), mtu + 14 + 4);
  399. return 0;
  400. }
  401. static int mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex,
  402. int fc)
  403. {
  404. u32 v;
  405. int enable, port = mac->instance->index;
  406. if (speed >= 0 && speed != SPEED_10 && speed != SPEED_100 &&
  407. speed != SPEED_1000)
  408. return -1;
  409. if (duplex > 0 && duplex != DUPLEX_FULL)
  410. return -1;
  411. if (speed >= 0) {
  412. vsc_read(mac->adapter, REG_MODE_CFG(port), &v);
  413. enable = v & 3; /* save tx/rx enables */
  414. v &= ~0xf;
  415. v |= 4; /* full duplex */
  416. if (speed == SPEED_1000)
  417. v |= 8; /* GigE */
  418. enable |= v;
  419. vsc_write(mac->adapter, REG_MODE_CFG(port), v);
  420. if (speed == SPEED_1000)
  421. v = 0x82;
  422. else if (speed == SPEED_100)
  423. v = 0x84;
  424. else /* SPEED_10 */
  425. v = 0x86;
  426. vsc_write(mac->adapter, REG_DEV_SETUP(port), v | 1); /* reset */
  427. vsc_write(mac->adapter, REG_DEV_SETUP(port), v);
  428. vsc_read(mac->adapter, REG_DBG(port), &v);
  429. v &= ~0xff00;
  430. if (speed == SPEED_1000)
  431. v |= 0x400;
  432. else if (speed == SPEED_100)
  433. v |= 0x2000;
  434. else /* SPEED_10 */
  435. v |= 0xff00;
  436. vsc_write(mac->adapter, REG_DBG(port), v);
  437. vsc_write(mac->adapter, REG_TX_IFG(port),
  438. speed == SPEED_1000 ? 5 : 0x11);
  439. if (duplex == DUPLEX_HALF)
  440. enable = 0x0; /* 100 or 10 */
  441. else if (speed == SPEED_1000)
  442. enable = 0xc;
  443. else /* SPEED_100 or 10 */
  444. enable = 0x4;
  445. enable |= 0x9 << 10; /* IFG1 */
  446. enable |= 0x6 << 6; /* IFG2 */
  447. enable |= 0x1 << 4; /* VLAN */
  448. enable |= 0x3; /* RX/TX EN */
  449. vsc_write(mac->adapter, REG_MODE_CFG(port), enable);
  450. }
  451. vsc_read(mac->adapter, REG_PAUSE_CFG(port), &v);
  452. v &= 0xfff0ffff;
  453. v |= 0x20000; /* xon/xoff */
  454. if (fc & PAUSE_RX)
  455. v |= 0x40000;
  456. if (fc & PAUSE_TX)
  457. v |= 0x80000;
  458. if (fc == (PAUSE_RX | PAUSE_TX))
  459. v |= 0x10000;
  460. vsc_write(mac->adapter, REG_PAUSE_CFG(port), v);
  461. return 0;
  462. }
  463. static int mac_enable(struct cmac *mac, int which)
  464. {
  465. u32 val;
  466. int port = mac->instance->index;
  467. /* Write the correct WM value when the port is enabled. */
  468. vsc_write(mac->adapter, REG_HIGH_LOW_WM(1,port), WM_ENABLE);
  469. vsc_read(mac->adapter, REG_MODE_CFG(port), &val);
  470. if (which & MAC_DIRECTION_RX)
  471. val |= 0x2;
  472. if (which & MAC_DIRECTION_TX)
  473. val |= 1;
  474. vsc_write(mac->adapter, REG_MODE_CFG(port), val);
  475. return 0;
  476. }
  477. static int mac_disable(struct cmac *mac, int which)
  478. {
  479. u32 val;
  480. int i, port = mac->instance->index;
  481. /* Reset the port, this also writes the correct WM value */
  482. mac_reset(mac);
  483. vsc_read(mac->adapter, REG_MODE_CFG(port), &val);
  484. if (which & MAC_DIRECTION_RX)
  485. val &= ~0x2;
  486. if (which & MAC_DIRECTION_TX)
  487. val &= ~0x1;
  488. vsc_write(mac->adapter, REG_MODE_CFG(port), val);
  489. vsc_read(mac->adapter, REG_MODE_CFG(port), &val);
  490. /* Clear stats */
  491. for (i = 0; i <= 0x3a; ++i)
  492. vsc_write(mac->adapter, CRA(4, port, i), 0);
  493. /* Clear sofware counters */
  494. memset(&mac->stats, 0, sizeof(struct cmac_statistics));
  495. return 0;
  496. }
  497. static void rmon_update(struct cmac *mac, unsigned int addr, u64 *stat)
  498. {
  499. u32 v, lo;
  500. vsc_read(mac->adapter, addr, &v);
  501. lo = *stat;
  502. *stat = *stat - lo + v;
  503. if (v == 0)
  504. return;
  505. if (v < lo)
  506. *stat += (1ULL << 32);
  507. }
  508. static void port_stats_update(struct cmac *mac)
  509. {
  510. int port = mac->instance->index;
  511. /* Rx stats */
  512. rmon_update(mac, REG_RX_OK_BYTES(port), &mac->stats.RxOctetsOK);
  513. rmon_update(mac, REG_RX_BAD_BYTES(port), &mac->stats.RxOctetsBad);
  514. rmon_update(mac, REG_RX_UNICAST(port), &mac->stats.RxUnicastFramesOK);
  515. rmon_update(mac, REG_RX_MULTICAST(port),
  516. &mac->stats.RxMulticastFramesOK);
  517. rmon_update(mac, REG_RX_BROADCAST(port),
  518. &mac->stats.RxBroadcastFramesOK);
  519. rmon_update(mac, REG_CRC(port), &mac->stats.RxFCSErrors);
  520. rmon_update(mac, REG_RX_ALIGNMENT(port), &mac->stats.RxAlignErrors);
  521. rmon_update(mac, REG_RX_OVERSIZE(port),
  522. &mac->stats.RxFrameTooLongErrors);
  523. rmon_update(mac, REG_RX_PAUSE(port), &mac->stats.RxPauseFrames);
  524. rmon_update(mac, REG_RX_JABBERS(port), &mac->stats.RxJabberErrors);
  525. rmon_update(mac, REG_RX_FRAGMENTS(port), &mac->stats.RxRuntErrors);
  526. rmon_update(mac, REG_RX_UNDERSIZE(port), &mac->stats.RxRuntErrors);
  527. rmon_update(mac, REG_RX_SYMBOL_CARRIER(port),
  528. &mac->stats.RxSymbolErrors);
  529. rmon_update(mac, REG_RX_SIZE_1519_TO_MAX(port),
  530. &mac->stats.RxJumboFramesOK);
  531. /* Tx stats (skip collision stats as we are full-duplex only) */
  532. rmon_update(mac, REG_TX_OK_BYTES(port), &mac->stats.TxOctetsOK);
  533. rmon_update(mac, REG_TX_UNICAST(port), &mac->stats.TxUnicastFramesOK);
  534. rmon_update(mac, REG_TX_MULTICAST(port),
  535. &mac->stats.TxMulticastFramesOK);
  536. rmon_update(mac, REG_TX_BROADCAST(port),
  537. &mac->stats.TxBroadcastFramesOK);
  538. rmon_update(mac, REG_TX_PAUSE(port), &mac->stats.TxPauseFrames);
  539. rmon_update(mac, REG_TX_UNDERRUN(port), &mac->stats.TxUnderrun);
  540. rmon_update(mac, REG_TX_SIZE_1519_TO_MAX(port),
  541. &mac->stats.TxJumboFramesOK);
  542. }
  543. /*
  544. * This function is called periodically to accumulate the current values of the
  545. * RMON counters into the port statistics. Since the counters are only 32 bits
  546. * some of them can overflow in less than a minute at GigE speeds, so this
  547. * function should be called every 30 seconds or so.
  548. *
  549. * To cut down on reading costs we update only the octet counters at each tick
  550. * and do a full update at major ticks, which can be every 30 minutes or more.
  551. */
  552. static const struct cmac_statistics *mac_update_statistics(struct cmac *mac,
  553. int flag)
  554. {
  555. if (flag == MAC_STATS_UPDATE_FULL ||
  556. mac->instance->ticks >= MAJOR_UPDATE_TICKS) {
  557. port_stats_update(mac);
  558. mac->instance->ticks = 0;
  559. } else {
  560. int port = mac->instance->index;
  561. rmon_update(mac, REG_RX_OK_BYTES(port),
  562. &mac->stats.RxOctetsOK);
  563. rmon_update(mac, REG_RX_BAD_BYTES(port),
  564. &mac->stats.RxOctetsBad);
  565. rmon_update(mac, REG_TX_OK_BYTES(port),
  566. &mac->stats.TxOctetsOK);
  567. mac->instance->ticks++;
  568. }
  569. return &mac->stats;
  570. }
  571. static void mac_destroy(struct cmac *mac)
  572. {
  573. kfree(mac);
  574. }
  575. static struct cmac_ops vsc7326_ops = {
  576. .destroy = mac_destroy,
  577. .reset = mac_reset,
  578. .interrupt_handler = mac_intr_handler,
  579. .interrupt_enable = mac_intr_enable,
  580. .interrupt_disable = mac_intr_disable,
  581. .interrupt_clear = mac_intr_clear,
  582. .enable = mac_enable,
  583. .disable = mac_disable,
  584. .set_mtu = mac_set_mtu,
  585. .set_rx_mode = mac_set_rx_mode,
  586. .set_speed_duplex_fc = mac_set_speed_duplex_fc,
  587. .statistics_update = mac_update_statistics,
  588. .macaddress_get = mac_get_address,
  589. .macaddress_set = mac_set_address,
  590. };
  591. static struct cmac *vsc7326_mac_create(adapter_t *adapter, int index)
  592. {
  593. struct cmac *mac;
  594. u32 val;
  595. int i;
  596. mac = kzalloc(sizeof(*mac) + sizeof(cmac_instance), GFP_KERNEL);
  597. if (!mac)
  598. return NULL;
  599. mac->ops = &vsc7326_ops;
  600. mac->instance = (cmac_instance *)(mac + 1);
  601. mac->adapter = adapter;
  602. mac->instance->index = index;
  603. mac->instance->ticks = 0;
  604. i = 0;
  605. do {
  606. u32 vhi, vlo;
  607. vhi = vlo = 0;
  608. t1_tpi_read(adapter, (REG_LOCAL_STATUS << 2) + 4, &vlo);
  609. udelay(1);
  610. t1_tpi_read(adapter, REG_LOCAL_STATUS << 2, &vhi);
  611. udelay(5);
  612. val = (vhi << 16) | vlo;
  613. } while ((++i < 10000) && (val == 0xffffffff));
  614. return mac;
  615. }
  616. static int vsc7326_mac_reset(adapter_t *adapter)
  617. {
  618. vsc7326_full_reset(adapter);
  619. (void) run_bist_all(adapter);
  620. run_table(adapter, vsc7326_reset, ARRAY_SIZE(vsc7326_reset));
  621. return 0;
  622. }
  623. struct gmac t1_vsc7326_ops = {
  624. .stats_update_period = STATS_TICK_SECS,
  625. .create = vsc7326_mac_create,
  626. .reset = vsc7326_mac_reset,
  627. };