Release 4.11 drivers/atm/iphase.c
/******************************************************************************
iphase.c: Device driver for Interphase ATM PCI adapter cards
Author: Peter Wang <pwang@iphase.com>
Some fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
Interphase Corporation <www.iphase.com>
Version: 1.0
*******************************************************************************
This software may be used and distributed according to the terms
of the GNU General Public License (GPL), incorporated herein by reference.
Drivers based on this skeleton fall under the GPL and must retain
the authorship (implicit copyright) notice.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Modified from an incomplete driver for Interphase 5575 1KVC 1M card which
was originally written by Monalisa Agrawal at UNH. Now this driver
supports a variety of varients of Interphase ATM PCI (i)Chip adapter
card family (See www.iphase.com/products/ClassSheet.cfm?ClassID=ATM)
in terms of PHY type, the size of control memory and the size of
packet memory. The following are the change log and history:
Bugfix the Mona's UBR driver.
Modify the basic memory allocation and dma logic.
Port the driver to the latest kernel from 2.0.46.
Complete the ABR logic of the driver, and added the ABR work-
around for the hardware anormalies.
Add the CBR support.
Add the flow control logic to the driver to allow rate-limit VC.
Add 4K VC support to the board with 512K control memory.
Add the support of all the variants of the Interphase ATM PCI
(i)Chip adapter cards including x575 (155M OC3 and UTP155), x525
(25M UTP25) and x531 (DS3 and E3).
Add SMP support.
Support and updates available at: ftp://ftp.iphase.com/pub/atm
*******************************************************************************/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/errno.h>
#include <linux/atm.h>
#include <linux/atmdev.h>
#include <linux/sonet.h>
#include <linux/skbuff.h>
#include <linux/time.h>
#include <linux/delay.h>
#include <linux/uio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <linux/atomic.h>
#include <linux/uaccess.h>
#include <asm/string.h>
#include <asm/byteorder.h>
#include <linux/vmalloc.h>
#include <linux/jiffies.h>
#include "iphase.h"
#include "suni.h"
#define swap_byte_order(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8))
#define PRIV(dev) ((struct suni_priv *) dev->phy_data)
static unsigned char ia_phy_get(struct atm_dev *dev, unsigned long addr);
static void desc_dbg(IADEV *iadev);
static IADEV *ia_dev[8];
static struct atm_dev *_ia_dev[8];
static int iadev_count;
static void ia_led_timer(unsigned long arg);
static DEFINE_TIMER(ia_timer, ia_led_timer, 0, 0);
static int IA_TX_BUF = DFL_TX_BUFFERS, IA_TX_BUF_SZ = DFL_TX_BUF_SZ;
static int IA_RX_BUF = DFL_RX_BUFFERS, IA_RX_BUF_SZ = DFL_RX_BUF_SZ;
static uint IADebugFlag = /* IF_IADBG_ERR | IF_IADBG_CBR| IF_IADBG_INIT_ADAPTER
|IF_IADBG_ABR | IF_IADBG_EVENT*/ 0;
module_param(IA_TX_BUF, int, 0);
module_param(IA_TX_BUF_SZ, int, 0);
module_param(IA_RX_BUF, int, 0);
module_param(IA_RX_BUF_SZ, int, 0);
module_param(IADebugFlag, uint, 0644);
MODULE_LICENSE("GPL");
/**************************** IA_LIB **********************************/
static void ia_init_rtn_q (IARTN_Q *que)
{
que->next = NULL;
que->tail = NULL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 22 | 100.00% | 1 | 100.00% |
Total | 22 | 100.00% | 1 | 100.00% |
static void ia_enque_head_rtn_q (IARTN_Q *que, IARTN_Q * data)
{
data->next = NULL;
if (que->next == NULL)
que->next = que->tail = data;
else {
data->next = que->next;
que->next = data;
}
return;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 56 | 100.00% | 1 | 100.00% |
Total | 56 | 100.00% | 1 | 100.00% |
static int ia_enque_rtn_q (IARTN_Q *que, struct desc_tbl_t data) {
IARTN_Q *entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
if (!entry)
return -ENOMEM;
entry->data = data;
entry->next = NULL;
if (que->next == NULL)
que->next = que->tail = entry;
else {
que->tail->next = entry;
que->tail = que->tail->next;
}
return 1;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 86 | 93.48% | 1 | 25.00% |
Linus Torvalds | 4 | 4.35% | 1 | 25.00% |
Alan Cox | 1 | 1.09% | 1 | 25.00% |
Tillmann Heidsieck | 1 | 1.09% | 1 | 25.00% |
Total | 92 | 100.00% | 4 | 100.00% |
static IARTN_Q * ia_deque_rtn_q (IARTN_Q *que) {
IARTN_Q *tmpdata;
if (que->next == NULL)
return NULL;
tmpdata = que->next;
if ( que->next == que->tail)
que->next = que->tail = NULL;
else
que->next = que->next->next;
return tmpdata;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 66 | 100.00% | 1 | 100.00% |
Total | 66 | 100.00% | 1 | 100.00% |
static void ia_hack_tcq(IADEV *dev) {
u_short desc1;
u_short tcq_wr;
struct ia_vcc *iavcc_r = NULL;
tcq_wr = readl(dev->seg_reg+TCQ_WR_PTR) & 0xffff;
while (dev->host_tcq_wr != tcq_wr) {
desc1 = *(u_short *)(dev->seg_ram + dev->host_tcq_wr);
if (!desc1) ;
else if (!dev->desc_tbl[desc1 -1].timestamp) {
IF_ABR(printk(" Desc %d is reset at %ld\n", desc1 -1, jiffies);)
*(u_short *) (dev->seg_ram + dev->host_tcq_wr) = 0;
}
else if (dev->desc_tbl[desc1 -1].timestamp) {
if (!(iavcc_r = dev->desc_tbl[desc1 -1].iavcc)) {
printk("IA: Fatal err in get_desc\n");
continue;
}
iavcc_r->vc_desc_cnt--;
dev->desc_tbl[desc1 -1].timestamp = 0;
IF_EVENT(printk("ia_hack: return_q skb = 0x%p desc = %d\n",
dev->desc_tbl[desc1 -1].txskb, desc1);)
if (iavcc_r->pcr < dev->rate_limit) {
IA_SKB_STATE (dev->desc_tbl[desc1-1].txskb) |= IA_TX_DONE;
if (ia_enque_rtn_q(&dev->tx_return_q, dev->desc_tbl[desc1 -1]) < 0)
printk("ia_hack_tcq: No memory available\n");
}
dev->desc_tbl[desc1 -1].iavcc = NULL;
dev->desc_tbl[desc1 -1].txskb = NULL;
}
dev->host_tcq_wr += 2;
if (dev->host_tcq_wr > dev->ffL.tcq_ed)
dev->host_tcq_wr = dev->ffL.tcq_st;
}
} Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 285 | 99.30% | 1 | 50.00% |
David Howells | 2 | 0.70% | 1 | 50.00% |
Total | 287 | 100.00% | 2 | 100.00% |
/* ia_hack_tcq */
static u16 get_desc (IADEV *dev, struct ia_vcc *iavcc) {
u_short desc_num, i;
struct sk_buff *skb;
struct ia_vcc *iavcc_r = NULL;
unsigned long delta;
static unsigned long timer = 0;
int ltimeout;
ia_hack_tcq (dev);
if((time_after(jiffies,timer+50)) || ((dev->ffL.tcq_rd==dev->host_tcq_wr))) {
timer = jiffies;
i=0;
while (i < dev->num_tx_desc) {
if (!dev->desc_tbl[i].timestamp) {
i++;
continue;
}
ltimeout = dev->desc_tbl[i].iavcc->ltimeout;
delta = jiffies - dev->desc_tbl[i].timestamp;
if (delta >= ltimeout) {
IF_ABR(printk("RECOVER run!! desc_tbl %d = %d delta = %ld, time = %ld\n", i,dev->desc_tbl[i].timestamp, delta, jiffies);)
if (dev->ffL.tcq_rd == dev->ffL.tcq_st)
dev->ffL.tcq_rd = dev->ffL.tcq_ed;
else
dev->ffL.tcq_rd -= 2;
*(u_short *)(dev->seg_ram + dev->ffL.tcq_rd) = i+1;
if (!(skb = dev->desc_tbl[i].txskb) ||
!(iavcc_r = dev->desc_tbl[i].iavcc))
printk("Fatal err, desc table vcc or skb is NULL\n");
else
iavcc_r->vc_desc_cnt--;
dev->desc_tbl[i].timestamp = 0;
dev->desc_tbl[i].iavcc = NULL;
dev->desc_tbl[i].txskb = NULL;
}
i++;
} /* while */
}
if (dev->ffL.tcq_rd == dev->host_tcq_wr)
return 0xFFFF;
/* Get the next available descriptor number from TCQ */
desc_num = *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd);
while (!desc_num || (dev->desc_tbl[desc_num -1]).timestamp) {
dev->ffL.tcq_rd += 2;
if (dev->ffL.tcq_rd > dev->ffL.tcq_ed)
dev->ffL.tcq_rd = dev->ffL.tcq_st;
if (dev->ffL.tcq_rd == dev->host_tcq_wr)
return 0xFFFF;
desc_num = *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd);
}
/* get system time */
dev->desc_tbl[desc_num -1].timestamp = jiffies;
return desc_num;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 424 | 98.60% | 1 | 33.33% |
Julia Lawall | 5 | 1.16% | 1 | 33.33% |
Alan Cox | 1 | 0.23% | 1 | 33.33% |
Total | 430 | 100.00% | 3 | 100.00% |
static void clear_lockup (struct atm_vcc *vcc, IADEV *dev) {
u_char foundLockUp;
vcstatus_t *vcstatus;
u_short *shd_tbl;
u_short tempCellSlot, tempFract;
struct main_vc *abr_vc = (struct main_vc *)dev->MAIN_VC_TABLE_ADDR;
struct ext_vc *eabr_vc = (struct ext_vc *)dev->EXT_VC_TABLE_ADDR;
u_int i;
if (vcc->qos.txtp.traffic_class == ATM_ABR) {
vcstatus = (vcstatus_t *) &(dev->testTable[vcc->vci]->vc_status);
vcstatus->cnt++;
foundLockUp = 0;
if( vcstatus->cnt == 0x05 ) {
abr_vc += vcc->vci;
eabr_vc += vcc->vci;
if( eabr_vc->last_desc ) {
if( (abr_vc->status & 0x07) == ABR_STATE /* 0x2 */ ) {
/* Wait for 10 Micro sec */
udelay(10);
if ((eabr_vc->last_desc)&&((abr_vc->status & 0x07)==ABR_STATE))
foundLockUp = 1;
}
else {
tempCellSlot = abr_vc->last_cell_slot;
tempFract = abr_vc->fraction;
if((tempCellSlot == dev->testTable[vcc->vci]->lastTime)
&& (tempFract == dev->testTable[vcc->vci]->fract))
foundLockUp = 1;
dev->testTable[vcc->vci]->lastTime = tempCellSlot;
dev->testTable[vcc->vci]->fract = tempFract;
}
} /* last descriptor */
vcstatus->cnt = 0;
} /* vcstatus->cnt */
if (foundLockUp) {
IF_ABR(printk("LOCK UP found\n");)
writew(0xFFFD, dev->seg_reg+MODE_REG_0);
/* Wait for 10 Micro sec */
udelay(10);
abr_vc->status &= 0xFFF8;
abr_vc->status |= 0x0001; /* state is idle */
shd_tbl = (u_short *)dev->ABR_SCHED_TABLE_ADDR;
for( i = 0; ((i < dev->num_vc) && (shd_tbl[i])); i++ );
if (i < dev->num_vc)
shd_tbl[i] = vcc->vci;
else
IF_ERR(printk("ABR Seg. may not continue on VC %x\n",vcc->vci);)
writew(T_ONLINE, dev->seg_reg+MODE_REG_0);
writew(~(TRANSMIT_DONE|TCQ_NOT_EMPTY), dev->seg_reg+SEG_MASK_REG);
writew(TRANSMIT_DONE, dev->seg_reg+SEG_INTR_STATUS_REG);
vcstatus->cnt = 0;
} /* foundLockUp */
} /* if an ABR VC */
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 414 | 100.00% | 1 | 100.00% |
Total | 414 | 100.00% | 1 | 100.00% |
/*
** Conversion of 24-bit cellrate (cells/sec) to 16-bit floating point format.
**
** +----+----+------------------+-------------------------------+
** | R | NZ | 5-bit exponent | 9-bit mantissa |
** +----+----+------------------+-------------------------------+
**
** R = reserved (written as 0)
** NZ = 0 if 0 cells/sec; 1 otherwise
**
** if NZ = 1, rate = 1.mmmmmmmmm x 2^(eeeee) cells/sec
*/
static u16
cellrate_to_float(u32 cr)
{
#define NZ 0x4000
#define M_BITS 9 /* Number of bits in mantissa */
#define E_BITS 5 /* Number of bits in exponent */
#define M_MASK 0x1ff
#define E_MASK 0x1f
u16 flot;
u32 tmp = cr & 0x00ffffff;
int i = 0;
if (cr == 0)
return 0;
while (tmp != 1) {
tmp >>= 1;
i++;
}
if (i == M_BITS)
flot = NZ | (i << M_BITS) | (cr & M_MASK);
else if (i < M_BITS)
flot = NZ | (i << M_BITS) | ((cr << (M_BITS - i)) & M_MASK);
else
flot = NZ | (i << M_BITS) | ((cr >> (i - M_BITS)) & M_MASK);
return flot;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 151 | 100.00% | 1 | 100.00% |
Total | 151 | 100.00% | 1 | 100.00% |
#if 0
/*
** Conversion of 16-bit floating point format to 24-bit cellrate (cells/sec).
*/
static u32
float_to_cellrate(u16 rate)
{
u32 exp, mantissa, cps;
if ((rate & NZ) == 0)
return 0;
exp = (rate >> M_BITS) & E_MASK;
mantissa = rate & M_MASK;
if (exp == 0)
return 1;
cps = (1 << M_BITS) | mantissa;
if (exp == M_BITS)
cps = cps;
else if (exp > M_BITS)
cps <<= (exp - M_BITS);
else
cps >>= (M_BITS - exp);
return cps;
}
#endif
static void init_abr_vc (IADEV *dev, srv_cls_param_t *srv_p) {
srv_p->class_type = ATM_ABR;
srv_p->pcr = dev->LineRate;
srv_p->mcr = 0;
srv_p->icr = 0x055cb7;
srv_p->tbe = 0xffffff;
srv_p->frtt = 0x3a;
srv_p->rif = 0xf;
srv_p->rdf = 0xb;
srv_p->nrm = 0x4;
srv_p->trm = 0x7;
srv_p->cdf = 0x3;
srv_p->adtf = 50;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 88 | 100.00% | 1 | 100.00% |
Total | 88 | 100.00% | 1 | 100.00% |
static int
ia_open_abr_vc(IADEV *dev, srv_cls_param_t *srv_p,
struct atm_vcc *vcc, u8 flag)
{
f_vc_abr_entry *f_abr_vc;
r_vc_abr_entry *r_abr_vc;
u32 icr;
u8 trm, nrm, crm;
u16 adtf, air, *ptr16;
f_abr_vc =(f_vc_abr_entry *)dev->MAIN_VC_TABLE_ADDR;
f_abr_vc += vcc->vci;
switch (flag) {
case 1: /* FFRED initialization */
#if 0 /* sanity check */
if (srv_p->pcr == 0)
return INVALID_PCR;
if (srv_p->pcr > dev->LineRate)
srv_p->pcr = dev->LineRate;
if ((srv_p->mcr + dev->sum_mcr) > dev->LineRate)
return MCR_UNAVAILABLE;
if (srv_p->mcr > srv_p->pcr)
return INVALID_MCR;
if (!(srv_p->icr))
srv_p->icr = srv_p->pcr;
if ((srv_p->icr < srv_p->mcr) || (srv_p->icr > srv_p->pcr))
return INVALID_ICR;
if ((srv_p->tbe < MIN_TBE) || (srv_p->tbe > MAX_TBE))
return INVALID_TBE;
if ((srv_p->frtt < MIN_FRTT) || (srv_p->frtt > MAX_FRTT))
return INVALID_FRTT;
if (srv_p->nrm > MAX_NRM)
return INVALID_NRM;
if (srv_p->trm > MAX_TRM)
return INVALID_TRM;
if (srv_p->adtf > MAX_ADTF)
return INVALID_ADTF;
else if (srv_p->adtf == 0)
srv_p->adtf = 1;
if (srv_p->cdf > MAX_CDF)
return INVALID_CDF;
if (srv_p->rif > MAX_RIF)
return INVALID_RIF;
if (srv_p->rdf > MAX_RDF)
return INVALID_RDF;
#endif
memset ((caddr_t)f_abr_vc, 0, sizeof(*f_abr_vc));
f_abr_vc->f_vc_type = ABR;
nrm = 2 << srv_p->nrm; /* (2 ** (srv_p->nrm +1)) */
/* i.e 2**n = 2 << (n-1) */
f_abr_vc->f_nrm = nrm << 8 | nrm;
trm = 100000/(2 << (16 - srv_p->trm));
if ( trm == 0) trm = 1;
f_abr_vc->f_nrmexp =(((srv_p->nrm +1) & 0x0f) << 12)|(MRM << 8) | trm;
crm = srv_p->tbe / nrm;
if (crm == 0) crm = 1;
f_abr_vc->f_crm = crm & 0xff;
f_abr_vc->f_pcr = cellrate_to_float(srv_p->pcr);
icr = min( srv_p->icr, (srv_p->tbe > srv_p->frtt) ?
((srv_p->tbe/srv_p->frtt)*1000000) :
(1000000/(srv_p->frtt/srv_p->tbe)));
f_abr_vc->f_icr = cellrate_to_float(icr);
adtf = (10000 * srv_p->adtf)/8192;
if (adtf == 0) adtf = 1;
f_abr_vc->f_cdf = ((7 - srv_p->cdf) << 12 | adtf) & 0xfff;
f_abr_vc->f_mcr = cellrate_to_float(srv_p->mcr);
f_abr_vc->f_acr = f_abr_vc->f_icr;
f_abr_vc->f_status = 0x0042;
break;
case 0: /* RFRED initialization */
ptr16 = (u_short *)(dev->reass_ram + REASS_TABLE*dev->memSize);
*(ptr16 + vcc->vci) = NO_AAL5_PKT | REASS_ABR;
r_abr_vc = (r_vc_abr_entry*)(dev->reass_ram+ABR_VC_TABLE*dev->memSize);
r_abr_vc += vcc->vci;
r_abr_vc->r_status_rdf = (15 - srv_p->rdf) & 0x000f;
air = srv_p->pcr << (15 - srv_p->rif);
if (air == 0) air = 1;
r_abr_vc->r_air = cellrate_to_float(air);
dev->testTable[vcc->vci]->vc_status = VC_ACTIVE | VC_ABR;
dev->sum_mcr += srv_p->mcr;
dev->n_abr++;
break;
default:
break;
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 475 | 99.37% | 1 | 33.33% |
Linus Torvalds | 2 | 0.42% | 1 | 33.33% |
Adrian Bunk | 1 | 0.21% | 1 | 33.33% |
Total | 478 | 100.00% | 3 | 100.00% |
static int ia_cbr_setup (IADEV *dev, struct atm_vcc *vcc) {
u32 rateLow=0, rateHigh, rate;
int entries;
struct ia_vcc *ia_vcc;
int idealSlot =0, testSlot, toBeAssigned, inc;
u32 spacing;
u16 *SchedTbl, *TstSchedTbl;
u16 cbrVC, vcIndex;
u32 fracSlot = 0;
u32 sp_mod = 0;
u32 sp_mod2 = 0;
/* IpAdjustTrafficParams */
if (vcc->qos.txtp.max_pcr <= 0) {
IF_ERR(printk("PCR for CBR not defined\n");)
return -1;
}
rate = vcc->qos.txtp.max_pcr;
entries = rate / dev->Granularity;
IF_CBR(printk("CBR: CBR entries=0x%x for rate=0x%x & Gran=0x%x\n",
entries, rate, dev->Granularity);)
if (entries < 1)
IF_CBR(printk("CBR: Bandwidth smaller than granularity of CBR table\n");)
rateLow = entries * dev->Granularity;
rateHigh = (entries + 1) * dev->Granularity;
if (3*(rate - rateLow) > (rateHigh - rate))
entries++;
if (entries > dev->CbrRemEntries) {
IF_CBR(printk("CBR: Not enough bandwidth to support this PCR.\n");)
IF_CBR(printk("Entries = 0x%x, CbrRemEntries = 0x%x.\n",
entries, dev->CbrRemEntries);)
return -EBUSY;
}
ia_vcc = INPH_IA_VCC(vcc);
ia_vcc->NumCbrEntry = entries;
dev->sum_mcr += entries * dev->Granularity;
/* IaFFrednInsertCbrSched */
// Starting at an arbitrary location, place the entries into the table
// as smoothly as possible
cbrVC = 0;
spacing = dev->CbrTotEntries / entries;
sp_mod = dev->CbrTotEntries % entries; // get modulo
toBeAssigned = entries;
fracSlot = 0;
vcIndex = vcc->vci;
IF_CBR(printk("Vci=0x%x,Spacing=0x%x,Sp_mod=0x%x\n",vcIndex,spacing,sp_mod);)
while (toBeAssigned)
{
// If this is the first time, start the table loading for this connection
// as close to entryPoint as possible.
if (toBeAssigned == entries)
{
idealSlot = dev->CbrEntryPt;
dev->CbrEntryPt += 2; // Adding 2 helps to prevent clumping
if (dev->CbrEntryPt >= dev->CbrTotEntries)
dev->CbrEntryPt -= dev->CbrTotEntries;// Wrap if necessary
} else {
idealSlot += (u32)(spacing + fracSlot); // Point to the next location
// in the table that would be smoothest
fracSlot = ((sp_mod + sp_mod2) / entries); // get new integer part
sp_mod2 = ((sp_mod + sp_mod2) % entries); // calc new fractional part
}
if (idealSlot >= (int)dev->CbrTotEntries)
idealSlot -= dev->CbrTotEntries;
// Continuously check around this ideal value until a null
// location is encountered.
SchedTbl = (u16*)(dev->seg_ram+CBR_SCHED_TABLE*dev->memSize);
inc = 0;
testSlot = idealSlot;
TstSchedTbl = (u16*)(SchedTbl+testSlot); //set index and read in value
IF_CBR(printk("CBR Testslot 0x%x AT Location 0x%p, NumToAssign=%d\n",
testSlot, TstSchedTbl,toBeAssigned);)
memcpy((caddr_t)&cbrVC,(caddr_t)TstSchedTbl,sizeof(cbrVC));
while (cbrVC) // If another VC at this location, we have to keep looking
{
inc++;
testSlot = idealSlot - inc;
if (testSlot < 0) { // Wrap if necessary
testSlot += dev->CbrTotEntries;
IF_CBR(printk("Testslot Wrap. STable Start=0x%p,Testslot=%d\n",
SchedTbl,testSlot);)
}
TstSchedTbl = (u16 *)(SchedTbl + testSlot); // set table index
memcpy((caddr_t)&cbrVC,(caddr_t)TstSchedTbl,sizeof(cbrVC));
if (!cbrVC)
break;
testSlot = idealSlot + inc;
if (testSlot >= (int)dev->CbrTotEntries) { // Wrap if necessary
testSlot -= dev->CbrTotEntries;
IF_CBR(printk("TotCbrEntries=%d",dev->CbrTotEntries);)
IF_CBR(printk(" Testslot=0x%x ToBeAssgned=%d\n",
testSlot, toBeAssigned);)
}
// set table index and read in value
TstSchedTbl = (u16*)(SchedTbl + testSlot);
IF_CBR(printk("Reading CBR Tbl from 0x%p, CbrVal=0x%x Iteration %d\n",
TstSchedTbl,cbrVC,inc);)
memcpy((caddr_t)&cbrVC,(caddr_t)TstSchedTbl,sizeof(cbrVC));
} /* while */
// Move this VCI number into this location of the CBR Sched table.
memcpy((caddr_t)TstSchedTbl, (caddr_t)&vcIndex, sizeof(*TstSchedTbl));
dev->CbrRemEntries--;
toBeAssigned--;
} /* while */
/* IaFFrednCbrEnable */
dev->NumEnabledCBR++;
if (dev->NumEnabledCBR == 1) {
writew((CBR_EN | UBR_EN | ABR_EN | (0x23 << 2)), dev->seg_reg+STPARMS);
IF_CBR(printk("CBR is enabled\n");)
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 658 | 98.36% | 1 | 25.00% |
David Howells | 6 | 0.90% | 1 | 25.00% |
Linus Torvalds | 4 | 0.60% | 1 | 25.00% |
Julia Lawall | 1 | 0.15% | 1 | 25.00% |
Total | 669 | 100.00% | 4 | 100.00% |
static void ia_cbrVc_close (struct atm_vcc *vcc) {
IADEV *iadev;
u16 *SchedTbl, NullVci = 0;
u32 i, NumFound;
iadev = INPH_IA_DEV(vcc->dev);
iadev->NumEnabledCBR--;
SchedTbl = (u16*)(iadev->seg_ram+CBR_SCHED_TABLE*iadev->memSize);
if (iadev->NumEnabledCBR == 0) {
writew((UBR_EN | ABR_EN | (0x23 << 2)), iadev->seg_reg+STPARMS);
IF_CBR (printk("CBR support disabled\n");)
}
NumFound = 0;
for (i=0; i < iadev->CbrTotEntries; i++)
{
if (*SchedTbl == vcc->vci) {
iadev->CbrRemEntries++;
*SchedTbl = NullVci;
IF_CBR(NumFound++;)
}
SchedTbl++;
}
IF_CBR(printk("Exit ia_cbrVc_close, NumRemoved=%d\n",NumFound);)
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 152 | 100.00% | 1 | 100.00% |
Total | 152 | 100.00% | 1 | 100.00% |
static int ia_avail_descs(IADEV *iadev) {
int tmp = 0;
ia_hack_tcq(iadev);
if (iadev->host_tcq_wr >= iadev->ffL.tcq_rd)
tmp =