int qca_ar8327_sw_get_ports(struct switch_dev *dev, struct switch_val *val) { struct qca_phy_priv *priv = qca_phy_priv_get(dev); a_uint8_t ports = priv->vlan_table[val->port_vlan]; int i; val->len = 0; for (i = 0; i < dev->ports; i++) { struct switch_port *p; if (!(ports & (1 << i))) continue; p = &val->value.ports[val->len++]; p->id = i; if (priv->vlan_tagged[val->port_vlan] & (1 << i)) p->flags = (1 << SWITCH_PORT_FLAG_TAGGED); else p->flags = 0; /*Handle for VLAN 0*/ if (val->port_vlan == 0) p->flags = (1 << SWITCH_PORT_FLAG_TAGGED); } return 0; }
int qca_ar8327_sw_get_pvid(struct switch_dev *dev, int port, int *vlan) { struct qca_phy_priv *priv = qca_phy_priv_get(dev); *vlan = priv->pvid[port]; return 0; }
int qca_ar8327_sw_get_vid(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { struct qca_phy_priv *priv = qca_phy_priv_get(dev); val->value.i = priv->vlan_id[val->port_vlan]; return 0; }
int qca_ar8327_sw_set_pvid(struct switch_dev *dev, int port, int vlan) { struct qca_phy_priv *priv = qca_phy_priv_get(dev); /* make sure no invalid PVIDs get set */ if (vlan >= dev->vlans) return -1; priv->pvid[port] = vlan; return 0; }
int qca_ar8327_sw_set_ports(struct switch_dev *dev, struct switch_val *val) { struct qca_phy_priv *priv = qca_phy_priv_get(dev); a_uint8_t *vt = &priv->vlan_table[val->port_vlan]; int i, j; /*Handle for VLAN 0*/ if (val->port_vlan == 0) { priv->vlan_table[0] = 0; for (i = 0; i < val->len; i++) { struct switch_port *p = &val->value.ports[i]; priv->vlan_table[0] |= (1 << p->id); } #ifdef UCI_TAKEOVER #ifdef BOARD_AR71XX if(SSDK_CURRENT_CHIP_TYPE == CHIP_SHIVA) { ssdk_uci_vlan_table_set(priv->vlan_table[0],0); } #endif #endif return 0; } if (priv->vlan_id[val->port_vlan] == 0) priv->vlan_id[val->port_vlan] = val->port_vlan; *vt = 0; for (i = 0; i < val->len; i++) { struct switch_port *p = &val->value.ports[i]; if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) { priv->vlan_tagged[val->port_vlan] |= (1 << p->id); } else { priv->vlan_tagged[val->port_vlan] &= ~(1 << p->id); priv->pvid[p->id] = val->port_vlan; } *vt |= 1 << p->id; } #ifdef UCI_TAKEOVER #ifdef BOARD_AR71XX if(SSDK_CURRENT_CHIP_TYPE == CHIP_SHIVA) { a_uint8_t tag = priv->vlan_tagged[1] | priv->vlan_tagged[2]; ssdk_uci_vlan_ports_set(priv->vlan_id, tag, priv->pvid, priv->vlan_table); } #endif #endif return 0; }
int qca_ar8327_sw_set_vid(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { struct qca_phy_priv *priv = qca_phy_priv_get(dev); priv->vlan_id[val->port_vlan] = val->value.i; #ifdef BOARD_AR71XX if(SSDK_CURRENT_CHIP_TYPE == CHIP_SHIVA) { ssdk_uci_sw_set_vid(attr, val); } #endif return 0; }
int qca_ar8327_sw_set_pvid(struct switch_dev *dev, int port, int vlan) { struct qca_phy_priv *priv = qca_phy_priv_get(dev); /* make sure no invalid PVIDs get set */ if (vlan >= dev->vlans) return -1; priv->pvid[port] = vlan; #ifdef BOARD_AR71XX if(SSDK_CURRENT_CHIP_TYPE == CHIP_SHIVA) { ssdk_uci_sw_set_pvid(port, vlan); } #endif return 0; }
int qca_ar8327_sw_set_vlan(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { struct qca_phy_priv *priv = qca_phy_priv_get(dev); priv->vlan = !!val->value.i; #ifdef UCI_TAKEOVER #ifdef BOARD_AR71XX if(SSDK_CURRENT_CHIP_TYPE == CHIP_SHIVA) { ssdk_uci_vlan_enable_set(priv->vlan); } #endif #endif return 0; }
int qca_ar8327_sw_hw_apply(struct switch_dev *dev) { struct qca_phy_priv *priv = qca_phy_priv_get(dev); fal_pbmp_t portmask[AR8327_NUM_PORTS]; int i, j; mutex_lock(&priv->reg_mutex); memset(portmask, 0, sizeof(portmask)); if (!priv->init) { /*Handle VLAN 0 entry*/ if (priv->vlan_id[0] == 0 && priv->vlan_table[0] == 0) { qca_ar8327_sw_enable_vlan0(A_FALSE, 0); } /* calculate the port destination masks and load vlans * into the vlan translation unit */ for (j = 0; j < AR8327_MAX_VLANS; j++) { u8 vp = priv->vlan_table[j]; if (!vp) { fal_vlan_delete(0, priv->vlan_id[j]); continue; } fal_vlan_delete(0, priv->vlan_id[j]); fal_vlan_create(0, priv->vlan_id[j]); for (i = 0; i < dev->ports; i++) { u8 mask = (1 << i); if (vp & mask) { fal_vlan_member_add(0, priv->vlan_id[j], i, (mask & priv->vlan_tagged[j])? FAL_EG_TAGGED : FAL_EG_UNTAGGED); portmask[i] |= vp & ~mask; } } if (SSDK_CURRENT_CHIP_TYPE == CHIP_SHIVA) fal_vlan_member_update(0,priv->vlan_id[j],vp,0); } /*Hanlde VLAN 0 entry*/ if (priv->vlan_id[0] == 0 && priv->vlan_table[0]) { qca_ar8327_sw_enable_vlan0(A_TRUE, priv->vlan_table[0]); } } else { /* vlan disabled: * isolate all ports, but connect them to the cpu port */ for (i = 0; i < dev->ports; i++) { if (i == AR8327_PORT_CPU) continue; portmask[i] = 1 << AR8327_PORT_CPU; portmask[AR8327_PORT_CPU] |= (1 << i); } } /* update the port destination mask registers and tag settings */ for (i = 0; i < dev->ports; i++) { int pvid; fal_pt_1qmode_t ingressMode; fal_pt_1q_egmode_t egressMode; if (priv->vlan) { pvid = priv->vlan_id[priv->pvid[i]]; if (priv->vlan_tagged[priv->pvid[i]] & (1 << i)) { egressMode = FAL_EG_TAGGED; } else { egressMode = FAL_EG_UNTAGGED; } ingressMode = FAL_1Q_SECURE; } else { pvid = i; egressMode = FAL_EG_UNTOUCHED; ingressMode = FAL_1Q_DISABLE; } /*If VLAN 0 existes, change member port *egress mode as UNTOUCHED*/ if (priv->vlan_id[0] == 0 && priv->vlan_table[0] && ((0x1 << i) & priv->vlan_table[0]) && priv->vlan) { egressMode = FAL_EG_UNTOUCHED; } fal_port_1qmode_set(0, i, ingressMode); fal_port_egvlanmode_set(0, i, egressMode); fal_port_default_cvid_set(0, i, pvid); fal_portvlan_member_update(0, i, portmask[i]); } mutex_unlock(&priv->reg_mutex); return 0; }