| .. | .. |
|---|
| 30 | 30 | * Helper functions for common, but complicated tasks. |
|---|
| 31 | 31 | * |
|---|
| 32 | 32 | */ |
|---|
| 33 | +#include <linux/bug.h> |
|---|
| 33 | 34 | #include <asm/octeon/octeon.h> |
|---|
| 34 | 35 | |
|---|
| 35 | 36 | #include <asm/octeon/cvmx-config.h> |
|---|
| .. | .. |
|---|
| 43 | 44 | #include <asm/octeon/cvmx-helper-board.h> |
|---|
| 44 | 45 | |
|---|
| 45 | 46 | #include <asm/octeon/cvmx-pip-defs.h> |
|---|
| 46 | | -#include <asm/octeon/cvmx-smix-defs.h> |
|---|
| 47 | 47 | #include <asm/octeon/cvmx-asxx-defs.h> |
|---|
| 48 | | - |
|---|
| 49 | | -/** |
|---|
| 50 | | - * cvmx_override_pko_queue_priority(int ipd_port, uint64_t |
|---|
| 51 | | - * priorities[16]) is a function pointer. It is meant to allow |
|---|
| 52 | | - * customization of the PKO queue priorities based on the port |
|---|
| 53 | | - * number. Users should set this pointer to a function before |
|---|
| 54 | | - * calling any cvmx-helper operations. |
|---|
| 55 | | - */ |
|---|
| 56 | | -void (*cvmx_override_pko_queue_priority) (int pko_port, |
|---|
| 57 | | - uint64_t priorities[16]); |
|---|
| 58 | | - |
|---|
| 59 | | -/** |
|---|
| 60 | | - * cvmx_override_ipd_port_setup(int ipd_port) is a function |
|---|
| 61 | | - * pointer. It is meant to allow customization of the IPD port |
|---|
| 62 | | - * setup before packet input/output comes online. It is called |
|---|
| 63 | | - * after cvmx-helper does the default IPD configuration, but |
|---|
| 64 | | - * before IPD is enabled. Users should set this pointer to a |
|---|
| 65 | | - * function before calling any cvmx-helper operations. |
|---|
| 66 | | - */ |
|---|
| 67 | | -void (*cvmx_override_ipd_port_setup) (int ipd_port); |
|---|
| 68 | 48 | |
|---|
| 69 | 49 | /* Port count per interface */ |
|---|
| 70 | 50 | static int interface_port_count[9]; |
|---|
| .. | .. |
|---|
| 238 | 218 | mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface)); |
|---|
| 239 | 219 | |
|---|
| 240 | 220 | if (OCTEON_IS_MODEL(OCTEON_CN63XX)) { |
|---|
| 241 | | - switch (mode.cn63xx.mode) { |
|---|
| 221 | + switch (mode.cn61xx.mode) { |
|---|
| 242 | 222 | case 0: |
|---|
| 243 | 223 | return CVMX_HELPER_INTERFACE_MODE_SGMII; |
|---|
| 244 | 224 | case 1: |
|---|
| .. | .. |
|---|
| 337 | 317 | return CVMX_HELPER_INTERFACE_MODE_DISABLED; |
|---|
| 338 | 318 | } |
|---|
| 339 | 319 | |
|---|
| 340 | | - if (interface == 0 |
|---|
| 341 | | - && cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5 |
|---|
| 342 | | - && cvmx_sysinfo_get()->board_rev_major == 1) { |
|---|
| 343 | | - /* |
|---|
| 344 | | - * Lie about interface type of CN3005 board. This |
|---|
| 345 | | - * board has a switch on port 1 like the other |
|---|
| 346 | | - * evaluation boards, but it is connected over RGMII |
|---|
| 347 | | - * instead of GMII. Report GMII mode so that the |
|---|
| 348 | | - * speed is forced to 1 Gbit full duplex. Other than |
|---|
| 349 | | - * some initial configuration (which does not use the |
|---|
| 350 | | - * output of this function) there is no difference in |
|---|
| 351 | | - * setup between GMII and RGMII modes. |
|---|
| 352 | | - */ |
|---|
| 353 | | - return CVMX_HELPER_INTERFACE_MODE_GMII; |
|---|
| 354 | | - } |
|---|
| 355 | | - |
|---|
| 356 | 320 | /* Interface 1 is always disabled on CN31XX and CN30XX */ |
|---|
| 357 | 321 | if ((interface == 1) |
|---|
| 358 | 322 | && (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX) |
|---|
| .. | .. |
|---|
| 363 | 327 | mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface)); |
|---|
| 364 | 328 | |
|---|
| 365 | 329 | if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) { |
|---|
| 366 | | - switch (mode.cn56xx.mode) { |
|---|
| 330 | + switch (mode.cn52xx.mode) { |
|---|
| 367 | 331 | case 0: |
|---|
| 368 | 332 | return CVMX_HELPER_INTERFACE_MODE_DISABLED; |
|---|
| 369 | 333 | case 1: |
|---|
| .. | .. |
|---|
| 436 | 400 | tag_config.s.grp = 0; |
|---|
| 437 | 401 | |
|---|
| 438 | 402 | cvmx_pip_config_port(ipd_port, port_config, tag_config); |
|---|
| 439 | | - |
|---|
| 440 | | - /* Give the user a chance to override our setting for each port */ |
|---|
| 441 | | - if (cvmx_override_ipd_port_setup) |
|---|
| 442 | | - cvmx_override_ipd_port_setup(ipd_port); |
|---|
| 443 | 403 | |
|---|
| 444 | 404 | return 0; |
|---|
| 445 | 405 | } |
|---|
| .. | .. |
|---|
| 664 | 624 | int ipd_port = cvmx_helper_get_ipd_port(interface, 0); |
|---|
| 665 | 625 | int num_ports = interface_port_count[interface]; |
|---|
| 666 | 626 | while (num_ports--) { |
|---|
| 667 | | - /* |
|---|
| 668 | | - * Give the user a chance to override the per queue |
|---|
| 669 | | - * priorities. |
|---|
| 670 | | - */ |
|---|
| 671 | | - if (cvmx_override_pko_queue_priority) |
|---|
| 672 | | - cvmx_override_pko_queue_priority(ipd_port, priorities); |
|---|
| 673 | | - |
|---|
| 674 | 627 | cvmx_pko_config_port(ipd_port, |
|---|
| 675 | 628 | cvmx_pko_get_base_queue_per_core(ipd_port, |
|---|
| 676 | 629 | 0), |
|---|
| .. | .. |
|---|
| 809 | 762 | result = __cvmx_helper_loop_enable(interface); |
|---|
| 810 | 763 | break; |
|---|
| 811 | 764 | } |
|---|
| 812 | | - result |= __cvmx_helper_board_hardware_enable(interface); |
|---|
| 813 | 765 | return result; |
|---|
| 814 | 766 | } |
|---|
| 815 | 767 | |
|---|
| .. | .. |
|---|
| 819 | 771 | * Returns 0 on success |
|---|
| 820 | 772 | * !0 on failure |
|---|
| 821 | 773 | */ |
|---|
| 822 | | -int __cvmx_helper_errata_fix_ipd_ptr_alignment(void) |
|---|
| 774 | +static int __cvmx_helper_errata_fix_ipd_ptr_alignment(void) |
|---|
| 823 | 775 | { |
|---|
| 824 | 776 | #define FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES \ |
|---|
| 825 | 777 | (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_FIRST_MBUFF_SKIP) |
|---|
| .. | .. |
|---|
| 830 | 782 | #define INTERFACE(port) (port >> 4) |
|---|
| 831 | 783 | #define INDEX(port) (port & 0xf) |
|---|
| 832 | 784 | uint64_t *p64; |
|---|
| 833 | | - cvmx_pko_command_word0_t pko_command; |
|---|
| 785 | + union cvmx_pko_command_word0 pko_command; |
|---|
| 834 | 786 | union cvmx_buf_ptr g_buffer, pkt_buffer; |
|---|
| 835 | | - cvmx_wqe_t *work; |
|---|
| 787 | + struct cvmx_wqe *work; |
|---|
| 836 | 788 | int size, num_segs = 0, wqe_pcnt, pkt_pcnt; |
|---|
| 837 | 789 | union cvmx_gmxx_prtx_cfg gmx_cfg; |
|---|
| 838 | 790 | int retry_cnt; |
|---|
| .. | .. |
|---|
| 1057 | 1009 | int result = 0; |
|---|
| 1058 | 1010 | int interface; |
|---|
| 1059 | 1011 | union cvmx_l2c_cfg l2c_cfg; |
|---|
| 1060 | | - union cvmx_smix_en smix_en; |
|---|
| 1061 | 1012 | const int num_interfaces = cvmx_helper_get_number_of_interfaces(); |
|---|
| 1062 | 1013 | |
|---|
| 1063 | 1014 | /* |
|---|
| .. | .. |
|---|
| 1076 | 1027 | l2c_cfg.s.lrf_arb_mode = 0; |
|---|
| 1077 | 1028 | l2c_cfg.s.rfb_arb_mode = 0; |
|---|
| 1078 | 1029 | cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64); |
|---|
| 1079 | | - |
|---|
| 1080 | | - /* Make sure SMI/MDIO is enabled so we can query PHYs */ |
|---|
| 1081 | | - smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(0)); |
|---|
| 1082 | | - if (!smix_en.s.en) { |
|---|
| 1083 | | - smix_en.s.en = 1; |
|---|
| 1084 | | - cvmx_write_csr(CVMX_SMIX_EN(0), smix_en.u64); |
|---|
| 1085 | | - } |
|---|
| 1086 | | - |
|---|
| 1087 | | - /* Newer chips actually have two SMI/MDIO interfaces */ |
|---|
| 1088 | | - if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) && |
|---|
| 1089 | | - !OCTEON_IS_MODEL(OCTEON_CN58XX) && |
|---|
| 1090 | | - !OCTEON_IS_MODEL(OCTEON_CN50XX)) { |
|---|
| 1091 | | - smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(1)); |
|---|
| 1092 | | - if (!smix_en.s.en) { |
|---|
| 1093 | | - smix_en.s.en = 1; |
|---|
| 1094 | | - cvmx_write_csr(CVMX_SMIX_EN(1), smix_en.u64); |
|---|
| 1095 | | - } |
|---|
| 1096 | | - } |
|---|
| 1097 | 1030 | |
|---|
| 1098 | 1031 | cvmx_pko_initialize_global(); |
|---|
| 1099 | 1032 | for (interface = 0; interface < num_interfaces; interface++) { |
|---|
| .. | .. |
|---|
| 1142 | 1075 | * |
|---|
| 1143 | 1076 | * Returns Link state |
|---|
| 1144 | 1077 | */ |
|---|
| 1145 | | -cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port) |
|---|
| 1078 | +union cvmx_helper_link_info cvmx_helper_link_get(int ipd_port) |
|---|
| 1146 | 1079 | { |
|---|
| 1147 | | - cvmx_helper_link_info_t result; |
|---|
| 1080 | + union cvmx_helper_link_info result; |
|---|
| 1148 | 1081 | int interface = cvmx_helper_get_interface_num(ipd_port); |
|---|
| 1149 | 1082 | int index = cvmx_helper_get_interface_index_num(ipd_port); |
|---|
| 1150 | 1083 | |
|---|
| .. | .. |
|---|
| 1167 | 1100 | if (index == 0) |
|---|
| 1168 | 1101 | result = __cvmx_helper_rgmii_link_get(ipd_port); |
|---|
| 1169 | 1102 | else { |
|---|
| 1103 | + WARN(1, "Using deprecated link status - please update your DT"); |
|---|
| 1170 | 1104 | result.s.full_duplex = 1; |
|---|
| 1171 | 1105 | result.s.link_up = 1; |
|---|
| 1172 | 1106 | result.s.speed = 1000; |
|---|
| .. | .. |
|---|
| 1202 | 1136 | * |
|---|
| 1203 | 1137 | * Returns Zero on success, negative on failure |
|---|
| 1204 | 1138 | */ |
|---|
| 1205 | | -int cvmx_helper_link_set(int ipd_port, cvmx_helper_link_info_t link_info) |
|---|
| 1139 | +int cvmx_helper_link_set(int ipd_port, union cvmx_helper_link_info link_info) |
|---|
| 1206 | 1140 | { |
|---|
| 1207 | 1141 | int result = -1; |
|---|
| 1208 | 1142 | int interface = cvmx_helper_get_interface_num(ipd_port); |
|---|
| .. | .. |
|---|
| 1240 | 1174 | return result; |
|---|
| 1241 | 1175 | } |
|---|
| 1242 | 1176 | EXPORT_SYMBOL_GPL(cvmx_helper_link_set); |
|---|
| 1243 | | - |
|---|
| 1244 | | -/** |
|---|
| 1245 | | - * Configure a port for internal and/or external loopback. Internal loopback |
|---|
| 1246 | | - * causes packets sent by the port to be received by Octeon. External loopback |
|---|
| 1247 | | - * causes packets received from the wire to sent out again. |
|---|
| 1248 | | - * |
|---|
| 1249 | | - * @ipd_port: IPD/PKO port to loopback. |
|---|
| 1250 | | - * @enable_internal: |
|---|
| 1251 | | - * Non zero if you want internal loopback |
|---|
| 1252 | | - * @enable_external: |
|---|
| 1253 | | - * Non zero if you want external loopback |
|---|
| 1254 | | - * |
|---|
| 1255 | | - * Returns Zero on success, negative on failure. |
|---|
| 1256 | | - */ |
|---|
| 1257 | | -int cvmx_helper_configure_loopback(int ipd_port, int enable_internal, |
|---|
| 1258 | | - int enable_external) |
|---|
| 1259 | | -{ |
|---|
| 1260 | | - int result = -1; |
|---|
| 1261 | | - int interface = cvmx_helper_get_interface_num(ipd_port); |
|---|
| 1262 | | - int index = cvmx_helper_get_interface_index_num(ipd_port); |
|---|
| 1263 | | - |
|---|
| 1264 | | - if (index >= cvmx_helper_ports_on_interface(interface)) |
|---|
| 1265 | | - return -1; |
|---|
| 1266 | | - |
|---|
| 1267 | | - switch (cvmx_helper_interface_get_mode(interface)) { |
|---|
| 1268 | | - case CVMX_HELPER_INTERFACE_MODE_DISABLED: |
|---|
| 1269 | | - case CVMX_HELPER_INTERFACE_MODE_PCIE: |
|---|
| 1270 | | - case CVMX_HELPER_INTERFACE_MODE_SPI: |
|---|
| 1271 | | - case CVMX_HELPER_INTERFACE_MODE_NPI: |
|---|
| 1272 | | - case CVMX_HELPER_INTERFACE_MODE_LOOP: |
|---|
| 1273 | | - break; |
|---|
| 1274 | | - case CVMX_HELPER_INTERFACE_MODE_XAUI: |
|---|
| 1275 | | - result = |
|---|
| 1276 | | - __cvmx_helper_xaui_configure_loopback(ipd_port, |
|---|
| 1277 | | - enable_internal, |
|---|
| 1278 | | - enable_external); |
|---|
| 1279 | | - break; |
|---|
| 1280 | | - case CVMX_HELPER_INTERFACE_MODE_RGMII: |
|---|
| 1281 | | - case CVMX_HELPER_INTERFACE_MODE_GMII: |
|---|
| 1282 | | - result = |
|---|
| 1283 | | - __cvmx_helper_rgmii_configure_loopback(ipd_port, |
|---|
| 1284 | | - enable_internal, |
|---|
| 1285 | | - enable_external); |
|---|
| 1286 | | - break; |
|---|
| 1287 | | - case CVMX_HELPER_INTERFACE_MODE_SGMII: |
|---|
| 1288 | | - case CVMX_HELPER_INTERFACE_MODE_PICMG: |
|---|
| 1289 | | - result = |
|---|
| 1290 | | - __cvmx_helper_sgmii_configure_loopback(ipd_port, |
|---|
| 1291 | | - enable_internal, |
|---|
| 1292 | | - enable_external); |
|---|
| 1293 | | - break; |
|---|
| 1294 | | - } |
|---|
| 1295 | | - return result; |
|---|
| 1296 | | -} |
|---|