rtl8366_mii.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  1. /*
  2. * (C) Copyright 2010
  3. * Michael Kurz <michi.kurz@googlemail.com>.
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. #include <common.h>
  24. #include <net.h>
  25. #include <netdev.h>
  26. #include <miiphy.h>
  27. #include MII_GPIOINCLUDE
  28. #include "rtl8366.h"
  29. #ifdef DEBUG_RTL8366
  30. #define DBG(fmt,args...) printf (fmt ,##args)
  31. #else
  32. #define DBG(fmt,args...)
  33. #endif
  34. //-------------------------------------------------------------------
  35. // Soft SMI functions
  36. //-------------------------------------------------------------------
  37. #define DELAY 2
  38. static void smi_init(void)
  39. {
  40. MII_SDAINPUT;
  41. MII_SCKINPUT;
  42. MII_SETSDA(1);
  43. MII_SETSCK(1);
  44. udelay(20);
  45. }
  46. static void smi_start(void)
  47. {
  48. /*
  49. * rtl8366 chip needs a extra clock with
  50. * SDA high before start condition
  51. */
  52. /* set gpio pins output */
  53. MII_SDAOUTPUT;
  54. MII_SCKOUTPUT;
  55. udelay(DELAY);
  56. /* set initial state: SCK:0, SDA:1 */
  57. MII_SETSCK(0);
  58. MII_SETSDA(1);
  59. udelay(DELAY);
  60. /* toggle clock */
  61. MII_SETSCK(1);
  62. udelay(DELAY);
  63. MII_SETSCK(0);
  64. udelay(DELAY);
  65. /* start condition */
  66. MII_SETSCK(1);
  67. udelay(DELAY);
  68. MII_SETSDA(0);
  69. udelay(DELAY);
  70. MII_SETSCK(0);
  71. udelay(DELAY);
  72. MII_SETSDA(1);
  73. }
  74. static void smi_stop(void)
  75. {
  76. /*
  77. * rtl8366 chip needs a extra clock with
  78. * SDA high after stop condition
  79. */
  80. /* stop condition */
  81. udelay(DELAY);
  82. MII_SETSDA(0);
  83. MII_SETSCK(1);
  84. udelay(DELAY);
  85. MII_SETSDA(1);
  86. udelay(DELAY);
  87. MII_SETSCK(1);
  88. udelay(DELAY);
  89. MII_SETSCK(0);
  90. udelay(DELAY);
  91. /* toggle clock */
  92. MII_SETSCK(1);
  93. udelay(DELAY);
  94. MII_SETSCK(0);
  95. udelay(DELAY);
  96. MII_SETSCK(1);
  97. /* set gpio pins input */
  98. MII_SDAINPUT;
  99. MII_SCKINPUT;
  100. }
  101. static void smi_writeBits(uint32_t data, uint8_t length)
  102. {
  103. uint8_t test;
  104. for( ; length > 0; length--) {
  105. udelay(DELAY);
  106. /* output data */
  107. test = (((data & (1 << (length - 1))) != 0) ? 1 : 0);
  108. MII_SETSDA(test);
  109. udelay(DELAY);
  110. /* toogle clock */
  111. MII_SETSCK(1);
  112. udelay(DELAY);
  113. MII_SETSCK(0);
  114. }
  115. }
  116. static uint32_t smi_readBits(uint8_t length)
  117. {
  118. uint32_t ret;
  119. MII_SDAINPUT;
  120. for(ret = 0 ; length > 0; length--) {
  121. udelay(DELAY);
  122. ret <<= 1;
  123. /* toogle clock */
  124. MII_SETSCK(1);
  125. udelay(DELAY);
  126. ret |= MII_GETSDA;
  127. MII_SETSCK(0);
  128. }
  129. MII_SDAOUTPUT;
  130. return ret;
  131. }
  132. static int smi_waitAck(void)
  133. {
  134. uint32_t retry = 0;
  135. while (smi_readBits(1)) {
  136. if (retry++ == 5)
  137. return -1;
  138. }
  139. return 0;
  140. }
  141. static int smi_read(uint32_t reg, uint32_t *data)
  142. {
  143. uint32_t rawData;
  144. /* send start condition */
  145. smi_start();
  146. /* send CTRL1 code: 0b1010*/
  147. smi_writeBits(0x0a, 4);
  148. /* send CTRL2 code: 0b100 */
  149. smi_writeBits(0x04, 3);
  150. /* send READ command */
  151. smi_writeBits(0x01, 1);
  152. /* wait for ACK */
  153. if (smi_waitAck())
  154. return -1;
  155. /* send address low */
  156. smi_writeBits(reg & 0xFF, 8);
  157. /* wait for ACK */
  158. if (smi_waitAck())
  159. return -1;
  160. /* send address high */
  161. smi_writeBits((reg & 0xFF00) >> 8, 8);
  162. /* wait for ACK */
  163. if (smi_waitAck())
  164. return -1;
  165. /* read data low */
  166. rawData = (smi_readBits(8) & 0xFF);
  167. /* send ACK */
  168. smi_writeBits(0, 1);
  169. /* read data high */
  170. rawData |= (smi_readBits(8) & 0xFF) << 8;
  171. /* send NACK */
  172. smi_writeBits(1, 1);
  173. /* send stop condition */
  174. smi_stop();
  175. if (data)
  176. *data = rawData;
  177. return 0;
  178. }
  179. static int smi_write(uint32_t reg, uint32_t data)
  180. {
  181. /* send start condition */
  182. smi_start();
  183. /* send CTRL1 code: 0b1010*/
  184. smi_writeBits(0x0a, 4);
  185. /* send CTRL2 code: 0b100 */
  186. smi_writeBits(0x04, 3);
  187. /* send WRITE command */
  188. smi_writeBits(0x00, 1);
  189. /* wait for ACK */
  190. if (smi_waitAck())
  191. return -1;
  192. /* send address low */
  193. smi_writeBits(reg & 0xFF, 8);
  194. /* wait for ACK */
  195. if (smi_waitAck())
  196. return -1;
  197. /* send address high */
  198. smi_writeBits((reg & 0xFF00) >> 8, 8);
  199. /* wait for ACK */
  200. if (smi_waitAck())
  201. return -1;
  202. /* send data low */
  203. smi_writeBits(data & 0xFF, 8);
  204. /* wait for ACK */
  205. if (smi_waitAck())
  206. return -1;
  207. /* send data high */
  208. smi_writeBits((data & 0xFF00) >> 8, 8);
  209. /* wait for ACK */
  210. if (smi_waitAck())
  211. return -1;
  212. /* send stop condition */
  213. smi_stop();
  214. return 0;
  215. }
  216. //-------------------------------------------------------------------
  217. // Switch register read / write functions
  218. //-------------------------------------------------------------------
  219. static int rtl8366_readRegister(uint32_t reg, uint16_t *data)
  220. {
  221. uint32_t regData;
  222. DBG("rtl8366: read register=%#04x, data=", reg);
  223. if (smi_read(reg, &regData)) {
  224. printf("\nrtl8366 smi read failed!\n");
  225. return -1;
  226. }
  227. if (data)
  228. *data = regData;
  229. DBG("%#04x\n", regData);
  230. return 0;
  231. }
  232. static int rtl8366_writeRegister(uint32_t reg, uint16_t data)
  233. {
  234. DBG("rtl8366: write register=%#04x, data=%#04x\n", reg, data);
  235. if (smi_write(reg, data)) {
  236. printf("rtl8366 smi write failed!\n");
  237. return -1;
  238. }
  239. return 0;
  240. }
  241. static int rtl8366_setRegisterBit(uint32_t reg, uint32_t bitNum, uint32_t value)
  242. {
  243. uint16_t regData;
  244. if (bitNum >= 16)
  245. return -1;
  246. if (rtl8366_readRegister(reg, &regData))
  247. return -1;
  248. if (value)
  249. regData |= (1 << bitNum);
  250. else
  251. regData &= ~(1 << bitNum);
  252. if (rtl8366_writeRegister(reg, regData))
  253. return -1;
  254. return 0;
  255. }
  256. //-------------------------------------------------------------------
  257. // MII PHY read / write functions
  258. //-------------------------------------------------------------------
  259. static int rtl8366_getPhyReg(uint32_t phyNum, uint32_t reg, uint16_t *data)
  260. {
  261. uint16_t phyAddr, regData;
  262. if (phyNum > RTL8366S_PHY_NO_MAX) {
  263. printf("rtl8366s: invalid phy number!\n");
  264. return -1;
  265. }
  266. if (phyNum > RTL8366S_PHY_ADDR_MAX) {
  267. printf("rtl8366s: invalid phy register number!\n");
  268. return -1;
  269. }
  270. if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG,
  271. RTL8366S_PHY_CTRL_READ))
  272. return -1;
  273. phyAddr = 0x8000 | (1 << (phyNum + RTL8366S_PHY_NO_OFFSET))
  274. | (reg & RTL8366S_PHY_REG_MASK);
  275. if (rtl8366_writeRegister(phyAddr, 0))
  276. return -1;
  277. if (rtl8366_readRegister(RTL8366S_PHY_ACCESS_DATA_REG, &regData))
  278. return -1;
  279. if (data)
  280. *data = regData;
  281. return 0;
  282. }
  283. static int rtl8366_setPhyReg(uint32_t phyNum, uint32_t reg, uint16_t data)
  284. {
  285. uint16_t phyAddr;
  286. if (phyNum > RTL8366S_PHY_NO_MAX) {
  287. printf("rtl8366s: invalid phy number!\n");
  288. return -1;
  289. }
  290. if (phyNum > RTL8366S_PHY_ADDR_MAX) {
  291. printf("rtl8366s: invalid phy register number!\n");
  292. return -1;
  293. }
  294. if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG,
  295. RTL8366S_PHY_CTRL_WRITE))
  296. return -1;
  297. phyAddr = 0x8000 | (1 << (phyNum + RTL8366S_PHY_NO_OFFSET))
  298. | (reg & RTL8366S_PHY_REG_MASK);
  299. if (rtl8366_writeRegister(phyAddr, data))
  300. return -1;
  301. return 0;
  302. }
  303. static int rtl8366_miiread(char *devname, uchar phy_adr, uchar reg, ushort *data)
  304. {
  305. uint16_t regData;
  306. DBG("rtl8366_miiread: devname=%s, addr=%#02x, reg=%#02x\n",
  307. devname, phy_adr, reg);
  308. if (strcmp(devname, RTL8366_DEVNAME) != 0)
  309. return -1;
  310. if (rtl8366_getPhyReg(phy_adr, reg, &regData)) {
  311. printf("rtl8366_miiread: write failed!\n");
  312. return -1;
  313. }
  314. if (data)
  315. *data = regData;
  316. return 0;
  317. }
  318. static int rtl8366_miiwrite(char *devname, uchar phy_adr, uchar reg, ushort data)
  319. {
  320. DBG("rtl8366_miiwrite: devname=%s, addr=%#02x, reg=%#02x, data=%#04x\n",
  321. devname, phy_adr, reg, data);
  322. if (strcmp(devname, RTL8366_DEVNAME) != 0)
  323. return -1;
  324. if (rtl8366_setPhyReg(phy_adr, reg, data)) {
  325. printf("rtl8366_miiwrite: write failed!\n");
  326. return -1;
  327. }
  328. return 0;
  329. }
  330. int rtl8366_mii_register(bd_t *bis)
  331. {
  332. miiphy_register(strdup(RTL8366_DEVNAME), rtl8366_miiread,
  333. rtl8366_miiwrite);
  334. return 0;
  335. }
  336. //-------------------------------------------------------------------
  337. // Switch management functions
  338. //-------------------------------------------------------------------
  339. int rtl8366s_setGreenFeature(uint32_t tx, uint32_t rx)
  340. {
  341. if (rtl8366_setRegisterBit(RTL8366S_GREEN_FEATURE_REG,
  342. RTL8366S_GREEN_FEATURE_TX_BIT, tx))
  343. return -1;
  344. if (rtl8366_setRegisterBit(RTL8366S_GREEN_FEATURE_REG,
  345. RTL8366S_GREEN_FEATURE_RX_BIT, rx))
  346. return -1;
  347. return 0;
  348. }
  349. int rtl8366s_setPowerSaving(uint32_t phyNum, uint32_t enabled)
  350. {
  351. uint16_t regData;
  352. if (phyNum > RTL8366S_PHY_NO_MAX)
  353. return -1;
  354. if (rtl8366_getPhyReg(phyNum, 12, &regData))
  355. return -1;
  356. if (enabled)
  357. regData |= (1 << 12);
  358. else
  359. regData &= ~(1 << 12);
  360. if (rtl8366_setPhyReg(phyNum, 12, regData))
  361. return -1;
  362. return 0;
  363. }
  364. int rtl8366s_setGreenEthernet(uint32_t greenFeature, uint32_t powerSaving)
  365. {
  366. uint32_t phyNum, i;
  367. uint16_t regData;
  368. const uint16_t greenSettings[][2] =
  369. {
  370. {0xBE5B,0x3500},
  371. {0xBE5C,0xB975},
  372. {0xBE5D,0xB9B9},
  373. {0xBE77,0xA500},
  374. {0xBE78,0x5A78},
  375. {0xBE79,0x6478}
  376. };
  377. if (rtl8366_readRegister(RTL8366S_MODEL_ID_REG, &regData))
  378. return -1;
  379. switch (regData)
  380. {
  381. case 0x0000:
  382. for (i = 0; i < 6; i++) {
  383. if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG, RTL8366S_PHY_CTRL_WRITE))
  384. return -1;
  385. if (rtl8366_writeRegister(greenSettings[i][0], greenSettings[i][1]))
  386. return -1;
  387. }
  388. break;
  389. case RTL8366S_MODEL_8366SR:
  390. if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG, RTL8366S_PHY_CTRL_WRITE))
  391. return -1;
  392. if (rtl8366_writeRegister(greenSettings[0][0], greenSettings[0][1]))
  393. return -1;
  394. break;
  395. default:
  396. printf("rtl8366s_initChip: unsupported chip found!\n");
  397. return -1;
  398. }
  399. if (rtl8366s_setGreenFeature(greenFeature, powerSaving))
  400. return -1;
  401. for (phyNum = 0; phyNum <= RTL8366S_PHY_NO_MAX; phyNum++) {
  402. if (rtl8366s_setPowerSaving(phyNum, powerSaving))
  403. return -1;
  404. }
  405. return 0;
  406. }
  407. int rtl8366s_setCPUPortMask(uint8_t port, uint32_t enabled)
  408. {
  409. if(port >= 6){
  410. printf("rtl8366s_setCPUPortMask: invalid port number\n");
  411. return -1;
  412. }
  413. return rtl8366_setRegisterBit(RTL8366S_CPU_CTRL_REG, port, enabled);
  414. }
  415. int rtl8366s_setCPUDisableInsTag(uint32_t enable)
  416. {
  417. return rtl8366_setRegisterBit(RTL8366S_CPU_CTRL_REG,
  418. RTL8366S_CPU_INSTAG_BIT, enable);
  419. }
  420. int rtl8366s_setCPUDropUnda(uint32_t enable)
  421. {
  422. return rtl8366_setRegisterBit(RTL8366S_CPU_CTRL_REG,
  423. RTL8366S_CPU_DRP_BIT, enable);
  424. }
  425. int rtl8366s_setCPUPort(uint8_t port, uint32_t noTag, uint32_t dropUnda)
  426. {
  427. uint32_t i;
  428. if(port >= 6){
  429. printf("rtl8366s_setCPUPort: invalid port number\n");
  430. return -1;
  431. }
  432. /* reset register */
  433. for(i = 0; i < 6; i++)
  434. {
  435. if(rtl8366s_setCPUPortMask(i, 0)){
  436. printf("rtl8366s_setCPUPort: rtl8366s_setCPUPortMask failed\n");
  437. return -1;
  438. }
  439. }
  440. if(rtl8366s_setCPUPortMask(port, 1)){
  441. printf("rtl8366s_setCPUPort: rtl8366s_setCPUPortMask failed\n");
  442. return -1;
  443. }
  444. if(rtl8366s_setCPUDisableInsTag(noTag)){
  445. printf("rtl8366s_setCPUPort: rtl8366s_setCPUDisableInsTag fail\n");
  446. return -1;
  447. }
  448. if(rtl8366s_setCPUDropUnda(dropUnda)){
  449. printf("rtl8366s_setCPUPort: rtl8366s_setCPUDropUnda fail\n");
  450. return -1;
  451. }
  452. return 0;
  453. }
  454. int rtl8366s_setLedConfig(uint32_t ledNum, uint8_t config)
  455. {
  456. uint16_t regData;
  457. if(ledNum >= RTL8366S_LED_GROUP_MAX) {
  458. DBG("rtl8366s_setLedConfig: invalid led group\n");
  459. return -1;
  460. }
  461. if(config > RTL8366S_LEDCONF_LEDFORCE) {
  462. DBG("rtl8366s_setLedConfig: invalid led config\n");
  463. return -1;
  464. }
  465. if (rtl8366_readRegister(RTL8366S_LED_INDICATED_CONF_REG, &regData)) {
  466. printf("rtl8366s_setLedConfig: failed to get led register!\n");
  467. return -1;
  468. }
  469. regData &= ~(0xF << (ledNum * 4));
  470. regData |= config << (ledNum * 4);
  471. if (rtl8366_writeRegister(RTL8366S_LED_INDICATED_CONF_REG, regData)) {
  472. printf("rtl8366s_setLedConfig: failed to set led register!\n");
  473. return -1;
  474. }
  475. return 0;
  476. }
  477. int rtl8366s_getLedConfig(uint32_t ledNum, uint8_t *config)
  478. {
  479. uint16_t regData;
  480. if(ledNum >= RTL8366S_LED_GROUP_MAX) {
  481. DBG("rtl8366s_getLedConfig: invalid led group\n");
  482. return -1;
  483. }
  484. if (rtl8366_readRegister(RTL8366S_LED_INDICATED_CONF_REG, &regData)) {
  485. printf("rtl8366s_getLedConfig: failed to get led register!\n");
  486. return -1;
  487. }
  488. if (config)
  489. *config = (regData >> (ledNum * 4)) & 0xF;
  490. return 0;
  491. }
  492. int rtl8366s_setLedForceValue(uint32_t group0, uint32_t group1,
  493. uint32_t group2, uint32_t group3)
  494. {
  495. uint16_t regData;
  496. regData = (group0 & 0x3F) | ((group1 & 0x3F) << 6);
  497. if (rtl8366_writeRegister(RTL8366S_LED_0_1_FORCE_REG, regData)) {
  498. printf("rtl8366s_setLedForceValue: failed to set led register!\n");
  499. return -1;
  500. }
  501. regData = (group2 & 0x3F) | ((group3 & 0x3F) << 6);
  502. if (rtl8366_writeRegister(RTL8366S_LED_2_3_FORCE_REG, regData)) {
  503. printf("rtl8366s_setLedForceValue: failed to set led register!\n");
  504. return -1;
  505. }
  506. return 0;
  507. }
  508. int rtl8366s_initChip(void)
  509. {
  510. uint32_t ledGroup, i = 0;
  511. uint16_t regData;
  512. uint8_t ledData[RTL8366S_LED_GROUP_MAX];
  513. const uint16_t (*chipData)[2];
  514. const uint16_t chipB[][2] =
  515. {
  516. {0x0000, 0x0038},{0x8100, 0x1B37},{0xBE2E, 0x7B9F},{0xBE2B, 0xA4C8},
  517. {0xBE74, 0xAD14},{0xBE2C, 0xDC00},{0xBE69, 0xD20F},{0xBE3B, 0xB414},
  518. {0xBE24, 0x0000},{0xBE23, 0x00A1},{0xBE22, 0x0008},{0xBE21, 0x0120},
  519. {0xBE20, 0x1000},{0xBE24, 0x0800},{0xBE24, 0x0000},{0xBE24, 0xF000},
  520. {0xBE23, 0xDF01},{0xBE22, 0xDF20},{0xBE21, 0x101A},{0xBE20, 0xA0FF},
  521. {0xBE24, 0xF800},{0xBE24, 0xF000},{0x0242, 0x02BF},{0x0245, 0x02BF},
  522. {0x0248, 0x02BF},{0x024B, 0x02BF},{0x024E, 0x02BF},{0x0251, 0x02BF},
  523. {0x0230, 0x0A32},{0x0233, 0x0A32},{0x0236, 0x0A32},{0x0239, 0x0A32},
  524. {0x023C, 0x0A32},{0x023F, 0x0A32},{0x0254, 0x0A3F},{0x0255, 0x0064},
  525. {0x0256, 0x0A3F},{0x0257, 0x0064},{0x0258, 0x0A3F},{0x0259, 0x0064},
  526. {0x025A, 0x0A3F},{0x025B, 0x0064},{0x025C, 0x0A3F},{0x025D, 0x0064},
  527. {0x025E, 0x0A3F},{0x025F, 0x0064},{0x0260, 0x0178},{0x0261, 0x01F4},
  528. {0x0262, 0x0320},{0x0263, 0x0014},{0x021D, 0x9249},{0x021E, 0x0000},
  529. {0x0100, 0x0004},{0xBE4A, 0xA0B4},{0xBE40, 0x9C00},{0xBE41, 0x501D},
  530. {0xBE48, 0x3602},{0xBE47, 0x8051},{0xBE4C, 0x6465},{0x8000, 0x1F00},
  531. {0x8001, 0x000C},{0x8008, 0x0000},{0x8007, 0x0000},{0x800C, 0x00A5},
  532. {0x8101, 0x02BC},{0xBE53, 0x0005},{0x8E45, 0xAFE8},{0x8013, 0x0005},
  533. {0xBE4B, 0x6700},{0x800B, 0x7000},{0xBE09, 0x0E00},
  534. {0xFFFF, 0xABCD}
  535. };
  536. const uint16_t chipDefault[][2] =
  537. {
  538. {0x0242, 0x02BF},{0x0245, 0x02BF},{0x0248, 0x02BF},{0x024B, 0x02BF},
  539. {0x024E, 0x02BF},{0x0251, 0x02BF},
  540. {0x0254, 0x0A3F},{0x0256, 0x0A3F},{0x0258, 0x0A3F},{0x025A, 0x0A3F},
  541. {0x025C, 0x0A3F},{0x025E, 0x0A3F},
  542. {0x0263, 0x007C},{0x0100, 0x0004},
  543. {0xBE5B, 0x3500},{0x800E, 0x200F},{0xBE1D, 0x0F00},{0x8001, 0x5011},
  544. {0x800A, 0xA2F4},{0x800B, 0x17A3},{0xBE4B, 0x17A3},{0xBE41, 0x5011},
  545. {0xBE17, 0x2100},{0x8000, 0x8304},{0xBE40, 0x8304},{0xBE4A, 0xA2F4},
  546. {0x800C, 0xA8D5},{0x8014, 0x5500},{0x8015, 0x0004},{0xBE4C, 0xA8D5},
  547. {0xBE59, 0x0008},{0xBE09, 0x0E00},{0xBE36, 0x1036},{0xBE37, 0x1036},
  548. {0x800D, 0x00FF},{0xBE4D, 0x00FF},
  549. {0xFFFF, 0xABCD}
  550. };
  551. DBG("rtl8366s_initChip\n");
  552. /* save current led config and set to led force */
  553. for (ledGroup = 0; ledGroup < RTL8366S_LED_GROUP_MAX; ledGroup++) {
  554. if (rtl8366s_getLedConfig(ledGroup, &ledData[ledGroup]))
  555. return -1;
  556. if (rtl8366s_setLedConfig(ledGroup, RTL8366S_LEDCONF_LEDFORCE))
  557. return -1;
  558. }
  559. if (rtl8366s_setLedForceValue(0,0,0,0))
  560. return -1;
  561. if (rtl8366_readRegister(RTL8366S_MODEL_ID_REG, &regData))
  562. return -1;
  563. switch (regData)
  564. {
  565. case 0x0000:
  566. chipData = chipB;
  567. break;
  568. case RTL8366S_MODEL_8366SR:
  569. chipData = chipDefault;
  570. break;
  571. default:
  572. printf("rtl8366s_initChip: unsupported chip found!\n");
  573. return -1;
  574. }
  575. DBG("rtl8366s_initChip: found %x chip\n", regData);
  576. while ((chipData[i][0] != 0xFFFF) && (chipData[i][1] != 0xABCD)) {
  577. /* phy settings*/
  578. if ((chipData[i][0] & 0xBE00) == 0xBE00) {
  579. if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG,
  580. RTL8366S_PHY_CTRL_WRITE))
  581. return -1;
  582. }
  583. if (rtl8366_writeRegister(chipData[i][0], chipData[i][1]))
  584. return -1;
  585. i++;
  586. }
  587. /* chip needs some time */
  588. udelay(100 * 1000);
  589. /* restore led config */
  590. for (ledGroup = 0; ledGroup < RTL8366S_LED_GROUP_MAX; ledGroup++) {
  591. if (rtl8366s_setLedConfig(ledGroup, ledData[ledGroup]))
  592. return -1;
  593. }
  594. return 0;
  595. }
  596. int rtl8366s_initialize(void)
  597. {
  598. uint16_t regData;
  599. DBG("rtl8366s_initialize: start setup\n");
  600. smi_init();
  601. rtl8366_readRegister(RTL8366S_CHIP_ID_REG, &regData);
  602. DBG("Realtek 8366SR switch ID %#04x\n", regData);
  603. if (regData != 0x8366) {
  604. printf("rtl8366s_initialize: found unsupported switch\n");
  605. return -1;
  606. }
  607. if (rtl8366s_initChip()) {
  608. printf("rtl8366s_initialize: init chip failed\n");
  609. return -1;
  610. }
  611. if (rtl8366s_setGreenEthernet(1, 1)) {
  612. printf("rtl8366s_initialize: set green ethernet failed\n");
  613. return -1;
  614. }
  615. /* Set port 5 noTag and don't dropUnda */
  616. if (rtl8366s_setCPUPort(5, 1, 0)) {
  617. printf("rtl8366s_initialize: set CPU port failed\n");
  618. return -1;
  619. }
  620. return 0;
  621. }