]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/cxt1e1/pmcc4_drv.c
Merge tag 'fbdev-omap-dt-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba...
[karo-tx-linux.git] / drivers / staging / cxt1e1 / pmcc4_drv.c
1 /*-----------------------------------------------------------------------------
2  * pmcc4_drv.c -
3  *
4  * Copyright (C) 2007  One Stop Systems, Inc.
5  * Copyright (C) 2002-2006  SBE, Inc.
6  *
7  *   This program is free software; you can redistribute it and/or modify
8  *   it under the terms of the GNU General Public License as published by
9  *   the Free Software Foundation; either version 2 of the License, or
10  *   (at your option) any later version.
11  *
12  *   This program is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  * For further information, contact via email: support@onestopsystems.com
18  * One Stop Systems, Inc.  Escondido, California  U.S.A.
19  *-----------------------------------------------------------------------------
20  */
21
22 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23
24 #include <linux/types.h>
25 #include "pmcc4_sysdep.h"
26 #include <linux/errno.h>
27 #include <linux/kernel.h>
28 #include <linux/sched.h>        /* include for timer */
29 #include <linux/timer.h>        /* include for timer */
30 #include <linux/hdlc.h>
31 #include <linux/io.h>
32
33 #include "sbecom_inline_linux.h"
34 #include "libsbew.h"
35 #include "pmcc4_private.h"
36 #include "pmcc4.h"
37 #include "pmcc4_ioctls.h"
38 #include "musycc.h"
39 #include "comet.h"
40 #include "sbe_bid.h"
41
42 #define KERN_WARN KERN_WARNING
43
44 /* forward references */
45 status_t    c4_wk_chan_init (mpi_t *, mch_t *);
46 void        c4_wq_port_cleanup (mpi_t *);
47 status_t    c4_wq_port_init (mpi_t *);
48
49 int         c4_loop_port (ci_t *, int, u_int8_t);
50 status_t    c4_set_port (ci_t *, int);
51 status_t    musycc_chan_down (ci_t *, int);
52
53 u_int32_t musycc_chan_proto (int);
54 status_t    musycc_dump_ring (ci_t *, unsigned int);
55 status_t __init musycc_init (ci_t *);
56 void        musycc_init_mdt (mpi_t *);
57 void        musycc_serv_req (mpi_t *, u_int32_t);
58 void        musycc_update_timeslots (mpi_t *);
59
60 extern void musycc_update_tx_thp (mch_t *);
61 extern int  cxt1e1_log_level;
62 extern int  cxt1e1_max_mru;
63 extern int  cxt1e1_max_mtu;
64 extern int  max_rxdesc_used, max_rxdesc_default;
65 extern int  max_txdesc_used, max_txdesc_default;
66
67 #if defined (__powerpc__)
68 extern void *memset (void *s, int c, size_t n);
69
70 #endif
71
72 int         drvr_state = SBE_DRVR_INIT;
73 ci_t       *c4_list = NULL;
74 ci_t       *CI;                 /* dummy pointer to board ZEROE's data -
75                                  * DEBUG USAGE */
76
77
78 void
79 sbecom_set_loglevel (int d)
80 {
81     /*
82      * The code within the following -if- clause is a backdoor debug facility
83      * which can be used to display the state of a board's channel.
84      */
85     if (d > LOG_DEBUG)
86     {
87         unsigned int channum = d - (LOG_DEBUG + 1);     /* convert to ZERO
88                                                          * relativity */
89
90         (void) musycc_dump_ring ((ci_t *) CI, channum); /* CI implies support
91                                                          * for card 0 only */
92     } else
93     {
94         if (cxt1e1_log_level != d)
95         {
96             pr_info("log level changed from %d to %d\n", cxt1e1_log_level, d);
97             cxt1e1_log_level = d;          /* set new */
98         } else
99             pr_info("log level is %d\n", cxt1e1_log_level);
100     }
101 }
102
103
104 mch_t      *
105 c4_find_chan (int channum)
106 {
107     ci_t       *ci;
108     mch_t      *ch;
109     int         portnum, gchan;
110
111     for (ci = c4_list; ci; ci = ci->next)
112         for (portnum = 0; portnum < ci->max_port; portnum++)
113             for (gchan = 0; gchan < MUSYCC_NCHANS; gchan++)
114             {
115                 ch = ci->port[portnum].chan[gchan];
116                 if (ch) {
117                         if ((ch->state != UNASSIGNED) &&
118                            (ch->channum == channum))
119                                 return ch;
120                 }
121             }
122     return NULL;
123 }
124
125 /***
126  * Check port state and set LED states using watchdog or ioctl...
127  * also check for in-band SF loopback commands (& cause results if they are there)
128  *
129  * Alarm function depends on comet bits indicating change in
130  * link status (linkMask) to keep the link status indication straight.
131  *
132  * Indications are only LED and system log -- except when ioctl is invoked.
133  *
134  * "alarmed" record (a.k.a. copyVal, in some cases below) decodes as:
135  *
136  *   RMAI  (E1 only) 0x100
137  *   alarm LED on    0x80
138  *   link LED on     0x40
139  *   link returned   0x20 (link was down, now it's back and 'port get' hasn't run)
140  *   change in LED   0x10 (update LED register because value has changed)
141  *   link is down    0x08
142  *   YelAlm(RAI)     0x04
143  *   RedAlm          0x02
144  *   AIS(blue)Alm    0x01
145  *
146  * note "link has returned" indication is reset on read
147  * (e.g. by use of the c4_control port get command)
148  */
149
150 #define sbeLinkMask       0x41  /* change in signal status (lost/recovered) +
151                                  * state */
152 #define sbeLinkChange     0x40
153 #define sbeLinkDown       0x01
154 #define sbeAlarmsMask     0x07  /* red / yellow / blue alarm conditions */
155 #define sbeE1AlarmsMask   0x107 /* alarm conditions */
156
157 #define COMET_LBCMD_READ  0x80  /* read only (do not set, return read value) */
158
159 void
160 checkPorts (ci_t *ci)
161 {
162 #ifndef CONFIG_SBE_PMCC4_NCOMM
163     /*
164      * PORT POINT - NCOMM needs to avoid this code since the polling of
165      * alarms conflicts with NCOMM's interrupt servicing implementation.
166      */
167
168     struct s_comet_reg    *comet;
169     volatile u_int32_t value;
170     u_int32_t   copyVal, LEDval;
171
172     u_int8_t portnum;
173
174     LEDval = 0;
175     for (portnum = 0; portnum < ci->max_port; portnum++)
176     {
177         copyVal = 0x12f & (ci->alarmed[portnum]);       /* port's alarm record */
178         comet = ci->port[portnum].cometbase;
179         value = pci_read_32 ((u_int32_t *) &comet->cdrc_ists) & sbeLinkMask;    /* link loss reg */
180
181         if (value & sbeLinkChange)  /* is there a change in the link stuff */
182         {
183             /* if there's been a change (above) and yet it's the same (below) */
184             if (!(((copyVal >> 3) & sbeLinkDown) ^ (value & sbeLinkDown)))
185             {
186                 if (value & sbeLinkDown)
187                     pr_warning("%s: Port %d momentarily recovered.\n",
188                                ci->devname, portnum);
189                 else
190                     pr_warning("%s: Warning: Port %d link was briefly down.\n",
191                                ci->devname, portnum);
192             } else if (value & sbeLinkDown)
193                 pr_warning("%s: Warning: Port %d link is down.\n",
194                            ci->devname, portnum);
195             else
196             {
197                 pr_warning("%s: Port %d link has recovered.\n",
198                            ci->devname, portnum);
199                 copyVal |= 0x20;    /* record link transition to up */
200             }
201             copyVal |= 0x10;        /* change (link) --> update LEDs  */
202         }
203         copyVal &= 0x137;           /* clear LED & link old history bits &
204                                      * save others */
205         if (value & sbeLinkDown)
206             copyVal |= 0x08;        /* record link status (now) */
207         else
208         {                           /* if link is up, do this */
209             copyVal |= 0x40;        /* LED indicate link is up    */
210             /* Alarm things & the like ... first if E1, then if T1 */
211             if (IS_FRAME_ANY_E1 (ci->port[portnum].p.port_mode))
212             {
213                 /*
214                  * first check Codeword (SaX) changes & CRC and
215                  * sub-multi-frame errors
216                  */
217                 /*
218                  * note these errors are printed every time they are detected
219                  * vs. alarms
220                  */
221                 value = pci_read_32 ((u_int32_t *) &comet->e1_frmr_nat_ists);   /* codeword */
222                 if (value & 0x1f)
223                 {                   /* if errors (crc or smf only) */
224                     if (value & 0x10)
225                         pr_warning("%s: E1 Port %d Codeword Sa4 change detected.\n",
226                                    ci->devname, portnum);
227                     if (value & 0x08)
228                         pr_warning("%s: E1 Port %d Codeword Sa5 change detected.\n",
229                                    ci->devname, portnum);
230                     if (value & 0x04)
231                         pr_warning("%s: E1 Port %d Codeword Sa6 change detected.\n",
232                                    ci->devname, portnum);
233                     if (value & 0x02)
234                         pr_warning("%s: E1 Port %d Codeword Sa7 change detected.\n",
235                                    ci->devname, portnum);
236                     if (value & 0x01)
237                         pr_warning("%s: E1 Port %d Codeword Sa8 change detected.\n",
238                                    ci->devname, portnum);
239                 }
240                 value = pci_read_32 ((u_int32_t *) &comet->e1_frmr_mists);      /* crc & smf */
241                 if (value & 0x3)
242                 {                   /* if errors (crc or smf only) */
243                     if (value & sbeE1CRC)
244                         pr_warning("%s: E1 Port %d CRC-4 error(s) detected.\n",
245                                    ci->devname, portnum);
246                     if (value & sbeE1errSMF)    /* error in sub-multiframe */
247                         pr_warning("%s: E1 Port %d received errored SMF.\n",
248                                    ci->devname, portnum);
249                 }
250                 value = pci_read_32 ((u_int32_t *) &comet->e1_frmr_masts) & 0xcc; /* alarms */
251                 /*
252                  * pack alarms together (bitmiser), and construct similar to
253                  * T1
254                  */
255                 /* RAI,RMAI,.,.,LOF,AIS,.,. ==>  RMAI,.,.,.,.,.,RAI,LOF,AIS */
256                 /* see 0x97 */
257                 value = (value >> 2);
258                 if (value & 0x30)
259                 {
260                     if (value & 0x20)
261                         value |= 0x40;  /* RAI */
262                     if (value & 0x10)
263                         value |= 0x100; /* RMAI */
264                     value &= ~0x30;
265                 }                   /* finished packing alarm in handy order */
266                 if (value != (copyVal & sbeE1AlarmsMask))
267                 {                   /* if alarms changed */
268                     copyVal |= 0x10;/* change LED status   */
269                     if ((copyVal & sbeRedAlm) && !(value & sbeRedAlm))
270                     {
271                         copyVal &= ~sbeRedAlm;
272                         pr_warning("%s: E1 Port %d LOF alarm ended.\n",
273                                    ci->devname, portnum);
274                     } else if (!(copyVal & sbeRedAlm) && (value & sbeRedAlm))
275                     {
276                         copyVal |= sbeRedAlm;
277                         pr_warning("%s: E1 Warning: Port %d LOF alarm.\n",
278                                    ci->devname, portnum);
279                     } else if ((copyVal & sbeYelAlm) && !(value & sbeYelAlm))
280                     {
281                         copyVal &= ~sbeYelAlm;
282                         pr_warning("%s: E1 Port %d RAI alarm ended.\n",
283                                    ci->devname, portnum);
284                     } else if (!(copyVal & sbeYelAlm) && (value & sbeYelAlm))
285                     {
286                         copyVal |= sbeYelAlm;
287                         pr_warning("%s: E1 Warning: Port %d RAI alarm.\n",
288                                    ci->devname, portnum);
289                     } else if ((copyVal & sbeE1RMAI) && !(value & sbeE1RMAI))
290                     {
291                         copyVal &= ~sbeE1RMAI;
292                         pr_warning("%s: E1 Port %d RMAI alarm ended.\n",
293                                    ci->devname, portnum);
294                     } else if (!(copyVal & sbeE1RMAI) && (value & sbeE1RMAI))
295                     {
296                         copyVal |= sbeE1RMAI;
297                         pr_warning("%s: E1 Warning: Port %d RMAI alarm.\n",
298                                    ci->devname, portnum);
299                     } else if ((copyVal & sbeAISAlm) && !(value & sbeAISAlm))
300                     {
301                         copyVal &= ~sbeAISAlm;
302                         pr_warning("%s: E1 Port %d AIS alarm ended.\n",
303                                    ci->devname, portnum);
304                     } else if (!(copyVal & sbeAISAlm) && (value & sbeAISAlm))
305                     {
306                         copyVal |= sbeAISAlm;
307                         pr_warning("%s: E1 Warning: Port %d AIS alarm.\n",
308                                    ci->devname, portnum);
309                     }
310                 }
311                 /* end of E1 alarm code */
312             } else
313             {                       /* if a T1 mode */
314                 value = pci_read_32 ((u_int32_t *) &comet->t1_almi_ists);       /* alarms */
315                 value &= sbeAlarmsMask;
316                 if (value != (copyVal & sbeAlarmsMask))
317                 {                   /* if alarms changed */
318                     copyVal |= 0x10;/* change LED status   */
319                     if ((copyVal & sbeRedAlm) && !(value & sbeRedAlm))
320                     {
321                         copyVal &= ~sbeRedAlm;
322                         pr_warning("%s: Port %d red alarm ended.\n",
323                                    ci->devname, portnum);
324                     } else if (!(copyVal & sbeRedAlm) && (value & sbeRedAlm))
325                     {
326                         copyVal |= sbeRedAlm;
327                         pr_warning("%s: Warning: Port %d red alarm.\n",
328                                    ci->devname, portnum);
329                     } else if ((copyVal & sbeYelAlm) && !(value & sbeYelAlm))
330                     {
331                         copyVal &= ~sbeYelAlm;
332                         pr_warning("%s: Port %d yellow (RAI) alarm ended.\n",
333                                    ci->devname, portnum);
334                     } else if (!(copyVal & sbeYelAlm) && (value & sbeYelAlm))
335                     {
336                         copyVal |= sbeYelAlm;
337                         pr_warning("%s: Warning: Port %d yellow (RAI) alarm.\n",
338                                    ci->devname, portnum);
339                     } else if ((copyVal & sbeAISAlm) && !(value & sbeAISAlm))
340                     {
341                         copyVal &= ~sbeAISAlm;
342                         pr_warning("%s: Port %d blue (AIS) alarm ended.\n",
343                                    ci->devname, portnum);
344                     } else if (!(copyVal & sbeAISAlm) && (value & sbeAISAlm))
345                     {
346                         copyVal |= sbeAISAlm;
347                         pr_warning("%s: Warning: Port %d blue (AIS) alarm.\n",
348                                    ci->devname, portnum);
349                     }
350                 }
351             }                       /* end T1 mode alarm checks */
352         }
353         if (copyVal & sbeAlarmsMask)
354             copyVal |= 0x80;        /* if alarm turn yel LED on */
355         if (copyVal & 0x10)
356             LEDval |= 0x100;        /* tag if LED values have changed  */
357         LEDval |= ((copyVal & 0xc0) >> (6 - (portnum * 2)));
358
359         ci->alarmed[portnum] &= 0xfffff000;     /* out with the old (it's fff
360                                                  * ... foo) */
361         ci->alarmed[portnum] |= (copyVal);      /* in with the new */
362
363         /*
364          * enough with the alarms and LED's, now let's check for loopback
365          * requests
366          */
367
368         if (IS_FRAME_ANY_T1 (ci->port[portnum].p.port_mode))
369         {                           /* if a T1 mode  */
370             /*
371              * begin in-band (SF) loopback code detection -- start by reading
372              * command
373              */
374             value = pci_read_32 ((u_int32_t *) &comet->ibcd_ies);       /* detect reg. */
375             value &= 0x3;           /* trim to handy bits */
376             if (value & 0x2)
377             {                       /* activate loopback (sets for deactivate
378                                      * code length) */
379                 copyVal = c4_loop_port (ci, portnum, COMET_LBCMD_READ); /* read line loopback
380                                                                          * mode */
381                 if (copyVal != COMET_MDIAG_LINELB)      /* don't do it again if
382                                                          * already in that mode */
383                     c4_loop_port (ci, portnum, COMET_MDIAG_LINELB);     /* put port in line
384                                                                          * loopback mode */
385             }
386             if (value & 0x1)
387             {                       /* deactivate loopback (sets for activate
388                                      * code length) */
389                 copyVal = c4_loop_port (ci, portnum, COMET_LBCMD_READ); /* read line loopback
390                                                                          * mode */
391                 if (copyVal != COMET_MDIAG_LBOFF)       /* don't do it again if
392                                                          * already in that mode */
393                     c4_loop_port (ci, portnum, COMET_MDIAG_LBOFF);      /* take port out of any
394                                                                          * loopback mode */
395             }
396         }
397         if (IS_FRAME_ANY_T1ESF (ci->port[portnum].p.port_mode))
398         {                           /* if a T1 ESF mode  */
399             /* begin ESF loopback code */
400             value = pci_read_32 ((u_int32_t *) &comet->t1_rboc_sts) & 0x3f;     /* read command */
401             if (value == 0x07)
402                 c4_loop_port (ci, portnum, COMET_MDIAG_LINELB); /* put port in line
403                                                                  * loopback mode */
404             if (value == 0x0a)
405                 c4_loop_port (ci, portnum, COMET_MDIAG_PAYLB);  /* put port in payload
406                                                                  * loopbk mode */
407             if ((value == 0x1c) || (value == 0x19) || (value == 0x12))
408                 c4_loop_port (ci, portnum, COMET_MDIAG_LBOFF);  /* take port out of any
409                                                                  * loopbk mode */
410             if (cxt1e1_log_level >= LOG_DEBUG)
411                 if (value != 0x3f)
412                     pr_warning("%s: BOC value = %x on Port %d\n",
413                                ci->devname, value, portnum);
414             /* end ESF loopback code */
415         }
416     }
417
418     /* if something is new, update LED's */
419     if (LEDval & 0x100)
420         pci_write_32 ((u_int32_t *) &ci->cpldbase->leds, LEDval & 0xff);
421 #endif                              /*** CONFIG_SBE_PMCC4_NCOMM ***/
422 }
423
424
425 static void
426 c4_watchdog (ci_t *ci)
427 {
428     if (drvr_state != SBE_DRVR_AVAILABLE)
429     {
430         if (cxt1e1_log_level >= LOG_MONITOR)
431             pr_info("drvr not available (%x)\n", drvr_state);
432         return;
433     }
434     ci->wdcount++;
435     checkPorts (ci);
436     ci->wd_notify = 0;
437 }
438
439
440 void
441 c4_cleanup (void)
442 {
443     ci_t       *ci, *next;
444     mpi_t      *pi;
445     int         portnum, j;
446
447     ci = c4_list;
448     while (ci)
449     {
450         next = ci->next;            /* protect <next> from upcoming <free> */
451         pci_write_32 ((u_int32_t *) &ci->cpldbase->leds, PMCC4_CPLD_LED_OFF);
452         for (portnum = 0; portnum < ci->max_port; portnum++)
453         {
454             pi = &ci->port[portnum];
455             c4_wq_port_cleanup (pi);
456             for (j = 0; j < MUSYCC_NCHANS; j++)
457             {
458                 if (pi->chan[j])
459                     kfree(pi->chan[j]);     /* free mch_t struct */
460             }
461             kfree(pi->regram_saved);
462         }
463         kfree(ci->iqd_p_saved);
464         kfree(ci);
465         ci = next;                  /* cleanup next board, if any */
466     }
467 }
468
469
470 /*
471  * This function issues a write to all comet chips and expects the same data
472  * to be returned from the subsequent read.  This determines the board build
473  * to be a 1-port, 2-port, or 4-port build.  The value returned represents a
474  * bit-mask of the found ports.  Only certain configurations are considered
475  * VALID or LEGAL builds.
476  */
477
478 int
479 c4_get_portcfg (ci_t *ci)
480 {
481     struct s_comet_reg    *comet;
482     int         portnum, mask;
483     u_int32_t   wdata, rdata;
484
485     wdata = COMET_MDIAG_LBOFF;      /* take port out of any loopback mode */
486
487     mask = 0;
488     for (portnum = 0; portnum < MUSYCC_NPORTS; portnum++)
489     {
490         comet = ci->port[portnum].cometbase;
491         pci_write_32 ((u_int32_t *) &comet->mdiag, wdata);
492         rdata = pci_read_32 ((u_int32_t *) &comet->mdiag) & COMET_MDIAG_LBMASK;
493         if (wdata == rdata)
494             mask |= 1 << portnum;
495     }
496     return mask;
497 }
498
499
500 /* nothing herein should generate interrupts */
501
502 status_t    __init
503 c4_init (ci_t *ci, u_char *func0, u_char *func1)
504 {
505     mpi_t      *pi;
506     mch_t      *ch;
507     static u_int32_t count = 0;
508     int         portnum, j;
509
510     ci->state = C_INIT;
511     ci->brdno = count++;
512     ci->intlog.this_status_new = 0;
513     atomic_set (&ci->bh_pending, 0);
514
515     ci->reg = (struct musycc_globalr *) func0;
516     ci->eeprombase = (u_int32_t *) (func1 + EEPROM_OFFSET);
517     ci->cpldbase = (c4cpld_t *) ((u_int32_t *) (func1 + ISPLD_OFFSET));
518
519     /*** PORT POINT - the following is the first access of any type to the hardware ***/
520 #ifdef CONFIG_SBE_PMCC4_NCOMM
521     /* NCOMM driver uses INTB interrupt to monitor CPLD register */
522     pci_write_32 ((u_int32_t *) &ci->reg->glcd, GCD_MAGIC);
523 #else
524     /* standard driver POLLS for INTB via CPLD register */
525     pci_write_32 ((u_int32_t *) &ci->reg->glcd, GCD_MAGIC | MUSYCC_GCD_INTB_DISABLE);
526 #endif
527
528     {
529         int         pmsk;
530
531         /* need comet addresses available for determination of hardware build */
532         for (portnum = 0; portnum < MUSYCC_NPORTS; portnum++)
533         {
534             pi = &ci->port[portnum];
535             pi->cometbase = (struct s_comet_reg *) ((u_int32_t *) (func1 + COMET_OFFSET (portnum)));
536             pi->reg = (struct musycc_globalr *) ((u_char *) ci->reg + (portnum * 0x800));
537             pi->portnum = portnum;
538             pi->p.portnum = portnum;
539             pi->openchans = 0;
540 #ifdef SBE_MAP_DEBUG
541             pr_info("Comet-%d: addr = %p\n", portnum, pi->cometbase);
542 #endif
543         }
544         pmsk = c4_get_portcfg (ci);
545         switch (pmsk)
546         {
547         case 0x1:
548             ci->max_port = 1;
549             break;
550         case 0x3:
551             ci->max_port = 2;
552             break;
553 #if 0
554         case 0x7:                   /* not built, but could be... */
555             ci->max_port = 3;
556             break;
557 #endif
558         case 0xf:
559             ci->max_port = 4;
560             break;
561         default:
562             ci->max_port = 0;
563             pr_warning("%s: illegal port configuration (%x)\n",
564                        ci->devname, pmsk);
565             return SBE_DRVR_FAIL;
566         }
567 #ifdef SBE_MAP_DEBUG
568         pr_info(">> %s: c4_get_build - pmsk %x max_port %x\n",
569                 ci->devname, pmsk, ci->max_port);
570 #endif
571     }
572
573     for (portnum = 0; portnum < ci->max_port; portnum++)
574     {
575         pi = &ci->port[portnum];
576         pi->up = ci;
577         pi->sr_last = 0xffffffff;
578         pi->p.port_mode = CFG_FRAME_SF; /* T1 B8ZS, the default */
579         pi->p.portP = (CFG_CLK_PORT_EXTERNAL | CFG_LBO_LH0);    /* T1 defaults */
580
581         OS_sem_init (&pi->sr_sem_busy, SEM_AVAILABLE);
582         OS_sem_init (&pi->sr_sem_wait, SEM_TAKEN);
583
584         for (j = 0; j < 32; j++)
585         {
586             pi->fifomap[j] = -1;
587             pi->tsm[j] = 0;         /* no assignments, all available */
588         }
589
590         /* allocate channel structures for this port */
591         for (j = 0; j < MUSYCC_NCHANS; j++)
592         {
593                 ch = kzalloc(sizeof(mch_t), GFP_KERNEL | GFP_DMA);
594             if (ch)
595             {
596                 pi->chan[j] = ch;
597                 ch->state = UNASSIGNED;
598                 ch->up = pi;
599                 ch->gchan = (-1);   /* channel assignment not yet known */
600                 ch->channum = (-1); /* channel assignment not yet known */
601                 ch->p.card = ci->brdno;
602                 ch->p.port = portnum;
603                 ch->p.channum = (-1);   /* channel assignment not yet known */
604                 ch->p.mode_56k = 0; /* default is 64kbps mode */
605             } else
606             {
607                 pr_warning("failed mch_t malloc, port %d channel %d size %u.\n",
608                            portnum, j, (unsigned int) sizeof (mch_t));
609                 break;
610             }
611         }
612     }
613
614
615     {
616         /*
617          * Set LEDs through their paces to supply visual proof that LEDs are
618          * functional and not burnt out nor broken.
619          *
620          * YELLOW + GREEN -> OFF.
621          */
622
623         pci_write_32 ((u_int32_t *) &ci->cpldbase->leds,
624                       PMCC4_CPLD_LED_GREEN | PMCC4_CPLD_LED_YELLOW);
625         OS_uwait (750000, "leds");
626         pci_write_32 ((u_int32_t *) &ci->cpldbase->leds, PMCC4_CPLD_LED_OFF);
627     }
628
629     OS_init_watchdog (&ci->wd, (void (*) (void *)) c4_watchdog, ci, WATCHDOG_TIMEOUT);
630     return SBE_DRVR_SUCCESS;
631 }
632
633
634 /* better be fully setup to handle interrupts when you call this */
635
636 status_t    __init
637 c4_init2 (ci_t *ci)
638 {
639     status_t    ret;
640
641     /* PORT POINT: this routine generates first interrupt */
642         ret = musycc_init(ci);
643         if (ret != SBE_DRVR_SUCCESS)
644                 return ret;
645
646 #if 0
647     ci->p.framing_type = FRAMING_CBP;
648     ci->p.h110enable = 1;
649 #if 0
650     ci->p.hypersize = 0;
651 #else
652     hyperdummy = 0;
653 #endif
654     ci->p.clock = 0;                /* Use internal clocking until set to
655                                      * external */
656     c4_card_set_params (ci, &ci->p);
657 #endif
658     OS_start_watchdog (&ci->wd);
659     return SBE_DRVR_SUCCESS;
660 }
661
662
663 /* This function sets the loopback mode (or clears it, as the case may be). */
664
665 int
666 c4_loop_port (ci_t *ci, int portnum, u_int8_t cmd)
667 {
668     struct s_comet_reg    *comet;
669     volatile u_int32_t loopValue;
670
671     comet = ci->port[portnum].cometbase;
672     loopValue = pci_read_32 ((u_int32_t *) &comet->mdiag) & COMET_MDIAG_LBMASK;
673
674     if (cmd & COMET_LBCMD_READ)
675         return loopValue;           /* return the read value */
676
677     if (loopValue != cmd)
678     {
679         switch (cmd)
680         {
681         case COMET_MDIAG_LINELB:
682             /* set(SF)loopback down (turn off) code length to 6 bits */
683             pci_write_32 ((u_int32_t *) &comet->ibcd_cfg, 0x05);
684             break;
685         case COMET_MDIAG_LBOFF:
686             /* set (SF) loopback up (turn on) code length to 5 bits */
687             pci_write_32 ((u_int32_t *) &comet->ibcd_cfg, 0x00);
688             break;
689         }
690
691         pci_write_32 ((u_int32_t *) &comet->mdiag, cmd);
692         if (cxt1e1_log_level >= LOG_WARN)
693             pr_info("%s: loopback mode changed to %2x from %2x on Port %d\n",
694                     ci->devname, cmd, loopValue, portnum);
695         loopValue = pci_read_32 ((u_int32_t *) &comet->mdiag) & COMET_MDIAG_LBMASK;
696         if (loopValue != cmd)
697         {
698             if (cxt1e1_log_level >= LOG_ERROR)
699                 pr_info("%s: write to loop register failed, unknown state for Port %d\n",
700                         ci->devname, portnum);
701         }
702     } else
703     {
704         if (cxt1e1_log_level >= LOG_WARN)
705             pr_info("%s: loopback already in that mode (%2x)\n",
706                     ci->devname, loopValue);
707     }
708     return 0;
709 }
710
711
712 /* c4_frame_rw: read or write the comet register specified
713  * (modifies use of port_param to non-standard use of struct)
714  * Specifically:
715  *   pp.portnum     (one guess)
716  *   pp.port_mode   offset of register
717  *   pp.portP       write (or not, i.e. read)
718  *   pp.portStatus  write value
719  * BTW:
720  *   pp.portStatus  also used to return read value
721  *   pp.portP       also used during write, to return old reg value
722  */
723
724 status_t
725 c4_frame_rw (ci_t *ci, struct sbecom_port_param *pp)
726 {
727     struct s_comet_reg    *comet;
728     volatile u_int32_t data;
729
730     if (pp->portnum >= ci->max_port)/* sanity check */
731         return -ENXIO;
732
733     comet = ci->port[pp->portnum].cometbase;
734     data = pci_read_32 ((u_int32_t *) comet + pp->port_mode) & 0xff;
735
736     if (pp->portP)
737     {                               /* control says this is a register
738                                      * _write_ */
739         if (pp->portStatus == data)
740             pr_info("%s: Port %d already that value!  Writing again anyhow.\n",
741                     ci->devname, pp->portnum);
742         pp->portP = (u_int8_t) data;
743         pci_write_32 ((u_int32_t *) comet + pp->port_mode,
744                       pp->portStatus);
745         data = pci_read_32 ((u_int32_t *) comet + pp->port_mode) & 0xff;
746     }
747     pp->portStatus = (u_int8_t) data;
748     return 0;
749 }
750
751
752 /* c4_pld_rw: read or write the pld register specified
753  * (modifies use of port_param to non-standard use of struct)
754  * Specifically:
755  *   pp.port_mode   offset of register
756  *   pp.portP       write (or not, i.e. read)
757  *   pp.portStatus  write value
758  * BTW:
759  *   pp.portStatus  also used to return read value
760  *   pp.portP       also used during write, to return old reg value
761  */
762
763 status_t
764 c4_pld_rw (ci_t *ci, struct sbecom_port_param *pp)
765 {
766     volatile u_int32_t *regaddr;
767     volatile u_int32_t data;
768     int         regnum = pp->port_mode;
769
770     regaddr = (u_int32_t *) ci->cpldbase + regnum;
771     data = pci_read_32 ((u_int32_t *) regaddr) & 0xff;
772
773     if (pp->portP)
774     {                               /* control says this is a register
775                                      * _write_ */
776         pp->portP = (u_int8_t) data;
777         pci_write_32 ((u_int32_t *) regaddr, pp->portStatus);
778         data = pci_read_32 ((u_int32_t *) regaddr) & 0xff;
779     }
780     pp->portStatus = (u_int8_t) data;
781     return 0;
782 }
783
784 /* c4_musycc_rw: read or write the musycc register specified
785  * (modifies use of port_param to non-standard use of struct)
786  * Specifically:
787  *    mcp.RWportnum   port number and write indication bit (0x80)
788  *    mcp.offset      offset of register
789  *    mcp.value       write value going in and read value returning
790  */
791
792 /* PORT POINT: TX Subchannel Map registers are write-only
793  * areas within the MUSYCC and always return FF */
794 /* PORT POINT: regram and reg structures are minorly different and <offset> ioctl
795  * settings are aligned with the <reg> struct musycc_globalr{} usage.
796  * Also, regram is separately allocated shared memory, allocated for each port.
797  * PORT POINT: access offsets of 0x6000 for Msg Cfg Desc Tbl are for 4-port MUSYCC
798  * only.  (An 8-port MUSYCC has 0x16000 offsets for accessing its upper 4 tables.)
799  */
800
801 status_t
802 c4_musycc_rw (ci_t *ci, struct c4_musycc_param *mcp)
803 {
804     mpi_t      *pi;
805     volatile u_int32_t *dph;    /* hardware implemented register */
806     u_int32_t *dpr = NULL;      /* RAM image of registers for group command
807                                  * usage */
808     int         offset = mcp->offset % 0x800;   /* group relative address
809                                                  * offset, mcp->portnum is
810                                                  * not used */
811     int         portnum, ramread = 0;
812     volatile u_int32_t data;
813
814     /*
815      * Sanity check hardware accessibility.  The 0x6000 portion handles port
816      * numbers associated with Msg Descr Tbl decoding.
817      */
818     portnum = (mcp->offset % 0x6000) / 0x800;
819     if (portnum >= ci->max_port)
820         return -ENXIO;
821     pi = &ci->port[portnum];
822     if (mcp->offset >= 0x6000)
823         offset += 0x6000;           /* put back in MsgCfgDesc address offset */
824     dph = (u_int32_t *) ((u_long) pi->reg + offset);
825
826     /* read of TX are from RAM image, since hardware returns FF */
827     dpr = (u_int32_t *) ((u_long) pi->regram + offset);
828     if (mcp->offset < 0x6000)       /* non MsgDesc Tbl accesses might require
829                                      * RAM access */
830     {
831         if (offset >= 0x200 && offset < 0x380)
832             ramread = 1;
833         if (offset >= 0x10 && offset < 0x200)
834             ramread = 1;
835     }
836     /* read register from RAM or hardware, depending... */
837     if (ramread)
838     {
839         data = *dpr;
840         //pr_info("c4_musycc_rw: RAM addr %p  read data %x (portno %x offset %x RAM ramread %x)\n", dpr, data, portnum, offset, ramread); /* RLD DEBUG */
841     } else
842     {
843         data = pci_read_32 ((u_int32_t *) dph);
844         //pr_info("c4_musycc_rw: REG addr %p  read data %x (portno %x offset %x RAM ramread %x)\n", dph, data, portnum, offset, ramread); /* RLD DEBUG */
845     }
846
847
848     if (mcp->RWportnum & 0x80)
849     {                               /* control says this is a register
850                                      * _write_ */
851         if (mcp->value == data)
852             pr_info("%s: musycc grp%d already that value! writing again anyhow.\n",
853                     ci->devname, (mcp->RWportnum & 0x7));
854         /* write register RAM */
855         if (ramread)
856             *dpr = mcp->value;
857         /* write hardware register */
858         pci_write_32 ((u_int32_t *) dph, mcp->value);
859     }
860     mcp->value = data;              /* return the read value (or the 'old
861                                      * value', if is write) */
862     return 0;
863 }
864
865 status_t
866 c4_get_port (ci_t *ci, int portnum)
867 {
868     if (portnum >= ci->max_port)    /* sanity check */
869         return -ENXIO;
870
871     SD_SEM_TAKE (&ci->sem_wdbusy, "_wd_");      /* only 1 thru here, per
872                                                  * board */
873     checkPorts (ci);
874     ci->port[portnum].p.portStatus = (u_int8_t) ci->alarmed[portnum];
875     ci->alarmed[portnum] &= 0xdf;
876     SD_SEM_GIVE (&ci->sem_wdbusy);  /* release per-board hold */
877     return 0;
878 }
879
880 status_t
881 c4_set_port (ci_t *ci, int portnum)
882 {
883     mpi_t      *pi;
884     struct sbecom_port_param *pp;
885     int         e1mode;
886     u_int8_t    clck;
887     int         i;
888
889     if (portnum >= ci->max_port)    /* sanity check */
890         return -ENXIO;
891
892     pi = &ci->port[portnum];
893     pp = &ci->port[portnum].p;
894     e1mode = IS_FRAME_ANY_E1 (pp->port_mode);
895     if (cxt1e1_log_level >= LOG_MONITOR2)
896     {
897         pr_info("%s: c4_set_port[%d]:  entered, e1mode = %x, openchans %d.\n",
898                 ci->devname,
899                 portnum, e1mode, pi->openchans);
900     }
901     if (pi->openchans)
902         return -EBUSY;               /* group needs initialization only for
903                                      * first channel of a group */
904
905     {
906         status_t    ret;
907
908         ret = c4_wq_port_init(pi);
909         if (ret)       /* create/init workqueue_struct */
910                 return ret;
911     }
912
913     init_comet (ci, pi->cometbase, pp->port_mode, 1 /* clockmaster == true */ , pp->portP);
914     clck = pci_read_32 ((u_int32_t *) &ci->cpldbase->mclk) & PMCC4_CPLD_MCLK_MASK;
915     if (e1mode)
916         clck |= 1 << portnum;
917     else
918         clck &= 0xf ^ (1 << portnum);
919
920     pci_write_32 ((u_int32_t *) &ci->cpldbase->mclk, clck);
921     pci_write_32 ((u_int32_t *) &ci->cpldbase->mcsr, PMCC4_CPLD_MCSR_IND);
922     pci_write_32 ((u_int32_t *) &pi->reg->gbp, OS_vtophys (pi->regram));
923
924     /*********************************************************************/
925     /* ERRATA: If transparent mode is used, do not set OOFMP_DISABLE bit */
926     /*********************************************************************/
927
928     pi->regram->grcd =
929         __constant_cpu_to_le32 (MUSYCC_GRCD_RX_ENABLE |
930                                 MUSYCC_GRCD_TX_ENABLE |
931                                 MUSYCC_GRCD_OOFMP_DISABLE |
932                                 MUSYCC_GRCD_SF_ALIGN |  /* per MUSYCC ERRATA,
933                                                          * for T1 * fix */
934                                 MUSYCC_GRCD_COFAIRQ_DISABLE |
935                                 MUSYCC_GRCD_MC_ENABLE |
936                        (MUSYCC_GRCD_POLLTH_32 << MUSYCC_GRCD_POLLTH_SHIFT));
937
938     pi->regram->pcd =
939         __constant_cpu_to_le32 ((e1mode ? 1 : 0) |
940                                 MUSYCC_PCD_TXSYNC_RISING |
941                                 MUSYCC_PCD_RXSYNC_RISING |
942                                 MUSYCC_PCD_RXDATA_RISING);
943
944     /* Message length descriptor */
945        pi->regram->mld = __constant_cpu_to_le32 (cxt1e1_max_mru | (cxt1e1_max_mru << 16));
946
947     /* tsm algorithm */
948     for (i = 0; i < 32; i++)
949     {
950
951         /*** ASSIGNMENT NOTES:                             ***/
952         /*** Group's channel  ZERO  unavailable if E1.     ***/
953         /*** Group's channel  16    unavailable if E1 CAS. ***/
954         /*** Group's channels 24-31 unavailable if T1.     ***/
955
956         if (((i == 0) && e1mode) ||
957             ((i == 16) && ((pp->port_mode == CFG_FRAME_E1CRC_CAS) || (pp->port_mode == CFG_FRAME_E1CRC_CAS_AMI)))
958             || ((i > 23) && (!e1mode)))
959         {
960             pi->tsm[i] = 0xff;      /* make tslot unavailable for this mode */
961         } else
962         {
963             pi->tsm[i] = 0x00;      /* make tslot available for assignment */
964         }
965     }
966     for (i = 0; i < MUSYCC_NCHANS; i++)
967     {
968         pi->regram->ttsm[i] = 0;
969         pi->regram->rtsm[i] = 0;
970     }
971     FLUSH_MEM_WRITE ();
972     musycc_serv_req (pi, SR_GROUP_INIT | SR_RX_DIRECTION);
973     musycc_serv_req (pi, SR_GROUP_INIT | SR_TX_DIRECTION);
974
975     musycc_init_mdt (pi);
976
977     pi->group_is_set = 1;
978     pi->p = *pp;
979     return 0;
980 }
981
982
983 unsigned int max_int = 0;
984
985 status_t
986 c4_new_chan (ci_t *ci, int portnum, int channum, void *user)
987 {
988     mpi_t      *pi;
989     mch_t      *ch;
990     int         gchan;
991
992     if (c4_find_chan (channum))     /* a new channel shouldn't already exist */
993         return -EEXIST;
994
995     if (portnum >= ci->max_port)    /* sanity check */
996         return -ENXIO;
997
998     pi = &(ci->port[portnum]);
999     /* find any available channel within this port */
1000     for (gchan = 0; gchan < MUSYCC_NCHANS; gchan++)
1001     {
1002         ch = pi->chan[gchan];
1003         if (ch && ch->state == UNASSIGNED)      /* no assignment is good! */
1004             break;
1005     }
1006     if (gchan == MUSYCC_NCHANS)     /* exhausted table, all were assigned */
1007         return -ENFILE;
1008
1009     ch->up = pi;
1010
1011     /* NOTE: mch_t already cleared during OS_kmalloc() */
1012     ch->state = DOWN;
1013     ch->user = user;
1014     ch->gchan = gchan;
1015     ch->channum = channum;          /* mark our channel assignment */
1016     ch->p.channum = channum;
1017 #if 1
1018     ch->p.card = ci->brdno;
1019     ch->p.port = portnum;
1020 #endif
1021     ch->p.chan_mode = CFG_CH_PROTO_HDLC_FCS16;
1022     ch->p.idlecode = CFG_CH_FLAG_7E;
1023     ch->p.pad_fill_count = 2;
1024     spin_lock_init (&ch->ch_rxlock);
1025     spin_lock_init (&ch->ch_txlock);
1026
1027     {
1028         status_t    ret;
1029
1030         ret = c4_wk_chan_init(pi, ch);
1031         if (ret)
1032                 return ret;
1033     }
1034
1035     /* save off interface assignments which bound a board */
1036     if (!ci->first_if)          /* first channel registered is assumed to
1037                                      * be the lowest channel */
1038     {
1039         ci->first_if = ci->last_if = user;
1040         ci->first_channum = ci->last_channum = channum;
1041     } else
1042     {
1043         ci->last_if = user;
1044         if (ci->last_channum < channum) /* higher number channel found */
1045             ci->last_channum = channum;
1046     }
1047     return 0;
1048 }
1049
1050 status_t
1051 c4_del_chan (int channum)
1052 {
1053     mch_t      *ch;
1054
1055         ch = c4_find_chan(channum);
1056         if (!ch)
1057                 return -ENOENT;
1058
1059     if (ch->state == UP)
1060         musycc_chan_down ((ci_t *) 0, channum);
1061     ch->state = UNASSIGNED;
1062     ch->gchan = (-1);
1063     ch->channum = (-1);
1064     ch->p.channum = (-1);
1065     return 0;
1066 }
1067
1068 status_t
1069 c4_del_chan_stats (int channum)
1070 {
1071     mch_t      *ch;
1072
1073         ch = c4_find_chan(channum);
1074         if (!ch)
1075                 return -ENOENT;
1076
1077     memset (&ch->s, 0, sizeof (struct sbecom_chan_stats));
1078     return 0;
1079 }
1080
1081
1082 status_t
1083 c4_set_chan (int channum, struct sbecom_chan_param *p)
1084 {
1085     mch_t      *ch;
1086     int         i, x = 0;
1087
1088         ch = c4_find_chan(channum);
1089         if (!ch)
1090                 return -ENOENT;
1091
1092 #if 1
1093     if (ch->p.card != p->card ||
1094         ch->p.port != p->port ||
1095         ch->p.channum != p->channum)
1096         return -EINVAL;
1097 #endif
1098
1099     if (!(ch->up->group_is_set))
1100     {
1101         return -EIO;                 /* out of order, SET_PORT command
1102                                      * required prior to first group's
1103                                      * SET_CHAN command */
1104     }
1105     /*
1106      * Check for change of parameter settings in order to invoke closing of
1107      * channel prior to hardware poking.
1108      */
1109
1110     if (ch->p.status != p->status || ch->p.chan_mode != p->chan_mode ||
1111         ch->p.data_inv != p->data_inv || ch->p.intr_mask != p->intr_mask ||
1112         ch->txd_free < ch->txd_num) /* to clear out queued messages */
1113         x = 1;                      /* we have a change requested */
1114     for (i = 0; i < 32; i++)        /* check for timeslot mapping changes */
1115         if (ch->p.bitmask[i] != p->bitmask[i])
1116             x = 1;                  /* we have a change requested */
1117     ch->p = *p;
1118     if (x && (ch->state == UP))     /* if change request and channel is
1119                                      * open... */
1120     {
1121         status_t    ret;
1122
1123         ret = musycc_chan_down((ci_t *)0, channum);
1124         if (ret)
1125                 return ret;
1126         ret = c4_chan_up(ch->up->up, channum);
1127         if (ret)
1128                 return ret;
1129         sd_enable_xmit (ch->user);  /* re-enable to catch flow controlled
1130                                      * channel */
1131     }
1132     return 0;
1133 }
1134
1135
1136 status_t
1137 c4_get_chan (int channum, struct sbecom_chan_param *p)
1138 {
1139     mch_t      *ch;
1140
1141         ch = c4_find_chan(channum);
1142         if (!ch)
1143                 return -ENOENT;
1144
1145     *p = ch->p;
1146     return 0;
1147 }
1148
1149 status_t
1150 c4_get_chan_stats (int channum, struct sbecom_chan_stats *p)
1151 {
1152     mch_t      *ch;
1153
1154         ch = c4_find_chan(channum);
1155         if (!ch)
1156                 return -ENOENT;
1157
1158     *p = ch->s;
1159     p->tx_pending = atomic_read (&ch->tx_pending);
1160     return 0;
1161 }
1162
1163 static int
1164 c4_fifo_alloc (mpi_t *pi, int chan, int *len)
1165 {
1166     int         i, l = 0, start = 0, max = 0, maxstart = 0;
1167
1168     for (i = 0; i < 32; i++)
1169     {
1170         if (pi->fifomap[i] != -1)
1171         {
1172             l = 0;
1173             start = i + 1;
1174             continue;
1175         }
1176         ++l;
1177         if (l > max)
1178         {
1179             max = l;
1180             maxstart = start;
1181         }
1182         if (max == *len)
1183             break;
1184     }
1185     if (max != *len)
1186     {
1187         if (cxt1e1_log_level >= LOG_WARN)
1188             pr_info("%s: wanted to allocate %d fifo space, but got only %d\n",
1189                     pi->up->devname, *len, max);
1190         *len = max;
1191     }
1192     if (cxt1e1_log_level >= LOG_DEBUG)
1193         pr_info("%s: allocated %d fifo at %d for channel %d/%d\n",
1194                 pi->up->devname, max, start, chan, pi->p.portnum);
1195     for (i = maxstart; i < (maxstart + max); i++)
1196         pi->fifomap[i] = chan;
1197     return start;
1198 }
1199
1200 void
1201 c4_fifo_free (mpi_t *pi, int chan)
1202 {
1203     int         i;
1204
1205     if (cxt1e1_log_level >= LOG_DEBUG)
1206         pr_info("%s: deallocated fifo for channel %d/%d\n",
1207                 pi->up->devname, chan, pi->p.portnum);
1208     for (i = 0; i < 32; i++)
1209         if (pi->fifomap[i] == chan)
1210             pi->fifomap[i] = -1;
1211 }
1212
1213
1214 status_t
1215 c4_chan_up (ci_t *ci, int channum)
1216 {
1217     mpi_t      *pi;
1218     mch_t      *ch;
1219     struct mbuf *m;
1220     struct mdesc *md;
1221     int         nts, nbuf, txnum, rxnum;
1222     int         addr, i, j, gchan;
1223     u_int32_t   tmp;            /* for optimizing conversion across BE
1224                                  * platform */
1225
1226         ch = c4_find_chan(channum);
1227         if (!ch)
1228                 return -ENOENT;
1229
1230     if (ch->state == UP)
1231     {
1232         if (cxt1e1_log_level >= LOG_MONITOR)
1233             pr_info("%s: channel already UP, graceful early exit\n",
1234                     ci->devname);
1235         return 0;
1236     }
1237     pi = ch->up;
1238     gchan = ch->gchan;
1239     /* find nts ('number of timeslots') */
1240     nts = 0;
1241     for (i = 0; i < 32; i++)
1242     {
1243         if (ch->p.bitmask[i] & pi->tsm[i])
1244         {
1245             if (1 || cxt1e1_log_level >= LOG_WARN)
1246             {
1247                 pr_info("%s: c4_chan_up[%d] EINVAL (attempt to cfg in-use or unavailable TimeSlot[%d])\n",
1248                         ci->devname, channum, i);
1249                 pr_info("+ ask4 %x, currently %x\n",
1250                         ch->p.bitmask[i], pi->tsm[i]);
1251             }
1252             return -EINVAL;
1253         }
1254         for (j = 0; j < 8; j++)
1255             if (ch->p.bitmask[i] & (1 << j))
1256                 nts++;
1257     }
1258
1259     nbuf = nts / 8 ? nts / 8 : 1;
1260     if (!nbuf)
1261     {
1262         /* if( cxt1e1_log_level >= LOG_WARN)  */
1263         pr_info("%s: c4_chan_up[%d] ENOBUFS (no TimeSlots assigned)\n",
1264                 ci->devname, channum);
1265         return -ENOBUFS;             /* this should not happen */
1266     }
1267     addr = c4_fifo_alloc (pi, gchan, &nbuf);
1268     ch->state = UP;
1269
1270     /* Setup the Time Slot Map */
1271     musycc_update_timeslots (pi);
1272
1273     /* ch->tx_limit = nts; */
1274     ch->s.tx_pending = 0;
1275
1276     /* Set Channel Configuration Descriptors */
1277     {
1278         u_int32_t   ccd;
1279
1280         ccd = musycc_chan_proto (ch->p.chan_mode) << MUSYCC_CCD_PROTO_SHIFT;
1281         if ((ch->p.chan_mode == CFG_CH_PROTO_ISLP_MODE) ||
1282             (ch->p.chan_mode == CFG_CH_PROTO_TRANS))
1283         {
1284             ccd |= MUSYCC_CCD_FCS_XFER; /* Non FSC Mode */
1285         }
1286         ccd |= 2 << MUSYCC_CCD_MAX_LENGTH;      /* Select second MTU */
1287         ccd |= ch->p.intr_mask;
1288         ccd |= addr << MUSYCC_CCD_BUFFER_LOC;
1289         if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
1290             ccd |= (nbuf) << MUSYCC_CCD_BUFFER_LENGTH;
1291         else
1292             ccd |= (nbuf - 1) << MUSYCC_CCD_BUFFER_LENGTH;
1293
1294         if (ch->p.data_inv & CFG_CH_DINV_TX)
1295             ccd |= MUSYCC_CCD_INVERT_DATA;      /* Invert data */
1296         pi->regram->tcct[gchan] = cpu_to_le32 (ccd);
1297
1298         if (ch->p.data_inv & CFG_CH_DINV_RX)
1299             ccd |= MUSYCC_CCD_INVERT_DATA;      /* Invert data */
1300         else
1301             ccd &= ~MUSYCC_CCD_INVERT_DATA;     /* take away data inversion */
1302         pi->regram->rcct[gchan] = cpu_to_le32 (ccd);
1303         FLUSH_MEM_WRITE ();
1304     }
1305
1306     /* Reread the Channel Configuration Descriptor for this channel */
1307     musycc_serv_req (pi, SR_CHANNEL_CONFIG | SR_RX_DIRECTION | gchan);
1308     musycc_serv_req (pi, SR_CHANNEL_CONFIG | SR_TX_DIRECTION | gchan);
1309
1310     /*
1311      * Figure out how many buffers we want.  If the customer has changed from
1312      * the defaults, then use the changed values.  Otherwise, use Transparent
1313      * mode's specific minimum default settings.
1314      */
1315     if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
1316     {
1317         if (max_rxdesc_used == max_rxdesc_default)      /* use default setting */
1318             max_rxdesc_used = MUSYCC_RXDESC_TRANS;
1319         if (max_txdesc_used == max_txdesc_default)      /* use default setting */
1320             max_txdesc_used = MUSYCC_TXDESC_TRANS;
1321     }
1322     /*
1323      * Increase counts when hyperchanneling, since this implies an increase
1324      * in throughput per channel
1325      */
1326     rxnum = max_rxdesc_used + (nts / 4);
1327     txnum = max_txdesc_used + (nts / 4);
1328
1329 #if 0
1330     /* DEBUG INFO */
1331     if (cxt1e1_log_level >= LOG_MONITOR)
1332         pr_info("%s: mode %x rxnum %d (rxused %d def %d) txnum %d (txused %d def %d)\n",
1333                 ci->devname, ch->p.chan_mode,
1334                 rxnum, max_rxdesc_used, max_rxdesc_default,
1335                 txnum, max_txdesc_used, max_txdesc_default);
1336 #endif
1337
1338     ch->rxd_num = rxnum;
1339     ch->txd_num = txnum;
1340     ch->rxix_irq_srv = 0;
1341
1342         ch->mdr = kzalloc(sizeof(struct mdesc) * rxnum, GFP_KERNEL | GFP_DMA);
1343         ch->mdt = kzalloc(sizeof(struct mdesc) * txnum, GFP_KERNEL | GFP_DMA);
1344     if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
1345                tmp = __constant_cpu_to_le32 (cxt1e1_max_mru | EOBIRQ_ENABLE);
1346     else
1347                tmp = __constant_cpu_to_le32 (cxt1e1_max_mru);
1348
1349     for (i = 0, md = ch->mdr; i < rxnum; i++, md++)
1350     {
1351         if (i == (rxnum - 1))
1352         {
1353             md->snext = &ch->mdr[0];/* wrapness */
1354         } else
1355         {
1356             md->snext = &ch->mdr[i + 1];
1357         }
1358         md->next = cpu_to_le32 (OS_vtophys (md->snext));
1359
1360         m = OS_mem_token_alloc(cxt1e1_max_mru);
1361         if (!m) {
1362                 if (cxt1e1_log_level >= LOG_MONITOR)
1363                         pr_info(
1364                         "%s: c4_chan_up[%d] - token alloc failure, size = %d.\n",
1365                         ci->devname, channum, cxt1e1_max_mru);
1366                 goto errfree;
1367         }
1368         md->mem_token = m;
1369         md->data = cpu_to_le32 (OS_vtophys (OS_mem_token_data (m)));
1370         md->status = tmp | MUSYCC_RX_OWNED;     /* MUSYCC owns RX descriptor **
1371                                                  * CODING NOTE:
1372                                                  * MUSYCC_RX_OWNED = 0 so no
1373                                                  * need to byteSwap */
1374     }
1375
1376     for (i = 0, md = ch->mdt; i < txnum; i++, md++)
1377     {
1378         md->status = HOST_TX_OWNED; /* Host owns TX descriptor ** CODING
1379                                      * NOTE: HOST_TX_OWNED = 0 so no need to
1380                                      * byteSwap */
1381         md->mem_token = NULL;
1382         md->data = 0;
1383         if (i == (txnum - 1))
1384         {
1385             md->snext = &ch->mdt[0];/* wrapness */
1386         } else
1387         {
1388             md->snext = &ch->mdt[i + 1];
1389         }
1390         md->next = cpu_to_le32 (OS_vtophys (md->snext));
1391     }
1392     ch->txd_irq_srv = ch->txd_usr_add = &ch->mdt[0];
1393     ch->txd_free = txnum;
1394     ch->tx_full = 0;
1395     ch->txd_required = 0;
1396
1397     /* Configure it into the chip */
1398     tmp = cpu_to_le32 (OS_vtophys (&ch->mdt[0]));
1399     pi->regram->thp[gchan] = tmp;
1400     pi->regram->tmp[gchan] = tmp;
1401
1402     tmp = cpu_to_le32 (OS_vtophys (&ch->mdr[0]));
1403     pi->regram->rhp[gchan] = tmp;
1404     pi->regram->rmp[gchan] = tmp;
1405
1406     /* Activate the Channel */
1407     FLUSH_MEM_WRITE ();
1408     if (ch->p.status & RX_ENABLED)
1409     {
1410 #ifdef RLD_TRANS_DEBUG
1411         pr_info("++ c4_chan_up() CHAN RX ACTIVATE: chan %d\n", ch->channum);
1412 #endif
1413         ch->ch_start_rx = 0;        /* we are restarting RX... */
1414         musycc_serv_req (pi, SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION | gchan);
1415     }
1416     if (ch->p.status & TX_ENABLED)
1417     {
1418 #ifdef RLD_TRANS_DEBUG
1419         pr_info("++ c4_chan_up() CHAN TX ACTIVATE: chan %d <delayed>\n", ch->channum);
1420 #endif
1421         ch->ch_start_tx = CH_START_TX_1ST;      /* we are delaying start
1422                                                  * until receipt from user of
1423                                                  * first packet to transmit. */
1424     }
1425     ch->status = ch->p.status;
1426     pi->openchans++;
1427     return 0;
1428
1429 errfree:
1430     while (i > 0)
1431     {
1432         /* Don't leak all the previously allocated mbufs in this loop */
1433         i--;
1434         OS_mem_token_free (ch->mdr[i].mem_token);
1435     }
1436     kfree(ch->mdt);
1437     ch->mdt = NULL;
1438     ch->txd_num = 0;
1439     kfree(ch->mdr);
1440     ch->mdr = NULL;
1441     ch->rxd_num = 0;
1442     ch->state = DOWN;
1443     return -ENOBUFS;
1444 }
1445
1446 /* stop the hardware from servicing & interrupting */
1447
1448 void
1449 c4_stopwd (ci_t *ci)
1450 {
1451     OS_stop_watchdog (&ci->wd);
1452     SD_SEM_TAKE (&ci->sem_wdbusy, "_stop_");    /* ensure WD not running */
1453     SD_SEM_GIVE (&ci->sem_wdbusy);
1454 }
1455
1456
1457 void
1458 sbecom_get_brdinfo (ci_t *ci, struct sbe_brd_info *bip, u_int8_t *bsn)
1459 {
1460     char       *np;
1461     u_int32_t   sn = 0;
1462     int         i;
1463
1464     bip->brdno = ci->brdno;         /* our board number */
1465     bip->brd_id = ci->brd_id;
1466     bip->brd_hdw_id = ci->hdw_bid;
1467     bip->brd_chan_cnt = MUSYCC_NCHANS *ci->max_port;   /* number of channels
1468                                                          * being used */
1469     bip->brd_port_cnt = ci->max_port;   /* number of ports being used */
1470     bip->brd_pci_speed = BINFO_PCI_SPEED_unk;   /* PCI speed not yet
1471                                                  * determinable */
1472
1473     if (ci->first_if)
1474     {
1475         {
1476             struct net_device *dev;
1477
1478             dev = (struct net_device *) ci->first_if;
1479             np = (char *) dev->name;
1480         }
1481         strncpy (bip->first_iname, np, CHNM_STRLEN - 1);
1482     } else
1483         strcpy (bip->first_iname, "<NULL>");
1484     if (ci->last_if)
1485     {
1486         {
1487             struct net_device *dev;
1488
1489             dev = (struct net_device *) ci->last_if;
1490             np = (char *) dev->name;
1491         }
1492         strncpy (bip->last_iname, np, CHNM_STRLEN - 1);
1493     } else
1494         strcpy (bip->last_iname, "<NULL>");
1495
1496     if (bsn)
1497     {
1498         for (i = 0; i < 3; i++)
1499         {
1500             bip->brd_mac_addr[i] = *bsn++;
1501         }
1502         for (; i < 6; i++)
1503         {
1504             bip->brd_mac_addr[i] = *bsn;
1505             sn = (sn << 8) | *bsn++;
1506         }
1507     } else
1508     {
1509         for (i = 0; i < 6; i++)
1510             bip->brd_mac_addr[i] = 0;
1511     }
1512     bip->brd_sn = sn;
1513 }
1514
1515
1516 status_t
1517 c4_get_iidinfo (ci_t *ci, struct sbe_iid_info *iip)
1518 {
1519     struct net_device *dev;
1520     char       *np;
1521
1522         dev = getuserbychan(iip->channum);
1523         if (!dev)
1524                 return -ENOENT;
1525
1526     np = dev->name;
1527     strncpy (iip->iname, np, CHNM_STRLEN - 1);
1528     iip->iname[CHNM_STRLEN - 1] = '\0';
1529     return 0;
1530 }
1531
1532
1533 #ifdef CONFIG_SBE_PMCC4_NCOMM
1534 void        (*nciInterrupt[MAX_BOARDS][4]) (void);
1535 extern void wanpmcC4T1E1_hookInterrupt (int cardID, int deviceID, void *handler);
1536
1537 void
1538 wanpmcC4T1E1_hookInterrupt (int cardID, int deviceID, void *handler)
1539 {
1540     if (cardID < MAX_BOARDS)    /* sanity check */
1541         nciInterrupt[cardID][deviceID] = handler;
1542 }
1543
1544 irqreturn_t
1545 c4_ebus_intr_th_handler (void *devp)
1546 {
1547     ci_t       *ci = (ci_t *) devp;
1548     volatile u_int32_t ists;
1549     int         handled = 0;
1550     int         brdno;
1551
1552     /* which COMET caused the interrupt */
1553     brdno = ci->brdno;
1554     ists = pci_read_32 ((u_int32_t *) &ci->cpldbase->intr);
1555     if (ists & PMCC4_CPLD_INTR_CMT_1)
1556     {
1557         handled = 0x1;
1558         if (nciInterrupt[brdno][0] != NULL)
1559             (*nciInterrupt[brdno][0]) ();
1560     }
1561     if (ists & PMCC4_CPLD_INTR_CMT_2)
1562     {
1563         handled |= 0x2;
1564         if (nciInterrupt[brdno][1] != NULL)
1565             (*nciInterrupt[brdno][1]) ();
1566     }
1567     if (ists & PMCC4_CPLD_INTR_CMT_3)
1568     {
1569         handled |= 0x4;
1570         if (nciInterrupt[brdno][2] != NULL)
1571             (*nciInterrupt[brdno][2]) ();
1572     }
1573     if (ists & PMCC4_CPLD_INTR_CMT_4)
1574     {
1575         handled |= 0x8;
1576         if (nciInterrupt[brdno][3] != NULL)
1577             (*nciInterrupt[brdno][3]) ();
1578     }
1579 #if 0
1580     /*** Test code just de-implements the asserted interrupt.  Alternate
1581     vendor will supply COMET interrupt handling code herein or such.
1582     ***/
1583     pci_write_32 ((u_int32_t *) &ci->reg->glcd, GCD_MAGIC | MUSYCC_GCD_INTB_DISABLE);
1584 #endif
1585
1586     return IRQ_RETVAL (handled);
1587 }
1588
1589
1590 unsigned long
1591 wanpmcC4T1E1_getBaseAddress (int cardID, int deviceID)
1592 {
1593     ci_t       *ci;
1594     unsigned long base = 0;
1595
1596     ci = c4_list;
1597     while (ci)
1598     {
1599         if (ci->brdno == cardID)    /* found valid device */
1600         {
1601             if (deviceID < ci->max_port)        /* comet is supported */
1602                 base = ((unsigned long) ci->port[deviceID].cometbase);
1603             break;
1604         }
1605         ci = ci->next;              /* next board, if any */
1606     }
1607     return base;
1608 }
1609
1610 #endif                          /*** CONFIG_SBE_PMCC4_NCOMM ***/
1611
1612
1613 /***  End-of-File  ***/