[rdkb][common][app][Refactor switch tool]
[Description]
Refactor switch tool
1. align to newest openwrt version
2. add a patch to change the differences between openwrt and RDKB such as bridge name ...
[Release-log]
Change-Id: Iaba64709f3be51a2764b5374c043aa793596721d
diff --git a/recipes-devtools/switch/files/src/switch_ioctl.c b/recipes-devtools/switch/files/src/switch_ioctl.c
new file mode 100644
index 0000000..f6b97d4
--- /dev/null
+++ b/recipes-devtools/switch/files/src/switch_ioctl.c
@@ -0,0 +1,478 @@
+/*
+ * switch_ioctl.c: switch(ioctl) set API
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <linux/if.h>
+
+#include "switch_fun.h"
+#include "switch_ioctl.h"
+
+static int esw_fd;
+
+int switch_ioctl_init(void)
+{
+ esw_fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (esw_fd < 0) {
+ perror("socket");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void switch_ioctl_fini(void)
+{
+ close(esw_fd);
+}
+
+int reg_read_ioctl(unsigned int offset, unsigned int *value)
+{
+ struct ifreq ifr;
+ struct ra_mii_ioctl_data mii;
+
+ strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
+ ifr.ifr_data = &mii;
+
+ mii.phy_id = 0x1f;
+ mii.reg_num = offset;
+
+ if (-1 == ioctl(esw_fd, RAETH_MII_READ, &ifr)) {
+ perror("ioctl");
+ close(esw_fd);
+ exit(0);
+ }
+ *value = mii.val_out;
+ return 0;
+}
+
+int reg_read_tr(int offset, int *value)
+{
+ struct ifreq ifr;
+ struct ra_mii_ioctl_data mii;
+
+ strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
+ ifr.ifr_data = &mii;
+
+ mii.phy_id = 0;
+ mii.reg_num = offset;
+
+ if (-1 == ioctl(esw_fd, RAETH_MII_READ, &ifr)) {
+ perror("ioctl");
+ close(esw_fd);
+ exit(0);
+ }
+ *value = mii.val_out;
+ return 0;
+}
+
+int reg_write_ioctl(unsigned int offset, unsigned int value)
+{
+ struct ifreq ifr;
+ struct ra_mii_ioctl_data mii;
+
+ strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
+ ifr.ifr_data = &mii;
+
+ mii.phy_id = 0x1f;
+ mii.reg_num = offset;
+ mii.val_in = value;
+
+ if (-1 == ioctl(esw_fd, RAETH_MII_WRITE, &ifr)) {
+ perror("ioctl");
+ close(esw_fd);
+ exit(0);
+ }
+ return 0;
+}
+
+int reg_write_tr(int offset, int value)
+{
+ struct ifreq ifr;
+ struct ra_mii_ioctl_data mii;
+
+ strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
+ ifr.ifr_data = &mii;
+
+ mii.phy_id = 0;
+ mii.reg_num = offset;
+ mii.val_in = value;
+
+ if (-1 == ioctl(esw_fd, RAETH_MII_WRITE, &ifr)) {
+ perror("ioctl");
+ close(esw_fd);
+ exit(0);
+ }
+ return 0;
+}
+
+int phy_dump_ioctl(unsigned int phy_addr)
+{
+ struct ifreq ifr;
+ struct esw_reg reg;
+
+ reg.val = phy_addr;
+ strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
+ ifr.ifr_data = ®
+ if (-1 == ioctl(esw_fd, RAETH_ESW_PHY_DUMP, &ifr)) {
+ perror("ioctl");
+ close(esw_fd);
+ exit(0);
+ }
+ return 0;
+}
+
+int mii_mgr_cl22_read_ioctl(unsigned int port_num, unsigned int reg, unsigned int *value)
+{
+ unsigned int reg_value;
+ int loop_cnt;
+ int op_busy;
+
+ loop_cnt = 0;
+
+ /*Change to indirect access mode*/
+ /*if you need to use direct access mode, please change back manually by reset bit5*/
+ if (chip_name == 0x7530) {
+ reg_read(0x7804, ®_value);
+ if (((reg_value >> 5) & 0x1) == 0) {
+ reg_value |= 1 << 5;
+ reg_write(0x7804, reg_value);
+ printf("Change to indirect access mode:0x%x\n",
+ reg_value);
+ }
+ }
+ reg_value = 0x80090000 | (port_num << 20) | (reg << 25);
+ reg_write(0x701c, reg_value);
+ while (1)
+ {
+ reg_read(0x701c, ®_value);
+ op_busy = reg_value & (1 << 31);
+ if (!op_busy) {
+ reg_value = reg_value & 0xFFFF;
+ break;
+ } else if (loop_cnt < 10)
+ loop_cnt++;
+ else {
+ printf("MDIO read opeartion timeout\n");
+ reg_value = 0;
+ break;
+ }
+ }
+ //printf(" PHY Indirect Access Control(0x701c) register read value =0x%x \n", reg_value);
+ *value = reg_value;
+
+ return 0;
+}
+
+int mii_mgr_cl22_write_ioctl(unsigned int port_num, unsigned int reg, unsigned int value)
+{
+ unsigned int reg_value;
+ int loop_cnt;
+ int op_busy;
+
+ loop_cnt = 0;
+ /*Change to indirect access mode*/
+ /*if you need to use direct access mode, please change back manually by reset bit5*/
+ if (chip_name == 0x7530) {
+ reg_read(0x7804, ®_value);
+ if (((reg_value >> 5) & 0x1) == 0) {
+ reg_value |= 1 << 5;
+ reg_write(0x7804, reg_value);
+ printf("Change to indirect access mode:0x%x\n",
+ reg_value);
+ }
+ }
+
+ reg_value = 0x80050000 | (port_num << 20) | (reg << 25) | value;
+ reg_write(0x701c, reg_value);
+ while (1)
+ {
+ reg_read(0x701c, ®_value);
+ op_busy = reg_value & (1 << 31);
+ if (!op_busy)
+ break;
+ else if (loop_cnt < 10)
+ loop_cnt++;
+ else {
+ printf("MDIO write opeartion timeout\n");
+ break;
+ }
+ }
+
+ //printf(" PHY Indirect Access Control(0x701c) register write value =0x%x \n", reg_value);
+
+ return 0;
+}
+
+int mii_mgr_cl45_read_indirect(unsigned int port_num, unsigned int dev,
+ unsigned int reg, unsigned int *value)
+{
+ int sk, method, ret;
+ struct ifreq ifr;
+ struct ra_mii_ioctl_data mii;
+
+ if (!value)
+ return -1;
+
+ sk = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sk < 0) {
+ printf("Open socket failed\n");
+
+ return -1;
+ }
+
+ strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
+ ifr.ifr_data = &mii;
+
+ method = RAETH_MII_WRITE;
+ mii.phy_id = port_num;
+ mii.reg_num = 13;
+ mii.val_in = dev;
+ ret = ioctl(sk, method, &ifr);
+
+ method = RAETH_MII_WRITE;
+ mii.phy_id = port_num;
+ mii.reg_num = 14;
+ mii.val_in = reg;
+ ret = ioctl(sk, method, &ifr);
+
+ method = RAETH_MII_WRITE;
+ mii.phy_id = port_num;
+ mii.reg_num = 13;
+ mii.val_in = (0x6000 | dev);
+ ret = ioctl(sk, method, &ifr);
+
+ usleep(1000);
+
+ method = RAETH_MII_READ;
+ mii.phy_id = port_num;
+ mii.reg_num = 14;
+ ret = ioctl(sk, method, &ifr);
+
+ close(sk);
+ *value = mii.val_out;
+
+ return ret;
+}
+
+int mii_mgr_cl45_write_indirect(unsigned int port_num, unsigned int dev,
+ unsigned int reg, unsigned int value)
+{
+ int sk, method, ret;
+ struct ifreq ifr;
+ struct ra_mii_ioctl_data mii;
+
+ sk = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sk < 0) {
+ printf("Open socket failed\n");
+
+ return -1;
+ }
+
+ strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
+ ifr.ifr_data = &mii;
+
+ method = RAETH_MII_WRITE;
+ mii.phy_id = port_num;
+ mii.reg_num = 13;
+ mii.val_in = dev;
+ ret = ioctl(sk, method, &ifr);
+
+ method = RAETH_MII_WRITE;
+ mii.phy_id = port_num;
+ mii.reg_num = 14;
+ mii.val_in = reg;
+ ret = ioctl(sk, method, &ifr);
+
+ method = RAETH_MII_WRITE;
+ mii.phy_id = port_num;
+ mii.reg_num = 13;
+ mii.val_in = (0x6000 | dev);
+ ret = ioctl(sk, method, &ifr);
+
+ usleep(1000);
+
+ method = RAETH_MII_WRITE;
+ mii.phy_id = port_num;
+ mii.reg_num = 14;
+ mii.val_in = value;
+ ret = ioctl(sk, method, &ifr);
+
+ close(sk);
+
+ return ret;
+}
+
+int mii_mgr_cl45_read(unsigned int port_num, unsigned int dev,
+ unsigned int reg, unsigned int *value)
+{
+ unsigned int reg_value;
+ int loop_cnt;
+ int op_busy;
+ int ret = 0;
+
+ loop_cnt = 0;
+
+ reg_value = 0x80000000 | (port_num << 20) | (dev << 25) | reg;
+ reg_write(0x701c, reg_value);
+ while (1)
+ {
+ reg_read(0x701c, ®_value);
+ op_busy = reg_value & (1 << 31);
+ if (!op_busy) {
+ break;
+ } else if (loop_cnt < 10) {
+ loop_cnt++;
+ } else {
+ printf("MDIO cl45 set dev opeartion timeout\n");
+ reg_value = 0;
+ ret = -1;
+ goto out;
+ }
+ }
+
+ reg_value = 0x800c0000 | (port_num << 20) | (dev << 25);
+ reg_write(0x701c, reg_value);
+ while (1)
+ {
+ reg_read(0x701c, ®_value);
+ op_busy = reg_value & (1 << 31);
+ if (!op_busy) {
+ reg_value = reg_value & 0xFFFF;
+ break;
+ } else if (loop_cnt < 10) {
+ loop_cnt++;
+ } else {
+ printf("MDIO cl45 read reg opeartion timeout\n");
+ reg_value = 0;
+ ret = -1;
+ break;
+ }
+ }
+out:
+ //printf(" PHY Indirect Access Control(0x701c) register read value =0x%x \n", reg_value);
+ *value = reg_value;
+
+ return ret;
+}
+
+int mii_mgr_cl45_write(unsigned int port_num, unsigned int dev,
+ unsigned int reg, unsigned int value)
+{
+ unsigned int reg_value;
+ int loop_cnt;
+ int op_busy;
+ int ret = 0;
+
+ loop_cnt = 0;
+
+ reg_value = 0x80000000 | (port_num << 20) | (dev << 25) | reg;
+ reg_write(0x701c, reg_value);
+ while (1)
+ {
+ reg_read(0x701c, ®_value);
+ op_busy = reg_value & (1 << 31);
+ if (!op_busy)
+ break;
+ else if (loop_cnt < 10)
+ loop_cnt++;
+ else {
+ printf("MDIO cl45 set dev opeartion timeout\n");
+ ret = -1;
+ goto out;
+ }
+ }
+
+ reg_value = 0x80040000 | (port_num << 20) | (dev << 25) | value;
+ reg_write(0x701c, reg_value);
+ while (1)
+ {
+ reg_read(0x701c, ®_value);
+ op_busy = reg_value & (1 << 31);
+ if (!op_busy)
+ break;
+ else if (loop_cnt < 10)
+ loop_cnt++;
+ else {
+ printf("MDIO cl45 write reg opeartion timeout\n");
+ ret = -1;
+ break;
+ }
+ }
+out:
+ //printf(" PHY Indirect Access Control(0x701c) register write value =0x%x \n", reg_value);
+ return ret;
+}
+
+int mii_mgr_cl45_read_ioctl(unsigned int port_num, unsigned int dev,
+ unsigned int reg, unsigned int *value)
+{
+ if (chip_name == 0x7531 || chip_name == 0x7988)
+ return mii_mgr_cl45_read(port_num, dev, reg, value);
+ else if (chip_name == 0x7530)
+ return mii_mgr_cl45_read_indirect(port_num, dev, reg, value);
+ else
+ return -1;
+}
+
+int mii_mgr_cl45_write_ioctl(unsigned int port_num, unsigned int dev,
+ unsigned int reg, unsigned int value)
+{
+ if (chip_name == 0x7531 || chip_name == 0x7988)
+ return mii_mgr_cl45_write(port_num, dev, reg, value);
+ else if (chip_name == 0x7530)
+ return mii_mgr_cl45_write_indirect(port_num, dev, reg, value);
+ else
+ return -1;
+}
+
+int dump_gphy(void)
+{
+ int cl22_reg[6] = {0x00, 0x01, 0x04, 0x05, 0x09, 0x0A};
+ int cl45_start_reg = 0x9B;
+ int cl45_end_reg = 0xA2;
+ unsigned int value;
+ int port_num = 5;
+ int i, j, ret;
+
+ int sk, method;
+ struct ifreq ifr;
+ struct ra_mii_ioctl_data mii;
+
+ sk = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sk < 0) {
+ printf("Open socket failed\n");
+ return -1;
+ }
+
+ strncpy(ifr.ifr_name, ETH_DEVNAME, 5);
+ ifr.ifr_data = &mii;
+ /* dump CL45 reg first*/
+ for (i = 0; i < port_num; i++) {
+ printf("== Port %d ==\n", i);
+ for (j = cl45_start_reg; j < (cl45_end_reg + 1); j++) {
+ ret = mii_mgr_cl45_read_ioctl(i, 0x1E, j, &value);
+ if (ret)
+ continue;
+ printf("dev1Eh_reg%xh = 0x%x\n", j, value);
+ }
+ }
+ printf("== Global ==\n");
+ for (i = 0; i < sizeof(cl22_reg) / sizeof(cl22_reg[0]); i++) {
+ method = RAETH_MII_READ;
+ mii.phy_id = 0;
+ mii.reg_num = cl22_reg[i];
+ ret = ioctl(sk, method, &ifr);
+ printf("Reg%xh = 0x%x\n", cl22_reg[i], mii.val_out);
+ }
+
+ close(sk);
+
+ return ret;
+}