ch.c revision 193974072f41a843678abf5f61979c748687e66b
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* This file is part of the Chelsio T1 Ethernet driver.
*
* Copyright (C) 2003-2005 Chelsio Communications. All rights reserved.
*/
/*
* Solaris Multithreaded STREAMS DLPI Chelsio PCI Ethernet Driver
*/
/* #define CH_DEBUG 1 */
#ifdef CH_DEBUG
#define DEBUG_ENTER(a) debug_enter(a)
#else
#define DEBUG_ENTER(a)
#define PRINT(a)
#endif
#include <sys/ethernet.h>
#include "ostypes.h"
#include "common.h"
#include "oschtoe.h"
#include "sge.h"
#include "regs.h"
#include "ch.h" /* Chelsio Driver specific parameters */
#include "version.h"
/*
* Function prototypes.
*/
static int ch_quiesce(dev_info_t *);
#if defined(__sparc)
#endif
/* GLD interfaces */
static int ch_reset(gld_mac_info_t *);
static int ch_start(gld_mac_info_t *);
static int ch_stop(gld_mac_info_t *);
static int ch_set_promiscuous(gld_mac_info_t *, int);
/*
* Data access requirements.
*/
static struct ddi_device_acc_attr le_attr = {
};
/*
* No swap mapping device attributes
*/
static struct ddi_device_acc_attr null_attr = {
};
/*
* STREAMS driver identification struture module_info(9s)
*
* driver limit values
*/
static struct module_info ch_minfo = {
CHIDNUM, /* mi_idnum */
CHNAME, /* mi_idname */
CHMINPSZ, /* mi_minpsz */
CHMAXPSZ, /* mi_maxpsz */
CHHIWAT, /* mi_hiwat */
CHLOWAT /* mi_lowat */
};
/*
* STREAMS queue processiong procedures qinit(9s)
*
* read queue procedures
*/
(int (*)()) NULL, /* qi_putp */
gld_rsrv, /* qi_srvp */
gld_open, /* qi_qopen */
gld_close, /* qi_qclose */
(int (*)()) NULL, /* qi_qadmin */
&ch_minfo, /* qi_minfo */
NULL /* qi_mstat */
};
/*
* STREAMS queue processiong procedures qinit(9s)
*
* write queue procedures
*/
gld_wput, /* qi_putp */
gld_wsrv, /* qi_srvp */
(int (*)()) NULL, /* qi_qopen */
(int (*)()) NULL, /* qi_qclose */
(int (*)()) NULL, /* qi_qadmin */
&ch_minfo, /* qi_minfo */
NULL /* qi_mstat */
};
/*
* STREAMS entity declaration structure - streamtab(9s)
*/
&ch_rinit, /* read queue information */
&ch_winit, /* write queue information */
NULL, /* st_muxrinit */
NULL /* st_muxwrinit */
};
/*
* Device driver ops vector - cb_ops(9s)
*
* chinfo identifies driver as a STREAMS driver.
*/
nulldev, /* cb_open */
nulldev, /* cb_close */
nodev, /* cb_strategy */
nodev, /* cb_print */
nodev, /* cb_dump */
nodev, /* cb_read */
nodev, /* cb_write */
nodev, /* cb_ioctl */
nodev, /* cb_devmap */
nodev, /* cb_mmap */
nodev, /* cb_segmap */
nochpoll, /* cb_chpoll */
ddi_prop_op, /* report driver property information - prop_op(9e) */
&chinfo, /* cb_stream */
#if defined(__sparc)
#else
D_MP, /* cb_flag (supports multi-threading) */
#endif
CB_REV, /* cb_rev */
nodev, /* cb_aread */
nodev /* cb_awrite */
};
/*
* dev_ops(9S) structure
*
* Device Operations table, for autoconfiguration
*/
DEVO_REV, /* Driver build version */
0, /* Initial driver reference count */
gld_getinfo, /* funcp: get driver information - getinfo(9e) */
nulldev, /* funcp: entry point obsolute - identify(9e) */
nulldev, /* funp: probe for device - probe(9e) */
ch_attach, /* funp: attach driver to dev_info - attach(9e) */
ch_detach, /* funp: detach driver to unload - detach(9e) */
nodev, /* funp: reset device (not supported) - dev_ops(9s) */
&cb_ch_ops, /* ptr to cb_ops structure */
NULL, /* ptr to nexus bus operations structure (leaf) */
NULL, /* funp: change device power level - power(9e) */
ch_quiesce, /* devo_quiesce */
};
/*
* modldrv(9s) structure
*
* Definition for module specific device driver linkage structures (modctl.h)
*/
&mod_driverops, /* driver module */
&ch_ops, /* driver ops */
};
/*
* modlinkage(9s) structure
*
* module linkage base structure (modctl.h)
*/
static struct modlinkage modlinkage = {
MODREV_1, /* revision # of system */
&modldrv, /* NULL terminated list of linkage strucures */
};
/* ===================== start of STREAMS driver code ================== */
#ifdef CONFIG_CHELSIO_T1_OFFLOAD
/*
* global pointer to toe per-driver control structure.
*/
#define MAX_CARDS 4
#endif
/*
* Ethernet broadcast address definition.
*/
static struct ether_addr etherbroadcastaddr = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
/*
* Module initialization functions.
*
* Routine Called by
* _init(9E) modload(9F)
* _info(9E) modinfo(9F)
* _fini(9E) modunload(9F)
*/
/*
* _init(9E):
*
* Initial, one-time, resource allocation and data initialization.
*/
int
_init(void)
{
int status;
return (status);
}
/*
* _fini(9E): It is here that any device information that was allocated
* during the _init(9E) routine should be released and the module removed
* from the system. In the case of per-instance information, that information
* should be released in the _detach(9E) routine.
*/
int
_fini(void)
{
int status;
int i;
uint32_t t = 0;
for (i = 0; i < SZ_INUSE; i++)
t += buffers_in_use[i];
if (t != NULL)
return (DDI_FAILURE);
if (status == DDI_SUCCESS)
return (status);
}
int
{
int status;
return (status);
}
/*
* Attach(9E) - This is called on the open to the device. It creates
* an instance of the driver. In this routine we create the minor
* device node. The routine also initializes all per-unit
* mutex's and conditional variables.
*
* If we were resuming a suspended instance of a device due to power
* management, then that would be handled here as well. For more on
* that subject see the man page for pm(9E)
*
* Interface exists: make available by filling in network interface
* record. System will initialize the interface when it is ready
* to accept packets.
*/
int chdebug = 0;
int ch_abort_debug = 0;
static int
{
int rv;
int unit;
#ifdef CH_DEBUG
int Version;
int VendorID;
int DeviceID;
int SubDeviceID;
int Command;
#endif
char *driver;
if (ch_abort_debug)
debug_enter("ch_attach");
if (chdebug)
return (DDI_FAILURE);
if (cmd == DDI_ATTACH) {
PRINT(("macinfo allocation failed\n"));
DEBUG_ENTER("ch_attach");
return (DDI_FAILURE);
}
PRINT(("zalloc of chp failed\n"));
DEBUG_ENTER("ch_attach");
return (DDI_FAILURE);
}
#ifdef CONFIG_CHELSIO_T1_OFFLOAD
/* Solaris TOE support */
#endif
/*
* map in PCI register spaces
*
* PCI register set 0 - PCI configuration space
* PCI register set 1 - T101 card register space #1
*/
/* map in T101 PCI configuration space */
dip, /* ptr to dev's dev_info struct */
if (rv != DDI_SUCCESS) {
PRINT(("PCI config setup failed\n"));
DEBUG_ENTER("ch_attach");
#ifdef CONFIG_CHELSIO_T1_OFFLOAD
#endif
return (DDI_FAILURE);
}
macinfo->gldm_minpkt = 0;
/*
* do a power reset of card
*
* 1. set PwrState to D3hot (3)
* 2. clear PwrState flags
*/
/* delay .5 sec */
DELAY(500000);
#ifdef CH_DEBUG
#endif
/* map in T101 register space (BAR0) */
dip, /* ptr to dev's dev_info struct */
BAR0, /* register address space */
0, /* offset into register address space */
0, /* length mapped (everything) */
&le_attr, /* ptr to device attr structure */
if (rv != DDI_SUCCESS) {
PRINT(("map registers failed\n"));
DEBUG_ENTER("ch_attach");
#ifdef CONFIG_CHELSIO_T1_OFFLOAD
#endif
"%s: ddi_regs_map_setup BAR0 error %d\n",
return (DDI_FAILURE);
}
#ifdef CH_DEBUG
#endif
/*
* Add interrupt to system.
*/
dip, /* ptr to dev's dev_info struct */
0, /* interrupt # (0) */
if (rv != DDI_SUCCESS) {
PRINT(("iblock cookie failed\n"));
DEBUG_ENTER("ch_attach");
#ifdef CONFIG_CHELSIO_T1_OFFLOAD
#endif
"%s: ddi_get_iblock_cookie error %d\n",
return (DDI_FAILURE);
}
/*
* add interrupt handler before card setup.
*/
rv = ddi_add_intr(
dip, /* ptr to dev's dev_info struct */
0, /* interrupt # (0) */
0, /* iblock cookie ptr (NULL) */
0, /* idevice cookie ptr (NULL) */
gld_intr, /* function ptr to interrupt handler */
if (rv != DDI_SUCCESS) {
PRINT(("add_intr failed\n"));
DEBUG_ENTER("ch_attach");
#ifdef CONFIG_CHELSIO_T1_OFFLOAD
#endif
return (DDI_FAILURE);
}
/* initalize all the remaining per-card locks */
/* ------- initialize Chelsio card ------- */
PRINT(("card initialization failed\n"));
DEBUG_ENTER("ch_attach");
#ifdef CONFIG_CHELSIO_T1_OFFLOAD
#endif
return (DDI_FAILURE);
}
/* ------- done with Chelsio card ------- */
/* now can set mac address */
/*
* We only active checksum offload for T2 architectures.
*/
} else
rv = gld_register(
dip, /* ptr to dev's dev_info struct */
macinfo); /* ptr to gld macinfo buffer */
/*
* The Jumbo frames capability is not yet available
* in Solaris 10 so registration will fail. MTU > 1500 is
* supported in Update 1.
*/
if (rv != DDI_SUCCESS) {
rv = gld_register(
dip, /* ptr to dev's dev_info struct */
macinfo); /* ptr to gld macinfo buffer */
}
if (rv != DDI_SUCCESS) {
PRINT(("gld_register failed\n"));
DEBUG_ENTER("ch_attach");
return (DDI_FAILURE);
}
/*
* print a banner at boot time (verbose mode), announcing
* the device pointed to by dip
*/
if (ch_abort_debug)
debug_enter("ch_attach");
return (DDI_SUCCESS);
} else if (cmd == DDI_RESUME) {
PRINT(("attach resume\n"));
DEBUG_ENTER("ch_attach");
return (DDI_FAILURE);
return (DDI_SUCCESS);
} else {
PRINT(("attach: bad command\n"));
DEBUG_ENTER("ch_attach");
return (DDI_FAILURE);
}
}
/*
* quiesce(9E) entry point.
*
* This function is called when the system is single-threaded at high
* PIL with preemption disabled. Therefore, this function must not be
* blocked.
*
* This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
* DDI_FAILURE indicates an error condition and should almost never happen.
*/
static int
{
chdebug = 0;
ch_abort_debug = 0;
#ifdef CONFIG_CHELSIO_T1_OFFLOAD
#endif
/* Set driver state for this card to IDLE */
/*
* Do a power reset of card
* 1. set PwrState to D3hot (3)
* 2. clear PwrState flags
*/
/* Wait 0.5 sec */
drv_usecwait(500000);
/*
* Now stop the chip
*/
/* Disables all interrupts */
/* Disables SGE queues */
return (DDI_SUCCESS);
}
static int
{
if (cmd == DDI_DETACH) {
/*
* fail detach if there are outstanding mblks still
* in use somewhere.
*/
DEBUG_ENTER("ch_detach");
#ifdef CONFIG_CHELSIO_T1_OFFLOAD
return (DDI_FAILURE);
}
#endif
/*
* set driver state for this card to IDLE. We're
* shutting down.
*/
/*
* do a power reset of card
*
* 1. set PwrState to D3hot (3)
* 2. clear PwrState flags
*/
/* delay .5 sec */
DELAY(500000);
/* free register resources */
(void) gld_unregister(macinfo);
/* make sure no interrupts while shutting down card */
/*
* reset device and recover resources
*/
#if defined(__sparc)
#endif
DEBUG_ENTER("ch_detach end");
return (DDI_SUCCESS);
DEBUG_ENTER("suspend");
return (DDI_FAILURE);
#ifdef TODO
/* Un-initialize (STOP) T101 */
#endif
return (DDI_SUCCESS);
} else
return (DDI_FAILURE);
}
/*
* ch_alloc_dma_mem
*
* allocates DMA handle
* allocates kernel memory
* allocates DMA access handle
*
* chp - per-board descriptor
* type - byteswap mapping?
* flags - type of mapping
* size - # bytes mapped
* paddr - physical address
* dh - ddi dma handle
* ah - ddi access handle
*/
void *
{
align = 0x4000;
else {
return (0);
}
/*
* dynamically create a dma attribute structure
*/
&ch_dma_attr, /* DMA attributes */
DDI_DMA_SLEEP, /* Wait if no memory */
NULL, /* no argument to callback */
&ch_dh); /* DMA handle */
if (rv != DDI_SUCCESS) {
"%s: ch_alloc_dma_mem: ddi_dma_alloc_handle error %d\n",
return (0);
}
/* set byte order for data xfer */
if (type)
else
ch_dh, /* dma handle */
size, /* size desired allocate */
dev_attrp, /* access attributes */
DDI_DMA_SLEEP, /* wait for resources */
NULL, /* no argument */
&ch_vaddr, /* allocated memory */
&rlen, /* real size allocated */
&ch_ah); /* data access handle */
if (rv != DDI_SUCCESS) {
"%s: ch_alloc_dma_mem: ddi_dma_mem_alloc error %d\n",
return (0);
}
ch_dh, /* dma handle */
(struct as *)0, /* kernel address space */
ch_vaddr, /* virtual address */
rlen, /* length of object */
DDI_DMA_SLEEP, /* Wait for resources */
NULL, /* no argument */
&cookie, /* dma cookie */
&count);
if (rv != DDI_DMA_MAPPED) {
"%s: ch_alloc_dma_mem: ddi_dma_addr_bind_handle error %d\n",
return (0);
}
if (count != 1) {
"%s: ch_alloc_dma_mem: ch_alloc_dma_mem cookie count %d\n",
return (0);
}
return ((void *)ch_vaddr);
}
/*
* ch_free_dma_mem
*
* frees resources allocated by ch_alloc_dma_mem()
*
* frees DMA handle
* frees kernel memory
* frees DMA access handle
*/
void
{
(void) ddi_dma_unbind_handle(ch_dh);
}
/*
* create a dma handle and return a dma handle entry.
*/
{
int rv;
&ch_dma_attr, /* DMA attributes */
DDI_DMA_SLEEP, /* Wait if no memory */
NULL, /* no argument */
&ch_dh); /* DMA handle */
if (rv != DDI_SUCCESS) {
"%s: ch_get_dma_handle: ddi_dma_alloc_handle error %d\n",
return ((free_dh_t *)0);
}
return (dhe);
}
/*
* free the linked list of dma descriptor entries.
*/
static void
{
while (dhe) {
}
}
/*
* ch_bind_dma_handle()
*
* returns # of entries used off of cmdQ_ce_t array to hold physical addrs.
*
* chp - per-board descriptor
* size - # bytes mapped
* vaddr - virtual address
* cmp - array of cmdQ_ce_t entries
* cnt - # free entries in cmp array
*/
{
uint32_t n = 1;
}
return (0);
}
ch_dh, /* dma handle */
(struct as *)0, /* kernel address space */
vaddr, /* virtual address */
size, /* length of object */
DDI_DMA_SLEEP, /* Wait for resources */
NULL, /* no argument */
&cookie, /* dma cookie */
&count);
if (rv != DDI_DMA_MAPPED) {
/* return dma header descriptor back to free list */
"%s: ch_bind_dma_handle: ddi_dma_addr_bind_handle err %d\n",
return (0);
}
/*
* abort if we've run out of space
*/
/* return dma header descriptor back to free list */
return (0);
}
while (--count) {
cmp++;
n++;
}
return (n);
}
/*
* ch_unbind_dma_handle()
*
* frees resources alloacted by ch_bind_dma_handle().
*
* frees DMA handle
*/
void
{
if (ddi_dma_unbind_handle(ch_dh))
}
#if defined(__sparc)
/*
* DVMA stuff. Solaris only.
*/
/*
* create a dvma handle and return a dma handle entry.
* DVMA is on sparc only!
*/
{
int rv;
ch_dvma_attr.dlim_addr_lo = 0;
rv = dvma_reserve(
&ch_dvma_attr, /* DVMA attributes */
3, /* number of pages */
&ch_dh); /* DVMA handle */
if (rv != DDI_SUCCESS) {
"%s: ch_get_dvma_handle: dvma_reserve() error %d\n",
return ((free_dh_t *)0);
}
return (dhe);
}
/*
* free the linked list of dvma descriptor entries.
* DVMA is only on sparc!
*/
static void
{
while (dhe) {
}
}
/*
* ch_bind_dvma_handle()
*
* returns # of entries used off of cmdQ_ce_t array to hold physical addrs.
* DVMA in sparc only
*
* chp - per-board descriptor
* size - # bytes mapped
* vaddr - virtual address
* cmp - array of cmdQ_ce_t entries
* cnt - # free entries in cmp array
*/
{
uint32_t n = 1;
}
return (0);
}
n = cnt;
ch_dh, /* dvma handle */
vaddr, /* virtual address */
size, /* length of object */
0, /* start at index 0 */
&cookie);
cookie.dmac_notused = 0;
n = 1;
return (n);
}
/*
* ch_unbind_dvma_handle()
*
* frees resources alloacted by ch_bind_dvma_handle().
*
* frees DMA handle
*/
void
{
}
#endif /* defined(__sparc) */
/*
* send received packet up stream.
*
* if driver has been stopped, then we drop the message.
*/
void
{
/*
* probably do not need a lock here. When we set PESTOP in
* ch_stop() a packet could have just passed here and gone
* upstream. The next one will be dropped.
*/
/*
* note that flg will not be set unless enable_checksum_offload
*/
if (flg)
HCK_FULLCKSUM, 0);
} else {
}
}
/*
* unblock gld driver.
*/
void
{
}
/*
* reset the card.
*
* Note: we only do this after the card has been initialized.
*/
static int
{
return (GLD_FAILURE);
}
return (GLD_FAILURE);
}
#ifdef NOTYET
/*
* do a reset of card
*
* 1. set PwrState to D3hot (3)
* 2. clear PwrState flags
*/
/*
* When we did this, the card didn't start. First guess is that
* the initialization is not quite correct. For now, we don't
* reset things.
*/
/* delay .5 sec */
DELAY(500000);
}
#endif
return (GLD_SUCCESS);
}
static int
{
#ifdef CONFIG_CHELSIO_T1_OFFLOAD
/* only initialize card on first attempt */
} else
#else
/* go to running state, we're being started */
#endif
return (GLD_SUCCESS);
}
static int
{
/*
* can only stop the chip if it's been initialized
*/
return (GLD_FAILURE);
}
#ifdef CONFIG_CHELSIO_T1_OFFLOAD
} else
#else
#endif
return (GLD_SUCCESS);
}
static int
{
if (mp) {
} else {
return (GLD_FAILURE);
}
return (GLD_SUCCESS);
}
static int
{
}
static int
{
case M_IOCTL:
/* pe_ioctl() does qreply() */
break;
default:
/*
* cmn_err(CE_NOTE, "ch_ioctl not M_IOCTL\n");
* debug_enter("bad ch_ioctl");
*/
break;
}
return (GLD_SUCCESS);
}
static int
{
switch (flag) {
case GLD_MAC_PROMISC_MULTI:
break;
case GLD_MAC_PROMISC_NONE:
pe_set_promiscuous(chp, 0);
break;
case GLD_MAC_PROMISC_PHYS:
default:
break;
}
return (GLD_SUCCESS);
}
static int
{
/*
* race looks benign here.
*/
return (GLD_FAILURE);
}
(void) pe_get_stats(chp,
&speed,
&intrcnt,
&norcvbuf,
&oerrors,
&ierrors,
&underrun,
&overrun,
&framing,
&crc,
&carrier,
&late,
&defer,
&xerrs,
&rerrs,
&toolong,
&runt,
&multixmt,
&multircv,
&brdcstrcv);
return (GLD_SUCCESS);
}
static int
{
#ifdef TX_CKSUM_FIX
int frags;
struct ether_header *ehdr;
int tflg = 0;
#endif /* TX_CKSUM_FIX */
/*
* race looks benign here.
*/
return (GLD_FAILURE);
}
msg_flg = 0;
} else
} else
#ifdef TX_CKSUM_FIX
/*
* Check if the message spans more than one mblk or
* if it does and the ip header is not in the first
* fragment then pull up the message. This case is
* expected to be rare.
*/
frags = 0;
msg_len = 0;
do {
frags++;
} while (nmp);
/*
* If the first mblk has enough space at the beginning of
* the data buffer to hold a CPL header, then, we'll expancd
* the front of the buffer so a pullup will leave space for
* pe_start() to add the CPL header in line. We need to remember
* that we've done this so we can undo it after the pullup.
*
* Note that if we decide to do an allocb to hold the CPL header,
* we need to catch the case where we've added an empty mblk for
* the header but never did a pullup. This would result in the
* tests for etherheader, etc. being done on the initial, empty,
* mblk instead of the one with data. See PR3646 for further
* details. (note this PR is closed since it is no longer relevant).
*
* Another point is that if we do add an allocb to add space for
* a CPL header, after a pullup, the initial pointer, mp, in GLD will
* no longer point to a valid mblk. When we get the mblk (by allocb),
* we need to switch the mblk structure values between it and the
* mp structure values referenced by GLD. This handles the case where
* we've run out of cmdQ entries and report GLD_NORESOURCES back to
* GLD. The pointer to the mblk data will have been modified to hold
* an empty 8 bytes for the CPL header, For now, we let the pe_start()
* routine prepend an 8 byte mblk.
*/
tflg = 1;
}
if (frags > 3) {
return (GLD_SUCCESS);
}
} else if ((msg_len > MAX_ALL_HDRLEN) &&
return (GLD_SUCCESS);
}
}
if (tflg)
}
}
#endif /* TX_CKSUM_FIX */
/*
* return 0 - data send successfully
* return 1 - no resources, reschedule
*/
return (GLD_NORESOURCES);
else
return (GLD_SUCCESS);
}
static uint_t
{
}
/*
* generate name of driver with unit# postpended.
*/
void
{
if (unit > 9) {
} else {
}
}
void
{
}
#ifdef CONFIG_CHELSIO_T1_OFFLOAD
/*
* register toe offload.
*/
void *
{
/* start up adapter if first user */
} else
}
}
/*
* unregister toe offload.
* XXX Need to fix races here.
* 1. turn off SGE interrupts.
* 2. do update
* 3. re-enable SGE interrupts
* 4. SGE doorbell to make sure things get restarted.
*/
void
ch_unregister(void)
{
int i;
for (i = 0; i < MAX_CARDS; i++) {
continue;
} else
}
}
#endif /* CONFIG_CHELSIO_T1_OFFLOAD */
/*
* get properties from chxge.conf
*/
static void
{
int val;
int tval = 0;
extern int enable_latency_timer;
extern uint32_t sge_cmdq0_cnt;
extern uint32_t sge_cmdq1_cnt;
extern uint32_t sge_flq0_cnt;
extern uint32_t sge_flq1_cnt;
extern uint32_t sge_respq_cnt;
extern uint32_t sge_cmdq0_cnt_orig;
extern uint32_t sge_cmdq1_cnt_orig;
extern uint32_t sge_flq0_cnt_orig;
extern uint32_t sge_flq1_cnt_orig;
extern uint32_t sge_respq_cnt_orig;
"enable_dvma", -1);
if (val == -1)
"enable-dvma", -1);
if (val != -1) {
if (val != 0)
}
"amd_bug_workaround", -1);
if (val == -1)
"amd-bug-workaround", -1);
if (val != -1) {
if (val == 0) {
goto fail_exit;
}
}
/*
* Step up to the parent node, That's the node above us
* in the device tree. And will typically be the PCI host
* Controller.
*/
/*
* Now get the 'Vendor id' properties
*/
goto fail_exit;
}
/*
* Now get the 'Device id' properties
*/
goto fail_exit;
}
/*
* Now get the 'Revision id' properties
*/
goto fail_exit;
}
/*
* set default values based on node above us.
*/
(revision_id <= AMD_BRIDGE_REV)) {
uint32_t v;
/* if 133 Mhz not enabled, then do nothing - we're not PCIx */
if ((v & 0x20000) == NULL) {
goto fail_exit;
}
/* check burst size and transaction count */
switch (burst) {
case 0: /* 512 */
/* 512 burst size legal with split cnts 1,2,3 */
if (cnt <= 2) {
goto fail_exit;
}
break;
case 1: /* 1024 */
/* 1024 burst size legal with split cnts 1,2 */
if (cnt <= 1) {
goto fail_exit;
}
break;
case 2: /* 2048 */
/* 2048 burst size legal with split cnts 1 */
if (cnt == 0) {
goto fail_exit;
}
break;
case 3: /* 4096 */
break;
}
} else {
goto fail_exit;
}
/*
* if illegal burst size seen, then default to 1024 burst size
*/
/*
* if illegal transaction cnt seen, then default to 2
*/
/*
* alter the burstsize parameter via an entry
* in chxge.conf
*/
"pci_burstsize", -1);
if (val == -1)
"pci-burstsize", -1);
if (val != -1) {
switch (val) {
case 0: /* use default */
break;
case 1024:
break;
case 2048:
break;
case 4096:
break;
default:
break;
}
}
/*
* set transaction count
*/
"pci_split_transaction_cnt", -1);
if (val == -1)
"pci-split-transaction-cnt", -1);
if (val != -1) {
switch (val) {
case 0: /* use default */
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 8:
break;
case 12:
break;
case 16:
break;
case 32:
break;
default:
break;
}
}
/*
* set relaxed ordering bit?
*/
"pci_relaxed_ordering_on", -1);
if (val == -1)
"pci-relaxed-ordering-on", -1);
/*
* default is to use system default value.
*/
if (val != -1) {
if (val)
}
"enable_latency_timer", -1);
if (val == -1)
"enable-latency-timer", -1);
if (val != -1)
/*
* default maximum Jumbo Frame size.
*/
"maximum_mtu", -1);
if (val == -1) {
"maximum-mtu", -1);
}
if (val != -1) {
if (val > 9582) {
"maximum_mtu value %d > 9582. Value set to 9582",
val);
val = 9582;
} else if (val < 1500) {
"maximum_mtu value %d < 1500. Value set to 1500",
val);
val = 1500;
}
if (val)
}
/*
* default value for this instance mtu
*/
"accept_jumbo", -1);
if (val == -1) {
"accept-jumbo", -1);
}
if (val != -1) {
if (val)
}
#ifdef CONFIG_CHELSIO_T1_OFFLOAD
#else
}
#endif
"enable_checksum_offload", -1);
if (val == -1)
"enable-checksum-offload", -1);
if (val != -1) {
}
/*
* Provides a tuning capability for the command queue 0 size.
*/
"sge_cmdq0_cnt", -1);
if (val == -1)
"sge-cmdq0-cnt", -1);
if (val != -1) {
if (val > 10)
sge_cmdq0_cnt = val;
}
if (sge_cmdq0_cnt > 65535) {
"%s: sge-cmdQ0-cnt > 65535 - resetting value to default",
}
tval += sge_cmdq0_cnt;
/*
* Provides a tuning capability for the command queue 1 size.
*/
"sge_cmdq1_cnt", -1);
if (val == -1)
"sge-cmdq1-cnt", -1);
if (val != -1) {
if (val > 10)
sge_cmdq1_cnt = val;
}
if (sge_cmdq1_cnt > 65535) {
"%s: sge-cmdQ0-cnt > 65535 - resetting value to default",
}
/*
* Provides a tuning capability for the free list 0 size.
*/
"sge_flq0_cnt", -1);
if (val == -1)
"sge-flq0-cnt", -1);
if (val != -1) {
if (val > 512)
sge_flq0_cnt = val;
}
if (sge_flq0_cnt > 65535) {
"%s: sge-flq0-cnt > 65535 - resetting value to default",
}
tval += sge_flq0_cnt;
/*
* Provides a tuning capability for the free list 1 size.
*/
"sge_flq1_cnt", -1);
if (val == -1)
"sge-flq1-cnt", -1);
if (val != -1) {
if (val > 512)
sge_flq1_cnt = val;
}
if (sge_flq1_cnt > 65535) {
"%s: sge-flq1-cnt > 65535 - resetting value to default",
}
tval += sge_flq1_cnt;
/*
* Provides a tuning capability for the responce queue size.
*/
"sge_respq_cnt", -1);
if (val == -1)
"sge-respq-cnt", -1);
if (val != -1) {
if (val > 30)
sge_respq_cnt = val;
}
if (sge_respq_cnt > 65535) {
"%s: sge-respq-cnt > 65535 - resetting value to default",
}
if (tval > sge_respq_cnt) {
if (tval <= 65535) {
"%s: sge-respq-cnt < %d - setting value to %d (cmdQ+flq0+flq1)",
} else {
"%s: Q sizes invalid - resetting to default values",
}
}
}