11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* drivers/atm/uPD98402.c - NEC uPD98402 (PHY) declarations */ 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h> 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h> 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/atmdev.h> 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sonet.h> 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 125a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h> 1460063497a95e716c9a689af3be2687d261f115b4Arun Sharma#include <linux/atomic.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "uPD98402.h" 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args) 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DPRINTK(format,args...) 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct uPD98402_priv { 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct k_sonet_stats sonet_stats;/* link diagnostics */ 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char framing; /* SONET/SDH framing */ 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int loop_mode; /* loopback mode */ 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spinlock_t lock; 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PRIV(dev) ((struct uPD98402_priv *) dev->phy_data) 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PUT(val,reg) dev->ops->phy_put(dev,val,uPD98402_##reg) 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define GET(reg) dev->ops->phy_get(dev,uPD98402_##reg) 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int fetch_stats(struct atm_dev *dev,struct sonet_stats __user *arg,int zero) 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sonet_stats tmp; 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int error = 0; 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds atomic_add(GET(HECCT),&PRIV(dev)->sonet_stats.uncorr_hcs); 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sonet_copy_stats(&PRIV(dev)->sonet_stats,&tmp); 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (arg) error = copy_to_user(arg,&tmp,sizeof(tmp)); 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (zero && !error) { 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* unused fields are reported as -1, but we must not "adjust" 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds them */ 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp.corr_hcs = tmp.tx_cells = tmp.rx_cells = 0; 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sonet_subtract_stats(&PRIV(dev)->sonet_stats,&tmp); 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return error ? -EFAULT : 0; 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int set_framing(struct atm_dev *dev,unsigned char framing) 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds static const unsigned char sonet[] = { 1,2,3,0 }; 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds static const unsigned char sdh[] = { 1,0,0,2 }; 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *set; 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (framing) { 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SONET_FRAME_SONET: 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set = sonet; 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SONET_FRAME_SDH: 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set = sdh; 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&PRIV(dev)->lock, flags); 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PUT(set[0],C11T); 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PUT(set[1],C12T); 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PUT(set[2],C13T); 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PUT((GET(MDR) & ~uPD98402_MDR_SS_MASK) | (set[3] << 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds uPD98402_MDR_SS_SHIFT),MDR); 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&PRIV(dev)->lock, flags); 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int get_sense(struct atm_dev *dev,u8 __user *arg) 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char s[3]; 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&PRIV(dev)->lock, flags); 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s[0] = GET(C11R); 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s[1] = GET(C12R); 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s[2] = GET(C13R); 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&PRIV(dev)->lock, flags); 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (put_user(s[0], arg) || put_user(s[1], arg+1) || 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds put_user(s[2], arg+2) || put_user(0xff, arg+3) || 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds put_user(0xff, arg+4) || put_user(0xff, arg+5)) ? -EFAULT : 0; 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int set_loopback(struct atm_dev *dev,int mode) 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char mode_reg; 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode_reg = GET(MDR) & ~(uPD98402_MDR_TPLP | uPD98402_MDR_ALP | 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds uPD98402_MDR_RPLP); 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (__ATM_LM_XTLOC(mode)) { 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case __ATM_LM_NONE: 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case __ATM_LM_PHY: 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode_reg |= uPD98402_MDR_TPLP; 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case __ATM_LM_ATM: 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode_reg |= uPD98402_MDR_ALP; 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (__ATM_LM_XTRMT(mode)) { 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case __ATM_LM_NONE: 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case __ATM_LM_PHY: 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode_reg |= uPD98402_MDR_RPLP; 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PUT(mode_reg,MDR); 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PRIV(dev)->loop_mode = mode; 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int uPD98402_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg) 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SONET_GETSTATZ: 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SONET_GETSTAT: 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return fetch_stats(dev,arg, cmd == SONET_GETSTATZ); 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SONET_SETFRAMING: 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return set_framing(dev, (int)(unsigned long)arg); 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SONET_GETFRAMING: 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return put_user(PRIV(dev)->framing,(int __user *)arg) ? 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds -EFAULT : 0; 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SONET_GETFRSENSE: 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return get_sense(dev,arg); 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATM_SETLOOP: 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return set_loopback(dev, (int)(unsigned long)arg); 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATM_GETLOOP: 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ? 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds -EFAULT : 0; 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATM_QUERYLOOP: 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return put_user(ATM_LM_LOC_PHY | ATM_LM_LOC_ATM | 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ATM_LM_RMT_PHY,(int __user *)arg) ? -EFAULT : 0; 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOIOCTLCMD; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ADD_LIMITED(s,v) \ 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { atomic_add(GET(v),&PRIV(dev)->sonet_stats.s); \ 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (atomic_read(&PRIV(dev)->sonet_stats.s) < 0) \ 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds atomic_set(&PRIV(dev)->sonet_stats.s,INT_MAX); } 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void stat_event(struct atm_dev *dev) 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char events; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events = GET(PCR); 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (events & uPD98402_PFM_PFEB) ADD_LIMITED(path_febe,PFECB); 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (events & uPD98402_PFM_LFEB) ADD_LIMITED(line_febe,LECCT); 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (events & uPD98402_PFM_B3E) ADD_LIMITED(path_bip,B3ECT); 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (events & uPD98402_PFM_B2E) ADD_LIMITED(line_bip,B2ECT); 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (events & uPD98402_PFM_B1E) ADD_LIMITED(section_bip,B1ECT); 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef ADD_LIMITED 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void uPD98402_int(struct atm_dev *dev) 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds static unsigned long silence = 0; 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char reason; 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while ((reason = GET(PICR))) { 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (reason & uPD98402_INT_LOS) 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_NOTICE "%s(itf %d): signal lost\n", 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->type,dev->number); 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (reason & uPD98402_INT_PFM) stat_event(dev); 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (reason & uPD98402_INT_PCO) { 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void) GET(PCOCR); /* clear interrupt cause */ 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds atomic_add(GET(HECCT), 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &PRIV(dev)->sonet_stats.uncorr_hcs); 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((reason & uPD98402_INT_RFO) && 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (time_after(jiffies, silence) || silence == 0)) { 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "%s(itf %d): uPD98402 receive " 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "FIFO overflow\n",dev->type,dev->number); 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds silence = (jiffies+HZ/2)|1; 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int uPD98402_start(struct atm_dev *dev) 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DPRINTK("phy_start\n"); 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(dev->dev_data = kmalloc(sizeof(struct uPD98402_priv),GFP_KERNEL))) 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_init(&PRIV(dev)->lock); 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(&PRIV(dev)->sonet_stats,0,sizeof(struct k_sonet_stats)); 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void) GET(PCR); /* clear performance events */ 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PUT(uPD98402_PFM_FJ,PCMR); /* ignore frequency adj */ 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void) GET(PCOCR); /* clear overflows */ 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PUT(~uPD98402_PCO_HECC,PCOMR); 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void) GET(PICR); /* clear interrupts */ 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PUT(~(uPD98402_INT_PFM | uPD98402_INT_ALM | uPD98402_INT_RFO | 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds uPD98402_INT_LOS),PIMR); /* enable them */ 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void) fetch_stats(dev,NULL,1); /* clear kernel counters */ 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds atomic_set(&PRIV(dev)->sonet_stats.corr_hcs,-1); 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds atomic_set(&PRIV(dev)->sonet_stats.tx_cells,-1); 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds atomic_set(&PRIV(dev)->sonet_stats.rx_cells,-1); 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int uPD98402_stop(struct atm_dev *dev) 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* let SAR driver worry about stopping interrupts */ 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(PRIV(dev)); 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const struct atmphy_ops uPD98402_ops = { 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .start = uPD98402_start, 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ioctl = uPD98402_ioctl, 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .interrupt = uPD98402_int, 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .stop = uPD98402_stop, 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint uPD98402_init(struct atm_dev *dev) 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsDPRINTK("phy_init\n"); 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->phy = &uPD98402_ops; 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(uPD98402_init); 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic __init int uPD98402_module_init(void) 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(uPD98402_module_init); 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* module_exit not defined so not unloadable */ 266