Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

atm: [suni] add support for setting loopback and framing modes

Signed-off-by: Chas Williams <chas@cmf.nrl.navy.mil>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Chas Williams and committed by
David S. Miller
df3bc8bd 2be63b87

+133 -21
+105 -16
drivers/atm/suni.c
··· 1 - /* drivers/atm/suni.c - PMC PM5346 SUNI (PHY) driver */ 1 + /* 2 + * drivers/atm/suni.c - S/UNI PHY driver 3 + * 4 + * Supports the following: 5 + * PMC PM5346 S/UNI LITE 6 + * PMC PM5350 S/UNI 155 ULTRA 7 + * PMC PM5355 S/UNI 622 8 + */ 2 9 3 10 /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ 4 - 5 11 6 12 #include <linux/module.h> 7 13 #include <linux/jiffies.h> ··· 152 146 static int set_loopback(struct atm_dev *dev,int mode) 153 147 { 154 148 unsigned char control; 149 + int reg, dle, lle; 155 150 156 - control = GET(MCT) & ~(SUNI_MCT_DLE | SUNI_MCT_LLE); 151 + if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) { 152 + reg = SUNI_MCM; 153 + dle = SUNI_MCM_DLE; 154 + lle = SUNI_MCM_LLE; 155 + } else { 156 + reg = SUNI_MCT; 157 + dle = SUNI_MCT_DLE; 158 + lle = SUNI_MCT_LLE; 159 + } 160 + 161 + control = dev->ops->phy_get(dev, reg) & ~(dle | lle); 157 162 switch (mode) { 158 163 case ATM_LM_NONE: 159 164 break; 160 165 case ATM_LM_LOC_PHY: 161 - control |= SUNI_MCT_DLE; 166 + control |= dle; 162 167 break; 163 168 case ATM_LM_RMT_PHY: 164 - control |= SUNI_MCT_LLE; 169 + control |= lle; 165 170 break; 166 171 default: 167 172 return -EINVAL; 168 173 } 169 - PUT(control,MCT); 174 + dev->ops->phy_put(dev, control, reg); 170 175 PRIV(dev)->loop_mode = mode; 171 176 return 0; 177 + } 178 + 179 + /* 180 + * SONET vs. SDH Configuration 181 + * 182 + * Z0INS (register 0x06): 0 for SONET, 1 for SDH 183 + * ENSS (register 0x3D): 0 for SONET, 1 for SDH 184 + * LEN16 (register 0x28): 0 for SONET, 1 for SDH (n/a for S/UNI 155 QUAD) 185 + * LEN16 (register 0x50): 0 for SONET, 1 for SDH (n/a for S/UNI 155 QUAD) 186 + * S[1:0] (register 0x46): 00 for SONET, 10 for SDH 187 + */ 188 + 189 + static int set_sonet(struct atm_dev *dev) 190 + { 191 + if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) { 192 + PUT(GET(RPOP_RC) & ~SUNI_RPOP_RC_ENSS, RPOP_RC); 193 + PUT(GET(SSTB_CTRL) & ~SUNI_SSTB_CTRL_LEN16, SSTB_CTRL); 194 + PUT(GET(SPTB_CTRL) & ~SUNI_SPTB_CTRL_LEN16, SPTB_CTRL); 195 + } 196 + 197 + REG_CHANGE(SUNI_TPOP_APM_S, SUNI_TPOP_APM_S_SHIFT, 198 + SUNI_TPOP_S_SONET, TPOP_APM); 199 + 200 + return 0; 201 + } 202 + 203 + static int set_sdh(struct atm_dev *dev) 204 + { 205 + if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) { 206 + PUT(GET(RPOP_RC) | SUNI_RPOP_RC_ENSS, RPOP_RC); 207 + PUT(GET(SSTB_CTRL) | SUNI_SSTB_CTRL_LEN16, SSTB_CTRL); 208 + PUT(GET(SPTB_CTRL) | SUNI_SPTB_CTRL_LEN16, SPTB_CTRL); 209 + } 210 + 211 + REG_CHANGE(SUNI_TPOP_APM_S, SUNI_TPOP_APM_S_SHIFT, 212 + SUNI_TPOP_S_SDH, TPOP_APM); 213 + 214 + return 0; 215 + } 216 + 217 + 218 + static int get_framing(struct atm_dev *dev, void __user *arg) 219 + { 220 + int framing; 221 + unsigned char s; 222 + 223 + 224 + s = (GET(TPOP_APM) & SUNI_TPOP_APM_S) >> SUNI_TPOP_APM_S_SHIFT; 225 + if (s == SUNI_TPOP_S_SONET) 226 + framing = SONET_FRAME_SONET; 227 + else 228 + framing = SONET_FRAME_SDH; 229 + 230 + return put_user(framing, (int __user *) arg) ? -EFAULT : 0; 231 + } 232 + 233 + static int set_framing(struct atm_dev *dev, void __user *arg) 234 + { 235 + int mode; 236 + 237 + if (get_user(mode, (int __user *) arg)) 238 + return -EFAULT; 239 + 240 + if (mode == SONET_FRAME_SONET) 241 + return set_sonet(dev); 242 + else if (mode == SONET_FRAME_SDH) 243 + return set_sdh(dev); 244 + 245 + return -EINVAL; 172 246 } 173 247 174 248 ··· 265 179 case SONET_GETDIAG: 266 180 return get_diag(dev,arg); 267 181 case SONET_SETFRAMING: 268 - if ((int)(unsigned long)arg != SONET_FRAME_SONET) return -EINVAL; 269 - return 0; 182 + if (!capable(CAP_NET_ADMIN)) 183 + return -EPERM; 184 + return set_framing(dev, arg); 270 185 case SONET_GETFRAMING: 271 - return put_user(SONET_FRAME_SONET,(int __user *)arg) ? 272 - -EFAULT : 0; 186 + return get_framing(dev, arg); 273 187 case SONET_GETFRSENSE: 274 188 return -EINVAL; 275 189 case ATM_SETLOOP: 190 + if (!capable(CAP_NET_ADMIN)) 191 + return -EPERM; 276 192 return set_loopback(dev,(int)(unsigned long)arg); 277 193 case ATM_GETLOOP: 278 194 return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ? ··· 308 220 unsigned long flags; 309 221 int first; 310 222 311 - if (!(dev->phy_data = kmalloc(sizeof(struct suni_priv),GFP_KERNEL))) 312 - return -ENOMEM; 313 - 314 - PRIV(dev)->dev = dev; 315 223 spin_lock_irqsave(&sunis_lock,flags); 316 224 first = !sunis; 317 225 PRIV(dev)->next = sunis; ··· 368 284 { 369 285 unsigned char mri; 370 286 287 + if (!(dev->phy_data = kmalloc(sizeof(struct suni_priv),GFP_KERNEL))) 288 + return -ENOMEM; 289 + PRIV(dev)->dev = dev; 290 + 371 291 mri = GET(MRI); /* reset SUNI */ 292 + PRIV(dev)->type = (mri & SUNI_MRI_TYPE) >> SUNI_MRI_TYPE_SHIFT; 372 293 PUT(mri | SUNI_MRI_RESET,MRI); 373 294 PUT(mri,MRI); 374 295 PUT((GET(MT) & SUNI_MT_DS27_53),MT); /* disable all tests */ 375 - REG_CHANGE(SUNI_TPOP_APM_S,SUNI_TPOP_APM_S_SHIFT,SUNI_TPOP_S_SONET, 376 - TPOP_APM); /* use SONET */ 296 + set_sonet(dev); 377 297 REG_CHANGE(SUNI_TACP_IUCHP_CLP,0,SUNI_TACP_IUCHP_CLP, 378 298 TACP_IUCHP); /* idle cells */ 379 299 PUT(SUNI_IDLE_PATTERN,TACP_IUCPOP); 380 300 dev->phy = &suni_ops; 301 + 381 302 return 0; 382 303 } 383 304
+27 -4
drivers/atm/suni.h
··· 1 - /* drivers/atm/suni.h - PMC PM5346 SUNI (PHY) declarations */ 1 + /* 2 + * drivers/atm/suni.h - S/UNI PHY driver 3 + */ 2 4 3 5 /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ 4 - 5 6 6 7 #ifndef DRIVER_ATM_SUNI_H 7 8 #define DRIVER_ATM_SUNI_H ··· 40 39 #define SUNI_RLOP_LFM 0x1F /* RLOP Line FEBE MSB */ 41 40 #define SUNI_TLOP_CTRL 0x20 /* TLOP Control */ 42 41 #define SUNI_TLOP_DIAG 0x21 /* TLOP Diagnostic */ 43 - /* 0x22-0x2F reserved */ 42 + /* 0x22-0x27 reserved */ 43 + #define SUNI_SSTB_CTRL 0x28 44 44 #define SUNI_RPOP_SC 0x30 /* RPOP Status/Control */ 45 45 #define SUNI_RPOP_IS 0x31 /* RPOP Interrupt Status */ 46 46 /* 0x32 reserved */ ··· 54 52 #define SUNI_RPOP_PFM 0x3B /* RPOP Path FEBE MSB */ 55 53 /* 0x3C reserved */ 56 54 #define SUNI_RPOP_PBC 0x3D /* RPOP Path BIP-8 Configuration */ 55 + #define SUNI_RPOP_RC 0x3D /* RPOP Ring Control (PM5355) */ 57 56 /* 0x3E-0x3F reserved */ 58 57 #define SUNI_TPOP_CD 0x40 /* TPOP Control/Diagnostic */ 59 58 #define SUNI_TPOP_PC 0x41 /* TPOP Pointer Control */ ··· 85 82 #define SUNI_TACP_TCC 0x65 /* TACP Transmit Cell Counter */ 86 83 #define SUNI_TACP_TCCM 0x66 /* TACP Transmit Cell Counter MSB */ 87 84 #define SUNI_TACP_CFG 0x67 /* TACP Configuration */ 88 - /* 0x68-0x7F reserved */ 85 + #define SUNI_SPTB_CTRL 0x68 /* SPTB Control */ 86 + /* 0x69-0x7F reserved */ 89 87 #define SUNI_MT 0x80 /* Master Test */ 90 88 /* 0x81-0xFF reserved */ 91 89 ··· 98 94 #define SUNI_MRI_ID_SHIFT 0 99 95 #define SUNI_MRI_TYPE 0x70 /* R, SUNI type (lite is 011) */ 100 96 #define SUNI_MRI_TYPE_SHIFT 4 97 + #define SUNI_MRI_TYPE_PM5346 0x3 /* S/UNI 155 LITE */ 98 + #define SUNI_MRI_TYPE_PM5347 0x4 /* S/UNI 155 PLUS */ 99 + #define SUNI_MRI_TYPE_PM5350 0x7 /* S/UNI 155 ULTRA */ 100 + #define SUNI_MRI_TYPE_PM5355 0x1 /* S/UNI 622 */ 101 101 #define SUNI_MRI_RESET 0x80 /* RW, reset & power down chip 102 102 0: normal operation 103 103 1: reset & low power */ 104 + 105 + /* MCM is reg 0x4 */ 106 + #define SUNI_MCM_LLE 0x20 /* line loopback (PM5355) */ 107 + #define SUNI_MCM_DLE 0x10 /* diagnostic loopback (PM5355) */ 108 + 104 109 /* MCT is reg 5 */ 105 110 #define SUNI_MCT_LOOPT 0x01 /* RW, timing source, 0: from 106 111 TRCLK+/- */ ··· 156 143 157 144 /* TLOP_DIAG is reg 0x21 */ 158 145 #define SUNI_TLOP_DIAG_DBIP 0x01 /* insert line BIP err (continuously) */ 146 + 147 + /* SSTB_CTRL is reg 0x28 */ 148 + #define SUNI_SSTB_CTRL_LEN16 0x01 /* path trace message length bit */ 149 + 150 + /* RPOP_RC is reg 0x3D (PM5355) */ 151 + #define SUNI_RPOP_RC_ENSS 0x40 /* enable size bit */ 159 152 160 153 /* TPOP_DIAG is reg 0x40 */ 161 154 #define SUNI_TPOP_DIAG_PAIS 0x01 /* insert STS path alarm ind (cont) */ ··· 210 191 pattern */ 211 192 #define SUNI_TACP_IUCHP_GFC_SHIFT 4 212 193 194 + /* SPTB_CTRL is reg 0x68 */ 195 + #define SUNI_SPTB_CTRL_LEN16 0x01 /* path trace message length */ 196 + 213 197 /* MT is reg 0x80 */ 214 198 #define SUNI_MT_HIZIO 0x01 /* RW, all but data bus & MP interface 215 199 tri-state */ ··· 230 208 struct suni_priv { 231 209 struct k_sonet_stats sonet_stats; /* link diagnostics */ 232 210 int loop_mode; /* loopback mode */ 211 + int type; /* phy type */ 233 212 struct atm_dev *dev; /* device back-pointer */ 234 213 struct suni_priv *next; /* next SUNI */ 235 214 };
+1 -1
include/linux/sonet.h
··· 34 34 /* clear error insertion */ 35 35 #define SONET_GETDIAG _IOR('a',ATMIOC_PHYTYP+4,int) 36 36 /* query error insertion */ 37 - #define SONET_SETFRAMING _IO('a',ATMIOC_PHYTYP+5) 37 + #define SONET_SETFRAMING _IOW('a',ATMIOC_PHYTYP+5,int) 38 38 /* set framing mode (SONET/SDH) */ 39 39 #define SONET_GETFRAMING _IOR('a',ATMIOC_PHYTYP+6,int) 40 40 /* get framing mode */