Changeset 15308


Ignore:
Timestamp:
2009-04-20T23:26:44+02:00 (7 years ago)
Author:
nbd
Message:

clean up the ip175c driver some more, add support for setting the pvid and fix querying the phy status

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/generic-2.6/files/drivers/net/phy/ip175c.c

    r15305 r15308  
    238238        int vlan_enabled;               // TAG_VLAN_EN 
    239239        struct port_state { 
    240                 struct phy_device *phy; 
     240                u16 pvid; 
    241241                unsigned int shareports; 
    242                 u16 vlan_tag; 
    243242        } ports[MAX_PORTS]; 
    244243        unsigned int add_tag; 
     
    248247        const struct register_mappings *regs; 
    249248        reg proc_mii; /*!< phy/reg for the low level register access via /proc */ 
    250         int proc_errno; /*!< error code of the last read/write to "val" */ 
    251249 
    252250        char buf[80]; 
    253251}; 
    254252 
     253static int ip_phy_read(struct mii_bus *bus, int port, int reg) 
     254{ 
     255        int val; 
     256 
     257        mutex_lock(&bus->mdio_lock); 
     258        val = bus->read(bus, port, reg); 
     259        mutex_unlock(&bus->mdio_lock); 
     260 
     261        return val; 
     262} 
     263 
     264 
     265static int ip_phy_write(struct mii_bus *bus, int port, int reg, u16 val) 
     266{ 
     267        int err; 
     268 
     269        mutex_lock(&bus->mdio_lock); 
     270        err = bus->write(bus, port, reg, val); 
     271        mutex_unlock(&bus->mdio_lock); 
     272 
     273        return err; 
     274} 
     275 
     276 
    255277static int getPhy (struct ip175c_state *state, reg mii) 
     278{ 
     279        struct mii_bus *bus = state->mii_bus; 
     280        int val; 
     281 
     282        if (!REG_SUPP(mii)) 
     283                return -EFAULT; 
     284 
     285        val = ip_phy_read(bus, mii.p, mii.m); 
     286        if (val < 0) 
     287                pr_warning("IP175C: Unable to get MII register %d,%d: error %d\n", mii.p,mii.m,-val); 
     288 
     289        return val; 
     290} 
     291 
     292static int setPhy (struct ip175c_state *state, reg mii, u16 value) 
    256293{ 
    257294        struct mii_bus *bus = state->mii_bus; 
     
    260297        if (!REG_SUPP(mii)) 
    261298                return -EFAULT; 
    262         mutex_lock(&bus->mdio_lock); 
    263         err = bus->read(bus, mii.p, mii.m); 
    264         mutex_unlock(&bus->mdio_lock); 
     299 
     300        err = ip_phy_write(bus, mii.p, mii.m, value); 
    265301        if (err < 0) { 
    266                 state->proc_errno = err; 
    267                 pr_warning("IP175C: Unable to get MII register %d,%d: error %d\n", mii.p,mii.m,-err); 
    268                 return err; 
    269         } 
    270  
    271         pr_debug("IP175C: Read MII register %d,%d -> %04x\n", mii.p, mii.m, err); 
    272         return err; 
    273 } 
    274  
    275 static int setPhy (struct ip175c_state *state, reg mii, u16 value) 
    276 { 
    277         struct mii_bus *bus = state->mii_bus; 
    278         int err; 
    279  
    280         if (!REG_SUPP(mii)) 
    281                 return -EFAULT; 
    282         mutex_lock(&bus->mdio_lock); 
    283         err = bus->write(bus, mii.p, mii.m, value); 
    284         mutex_unlock(&bus->mdio_lock); 
    285         if (err < 0) { 
    286                 state->proc_errno = err; 
    287302                pr_warning("IP175C: Unable to set MII register %d,%d to %d: error %d\n", mii.p,mii.m,value,-err); 
    288303                return err; 
     
    290305        mdelay(2); 
    291306        getPhy(state, mii); 
    292         pr_debug("IP175C: Set MII register %d,%d to %04x\n", mii.p, mii.m, value); 
    293307        return 0; 
    294308} 
     
    471485                                return val; 
    472486                        } 
    473                         state->ports[i].vlan_tag = val; 
     487                        state->ports[i].pvid = val; 
    474488                } else { 
    475                         state->ports[i].vlan_tag = 0; 
     489                        state->ports[i].pvid = 0; 
    476490                } 
    477491        } 
     
    494508                        state->vlan_ports[j] = 0; 
    495509                        for (i=0; i<state->regs->NUM_PORTS; i++) { 
    496                                 if ((state->ports[i].vlan_tag == j) || 
    497                                                 (state->ports[i].vlan_tag == 0)) { 
     510                                if ((state->ports[i].pvid == j) || 
     511                                                (state->ports[i].pvid == 0)) { 
    498512                                        state->vlan_ports[j] |= (1<<i); 
    499513                                } 
     
    611625                if (REG_SUPP(state->regs->VLAN_DEFAULT_TAG_REG[i])) { 
    612626                        int err = setPhy(state, state->regs->VLAN_DEFAULT_TAG_REG[i], 
    613                                         state->ports[i].vlan_tag); 
     627                                        state->ports[i].pvid); 
    614628                        if (err < 0) { 
    615629                                return err; 
     
    639653        } 
    640654 
    641         for (i=0; i<state->regs->NUM_PORTS; i++) { 
    642                 int oldtag = state->ports[i].vlan_tag; 
    643                 if (oldtag >= 0 && oldtag < MAX_VLANS) { 
    644                         if (state->vlan_ports[oldtag] & (1<<i)) { 
    645                                 continue; // primary vlan is valid. 
    646                         } 
    647                 } 
    648                 state->ports[i].vlan_tag = 0; 
    649         } 
     655 
    650656 
    651657        for (i=0; i<state->regs->NUM_PORTS; i++) { 
    652658                unsigned int portmask = (1<<i); 
    653                 state->ports[i].shareports = portmask; 
    654                 for (j=0; j<MAX_VLANS; j++) { 
    655                         if (state->vlan_ports[j] & portmask) { 
    656                                 state->ports[i].shareports |= state->vlan_ports[j]; 
    657                                 if (state->ports[i].vlan_tag == 0) { 
    658                                         state->ports[i].vlan_tag = j; 
    659                                 } 
    660                         } 
    661                 } 
    662659                if (!state->vlan_enabled) { 
    663660                        // share with everybody! 
    664661                        state->ports[i].shareports = (1<<state->regs->NUM_PORTS)-1; 
     662                        continue; 
     663                } 
     664                state->ports[i].shareports = portmask; 
     665                for (j=0; j<MAX_VLANS; j++) { 
     666                        if (state->vlan_ports[j] & portmask) 
     667                                state->ports[i].shareports |= state->vlan_ports[j]; 
    665668                } 
    666669        } 
     
    701704        state->remove_tag = 0x0000; 
    702705        state->add_tag = 0x0000; 
    703         for (i = 0; i < MAX_PORTS; i++) { 
    704                 state->ports[i].vlan_tag = 0; 
     706        for (i = 0; i < MAX_PORTS; i++) 
    705707                state->ports[i].shareports = 0xffff; 
    706         } 
    707         for (i = 0; i < MAX_VLANS; i++) { 
     708 
     709        for (i = 0; i < MAX_VLANS; i++) 
    708710                state->vlan_ports[i] = 0x0; 
    709         } 
    710711 
    711712        if (state->vlan_enabled) { 
     
    774775                } 
    775776        } 
    776         /* 
    777         // no primary vlan id support in swconfig? 
    778         // primary vlan will be set to the first non-zero vlan a port is a member of. 
    779         for (i = 0; i< state->regs->NUM_PORTS; i++) { 
    780                 if (vlan_config->pvid & (1<<i)) { 
    781                         state->ports[i].vlan_tag = nr; 
    782                 } 
    783         } 
    784         */ 
    785777 
    786778        correct_vlan_state(state); 
     
    955947 
    956948        if (retval < 0) { 
    957                 state->proc_errno = retval; 
    958949                return retval; 
    959950        } else { 
    960                 state->proc_errno = 0; 
    961951                val->value.i = retval; 
    962952                return 0; 
     
    968958{ 
    969959        struct ip175c_state *state = dev->priv; 
    970         int myval; 
     960        int myval, err = 0; 
    971961 
    972962        myval = val->value.i; 
    973963        if (myval <= 0xffff && myval >= 0 && REG_SUPP(state->proc_mii)) { 
    974                 state->proc_errno = setPhy(state, state->proc_mii, (u16)myval); 
    975         } else { 
    976                 state->proc_errno = -EINVAL; 
    977         } 
    978         return state->proc_errno; 
    979 } 
    980  
    981 /*! get the errno of the last read/write of "val" */ 
    982 static int ip175c_get_errno(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) 
    983 { 
    984         struct ip175c_state *state = dev->priv; 
    985         val->value.i = state->proc_errno; 
    986         return 0; 
     964                err = setPhy(state, state->proc_mii, (u16)myval); 
     965        } 
     966        return err; 
    987967} 
    988968 
     
    997977static int ip175c_set_port_speed(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) 
    998978{ 
     979        struct ip175c_state *state = dev->priv; 
     980        struct mii_bus *bus = state->mii_bus; 
    999981        int nr = val->port_vlan; 
    1000         struct ip175c_state *state = dev->priv; 
    1001         struct phy_device *phy; 
    1002982        int ctrl; 
    1003983        int autoneg; 
     
    1014994        } 
    1015995 
    1016         if (nr == state->regs->CPU_PORT) { 
    1017                 return -EINVAL; // can't set speed for cpu port! 
    1018         } 
     996        /* can't set speed for cpu port */ 
     997        if (nr == state->regs->CPU_PORT) 
     998                return -EINVAL; 
    1019999 
    10201000        if (nr >= dev->ports || nr < 0) 
    10211001                return -EINVAL; 
    1022         phy = state->ports[nr].phy; 
    1023         if (!phy) 
    1024                 return -EINVAL; 
    1025  
    1026         ctrl = phy_read(phy, 0); 
     1002 
     1003        ctrl = ip_phy_read(bus, nr, 0); 
    10271004        if (ctrl < 0) 
    10281005                return -EIO; 
     
    10331010        ctrl |= (speed<<13); 
    10341011 
    1035         return phy_write(phy, 0, ctrl); 
     1012        return ip_phy_write(bus, nr, 0, ctrl); 
    10361013} 
    10371014 
    10381015static int ip175c_get_port_speed(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) 
    10391016{ 
     1017        struct ip175c_state *state = dev->priv; 
     1018        struct mii_bus *bus = state->mii_bus; 
    10401019        int nr = val->port_vlan; 
    1041         struct ip175c_state *state = dev->priv; 
    1042         struct phy_device *phy; 
    10431020        int speed, status; 
    10441021 
     
    10501027        if (nr >= dev->ports || nr < 0) 
    10511028                return -EINVAL; 
    1052         phy = state->ports[nr].phy; 
    1053         if (!phy) 
    1054                 return -EINVAL; 
    1055  
    1056         status = phy_read(phy, 1); 
    1057         speed = phy_read(phy, 18); 
     1029 
     1030        status = ip_phy_read(bus, nr, 1); 
     1031        speed = ip_phy_read(bus, nr, 18); 
    10581032        if (status < 0 || speed < 0) 
    10591033                return -EIO; 
     
    10701044static int ip175c_get_port_status(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) 
    10711045{ 
     1046        struct ip175c_state *state = dev->priv; 
     1047        struct mii_bus *bus = state->mii_bus; 
     1048        int ctrl, speed, status; 
    10721049        int nr = val->port_vlan; 
    1073         struct ip175c_state *state = dev->priv; 
    1074         struct phy_device *phy; 
    1075         int ctrl, speed, status; 
    10761050        int len; 
    10771051        char *buf = state->buf; // fixed-length at 80. 
     
    10851059        if (nr >= dev->ports || nr < 0) 
    10861060                return -EINVAL; 
    1087         phy = state->ports[nr].phy; 
    1088         if (!phy) 
    1089                 return -EINVAL; 
    1090  
    1091         ctrl = phy_read(phy, 0); 
    1092         status = phy_read(phy, 1); 
    1093         speed = phy_read(phy, 18); 
     1061 
     1062        ctrl = ip_phy_read(bus, nr, 0); 
     1063        status = ip_phy_read(bus, nr, 1); 
     1064        speed = ip_phy_read(bus, nr, 18); 
    10941065        if (ctrl < 0 || status < 0 || speed < 0) 
    10951066                return -EIO; 
     
    11161087} 
    11171088 
     1089static int ip175c_get_pvid(struct switch_dev *dev, int port, int *val) 
     1090{ 
     1091        struct ip175c_state *state = dev->priv; 
     1092 
     1093        *val = state->ports[port].pvid; 
     1094        return 0; 
     1095} 
     1096 
     1097static int ip175c_set_pvid(struct switch_dev *dev, int port, int val) 
     1098{ 
     1099        struct ip175c_state *state = dev->priv; 
     1100 
     1101        state->ports[port].pvid = val; 
     1102 
     1103        if (!REG_SUPP(state->regs->VLAN_DEFAULT_TAG_REG[port])) 
     1104                return 0; 
     1105 
     1106        return setPhy(state, state->regs->VLAN_DEFAULT_TAG_REG[port], val); 
     1107} 
     1108 
     1109 
    11181110enum Ports { 
    11191111        IP175C_PORT_STATUS, 
    11201112        IP175C_PORT_LINK, 
    11211113        IP175C_PORT_TAGGED, 
     1114        IP175C_PORT_PVID, 
    11221115}; 
    11231116 
     
    11821175                .set = ip175c_set_val, 
    11831176        }, 
    1184         [IP175C_REGISTER_ERRNO] = { 
    1185                 .id = IP175C_REGISTER_ERRNO, 
    1186                 .type = SWITCH_TYPE_INT, 
    1187                 .description = "Direct register access: returns last read or write error", 
    1188                 .name  = "errno", 
    1189                 .get  = ip175c_get_errno, 
    1190                 .set = NULL, 
    1191         }, 
    1192  
    11931177}; 
    11941178 
     
    12451229        dev->attr_vlan.n_attr = ARRAY_SIZE(ip175c_vlan); 
    12461230 
     1231        dev->get_port_pvid = ip175c_get_pvid; 
     1232        dev->set_port_pvid = ip175c_set_pvid; 
    12471233        dev->get_vlan_ports = ip175c_get_ports; 
    12481234        dev->set_vlan_ports = ip175c_set_ports; 
Note: See TracChangeset for help on using the changeset viewer.