Ignore:
Timestamp:
2010-07-01T20:08:19+02:00 (6 years ago)
Author:
juhosg
Message:

backfire: generic: rtl8366: move common VLAN handling functions to rtl8366_smi.c (backport of 21979)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/backfire/target/linux/generic-2.6/files/drivers/net/phy/rtl8366s.c

    r22024 r22025  
    662662} 
    663663 
    664 static int rtl8366s_set_vlan(struct rtl8366_smi *smi, int vid, u32 member, 
    665                              u32 untag, u32 fid) 
    666 { 
    667         struct rtl8366_vlan_4k vlan4k; 
    668         int err; 
    669         int i; 
    670  
    671         /* Update the 4K table */ 
    672         err = smi->ops->get_vlan_4k(smi, vid, &vlan4k); 
    673         if (err) 
    674                 return err; 
    675  
    676         vlan4k.member = member; 
    677         vlan4k.untag = untag; 
    678         vlan4k.fid = fid; 
    679         err = smi->ops->set_vlan_4k(smi, &vlan4k); 
    680         if (err) 
    681                 return err; 
    682  
    683         /* Try to find an existing MC entry for this VID */ 
    684         for (i = 0; i < smi->num_vlan_mc; i++) { 
    685                 struct rtl8366_vlan_mc vlanmc; 
    686  
    687                 err = smi->ops->get_vlan_mc(smi, i, &vlanmc); 
    688                 if (err) 
    689                         return err; 
    690  
    691                 if (vid == vlanmc.vid) { 
    692                         /* update the MC entry */ 
    693                         vlanmc.member = member; 
    694                         vlanmc.untag = untag; 
    695                         vlanmc.fid = fid; 
    696  
    697                         err = smi->ops->set_vlan_mc(smi, i, &vlanmc); 
    698                         break; 
    699                 } 
    700         } 
    701  
    702         return err; 
    703 } 
    704  
    705 static int rtl8366s_get_pvid(struct rtl8366_smi *smi, int port, int *val) 
    706 { 
    707         struct rtl8366_vlan_mc vlanmc; 
    708         int err; 
    709         int index; 
    710  
    711         err = smi->ops->get_mc_index(smi, port, &index); 
    712         if (err) 
    713                 return err; 
    714  
    715         err = smi->ops->get_vlan_mc(smi, index, &vlanmc); 
    716         if (err) 
    717                 return err; 
    718  
    719         *val = vlanmc.vid; 
    720         return 0; 
    721 } 
    722  
    723 static int rtl8366s_mc_is_used(struct rtl8366_smi *smi, int mc_index, 
    724                                int *used) 
    725 { 
    726         int err; 
    727         int i; 
    728  
    729         *used = 0; 
    730         for (i = 0; i < smi->num_ports; i++) { 
    731                 int index = 0; 
    732  
    733                 err = smi->ops->get_mc_index(smi, i, &index); 
    734                 if (err) 
    735                         return err; 
    736  
    737                 if (mc_index == index) { 
    738                         *used = 1; 
    739                         break; 
    740                 } 
    741         } 
    742  
    743         return 0; 
    744 } 
    745  
    746 static int rtl8366s_set_pvid(struct rtl8366_smi *smi, unsigned port, 
    747                              unsigned vid) 
    748 { 
    749         struct rtl8366_vlan_mc vlanmc; 
    750         struct rtl8366_vlan_4k vlan4k; 
    751         int err; 
    752         int i; 
    753  
    754         /* Try to find an existing MC entry for this VID */ 
    755         for (i = 0; i < smi->num_vlan_mc; i++) { 
    756                 err = smi->ops->get_vlan_mc(smi, i, &vlanmc); 
    757                 if (err) 
    758                         return err; 
    759  
    760                 if (vid == vlanmc.vid) { 
    761                         err = smi->ops->set_vlan_mc(smi, i, &vlanmc); 
    762                         if (err) 
    763                                 return err; 
    764  
    765                         err = smi->ops->set_mc_index(smi, port, i); 
    766                         return err; 
    767                 } 
    768         } 
    769  
    770         /* We have no MC entry for this VID, try to find an empty one */ 
    771         for (i = 0; i < smi->num_vlan_mc; i++) { 
    772                 err = smi->ops->get_vlan_mc(smi, i, &vlanmc); 
    773                 if (err) 
    774                         return err; 
    775  
    776                 if (vlanmc.vid == 0 && vlanmc.member == 0) { 
    777                         /* Update the entry from the 4K table */ 
    778                         err = smi->ops->get_vlan_4k(smi, vid, &vlan4k); 
    779                         if (err) 
    780                                 return err; 
    781  
    782                         vlanmc.vid = vid; 
    783                         vlanmc.member = vlan4k.member; 
    784                         vlanmc.untag = vlan4k.untag; 
    785                         vlanmc.fid = vlan4k.fid; 
    786                         err = smi->ops->set_vlan_mc(smi, i, &vlanmc); 
    787                         if (err) 
    788                                 return err; 
    789  
    790                         err = smi->ops->set_mc_index(smi, port, i); 
    791                         return err; 
    792                 } 
    793         } 
    794  
    795         /* MC table is full, try to find an unused entry and replace it */ 
    796         for (i = 0; i < smi->num_vlan_mc; i++) { 
    797                 int used; 
    798  
    799                 err = rtl8366s_mc_is_used(smi, i, &used); 
    800                 if (err) 
    801                         return err; 
    802  
    803                 if (!used) { 
    804                         /* Update the entry from the 4K table */ 
    805                         err = smi->ops->get_vlan_4k(smi, vid, &vlan4k); 
    806                         if (err) 
    807                                 return err; 
    808  
    809                         vlanmc.vid = vid; 
    810                         vlanmc.member = vlan4k.member; 
    811                         vlanmc.untag = vlan4k.untag; 
    812                         vlanmc.fid = vlan4k.fid; 
    813                         err = smi->ops->set_vlan_mc(smi, i, &vlanmc); 
    814                         if (err) 
    815                                 return err; 
    816  
    817                         err = smi->ops->set_mc_index(smi, port, i); 
    818                         return err; 
    819                 } 
    820         } 
    821  
    822         dev_err(smi->parent, 
    823                 "all VLAN member configurations are in use\n"); 
    824  
    825         return -ENOSPC; 
    826 } 
    827  
    828664static int rtl8366s_vlan_set_vlan(struct rtl8366_smi *smi, int enable) 
    829665{ 
     
    837673        return rtl8366_smi_rmwr(smi, RTL8366S_VLAN_TB_CTRL_REG, 
    838674                                1, (enable) ? 1 : 0); 
    839 } 
    840  
    841 static int rtl8366s_reset_vlan(struct rtl8366_smi *smi) 
    842 { 
    843         struct rtl8366_vlan_mc vlanmc; 
    844         int err; 
    845         int i; 
    846  
    847         /* clear VLAN member configurations */ 
    848         vlanmc.vid = 0; 
    849         vlanmc.priority = 0; 
    850         vlanmc.member = 0; 
    851         vlanmc.untag = 0; 
    852         vlanmc.fid = 0; 
    853         for (i = 0; i < smi->num_vlan_mc; i++) { 
    854                 err = smi->ops->set_vlan_mc(smi, i, &vlanmc); 
    855                 if (err) 
    856                         return err; 
    857         } 
    858  
    859         for (i = 0; i < smi->num_ports; i++) { 
    860                 if (i == smi->cpu_port) 
    861                         continue; 
    862  
    863                 err = rtl8366s_set_vlan(smi, (i + 1), 
    864                                          (1 << i) | (1 << smi->cpu_port), 
    865                                          (1 << i) | (1 << smi->cpu_port), 
    866                                          0); 
    867                 if (err) 
    868                         return err; 
    869  
    870                 err = rtl8366s_set_pvid(smi, i, (i + 1)); 
    871                 if (err) 
    872                         return err; 
    873         } 
    874  
    875         return 0; 
    876675} 
    877676 
     
    14011200        } 
    14021201 
    1403         return rtl8366s_set_vlan(smi, val->port_vlan, member, untag, 0); 
     1202        return rtl8366_set_vlan(smi, val->port_vlan, member, untag, 0); 
    14041203} 
    14051204 
     
    14071206{ 
    14081207        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
    1409         return rtl8366s_get_pvid(smi, port, val); 
     1208        return rtl8366_get_pvid(smi, port, val); 
    14101209} 
    14111210 
     
    14131212{ 
    14141213        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
    1415         return rtl8366s_set_pvid(smi, port, val); 
     1214        return rtl8366_set_pvid(smi, port, val); 
    14161215} 
    14171216 
     
    14291228                return err; 
    14301229 
    1431         return rtl8366s_reset_vlan(smi); 
     1230        return rtl8366_reset_vlan(smi); 
    14321231} 
    14331232 
Note: See TracChangeset for help on using the changeset viewer.