summaryrefslogtreecommitdiffstats
path: root/source4
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2007-12-04 00:12:13 +0100
committerStefan Metzmacher <metze@samba.org>2007-12-21 05:48:01 +0100
commitb038240ac72fa34a132eb52bda28bbb80f82c29e (patch)
tree8870bbb7b50ce698806bc0f2210204b98e38c19a /source4
parentfc2f06d31b6b52c5cbd83f34a34e5107649a5134 (diff)
downloadsamba-b038240ac72fa34a132eb52bda28bbb80f82c29e.tar.gz
samba-b038240ac72fa34a132eb52bda28bbb80f82c29e.tar.xz
samba-b038240ac72fa34a132eb52bda28bbb80f82c29e.zip
r26275: return loadparm context in lp_load.
(This used to be commit d01f0f4c2037b531b3fd088060717f90e60471e9)
Diffstat (limited to 'source4')
-rw-r--r--source4/client/smbmount.c12
-rw-r--r--source4/client/smbspool.c5
-rw-r--r--source4/lib/cmdline/popt_common.c6
-rw-r--r--source4/param/loadparm.c10
-rw-r--r--source4/scripting/ejs/smbcalls_config.c4
-rw-r--r--source4/scripting/ejs/smbscript.c7
-rw-r--r--source4/torture/gentest.c9
-rw-r--r--source4/torture/locktest.c13
-rw-r--r--source4/torture/locktest2.c3
-rw-r--r--source4/torture/masktest.c9
-rw-r--r--source4/utils/testparm.c7
11 files changed, 51 insertions, 34 deletions
diff --git a/source4/client/smbmount.c b/source4/client/smbmount.c
index db16c6cf1f..907405535e 100644
--- a/source4/client/smbmount.c
+++ b/source4/client/smbmount.c
@@ -323,7 +323,8 @@ static void smb_umount(const char *mount_point)
* not exit after open_sockets() or send_login() errors,
* as the smbfs mount would then have no way to recover.
*/
-static void send_fs_socket(const char *the_service, const char *mount_point, struct smbcli_state *c)
+static void send_fs_socket(struct loadparm_context *lp_ctx,
+ const char *the_service, const char *mount_point, struct smbcli_state *c)
{
int fd, closed = 0, res = 1;
pid_t parentpid = getppid();
@@ -407,7 +408,7 @@ static void send_fs_socket(const char *the_service, const char *mount_point, str
pause();
DEBUG(2,("mount.smbfs[%d]: got signal, getting new socket\n", sys_getpid()));
c = do_connection(the_service,
- lp_unicode(global_loadparm),
+ lp_unicode(lp_ctx),
lp_cli_maxprotocol(global_loadparm));
}
}
@@ -529,7 +530,7 @@ static void init_mount(void)
for any reason, we will have to unmount the mount point. There
is no exit from the next call...
*/
- send_fs_socket(service, mount_point, c);
+ send_fs_socket(global_loadparm, service, mount_point, c);
}
@@ -852,6 +853,7 @@ static void parse_mount_smb(int argc, char **argv)
extern char *optarg;
extern int optind;
char *p;
+ struct loadparm_context *lp_ctx;
DEBUGLEVEL = 1;
@@ -882,7 +884,7 @@ static void parse_mount_smb(int argc, char **argv)
}
if (getenv("PASSWD")) {
- pstrcpy(password,getenv("PASSWD"));
+ pstrcpy(password, getenv("PASSWD"));
got_pass = true;
}
@@ -895,7 +897,7 @@ static void parse_mount_smb(int argc, char **argv)
pstrcpy(username,getenv("LOGNAME"));
}
- if (!lp_load(dyn_CONFIGFILE)) {
+ if (!lp_load(dyn_CONFIGFILE, &lp_ctx)) {
fprintf(stderr, "Can't load %s - run testparm to debug it\n",
lp_config_file());
}
diff --git a/source4/client/smbspool.c b/source4/client/smbspool.c
index 7270942037..6a7454b6b2 100644
--- a/source4/client/smbspool.c
+++ b/source4/client/smbspool.c
@@ -50,6 +50,7 @@ static int smb_print(struct smbcli_state *, char *, FILE *);
FILE *fp; /* File to print */
int status=0; /* Status of LPD job */
struct smbcli_state *cli; /* SMB interface */
+ struct loadparm_context *lp_ctx;
/* we expect the URI in argv[0]. Detect the case where it is in argv[1] and cope */
if (argc > 2 && strncmp(argv[0],"smb://", 6) && !strncmp(argv[1],"smb://", 6)) {
@@ -176,13 +177,13 @@ static int smb_print(struct smbcli_state *, char *, FILE *);
setup_logging(argv[0], DEBUG_STDOUT);
- if (!lp_load(dyn_CONFIGFILE)) {
+ if (!lp_load(dyn_CONFIGFILE, &lp_ctx)) {
fprintf(stderr, "ERROR: Can't load %s - run testparm to debug it\n", lp_config_file());
return (1);
}
if (workgroup == NULL)
- workgroup = lp_workgroup();
+ workgroup = lp_workgroup(lp_ctx);
do
{
diff --git a/source4/lib/cmdline/popt_common.c b/source4/lib/cmdline/popt_common.c
index 1c96bf64cf..1eeb611256 100644
--- a/source4/lib/cmdline/popt_common.c
+++ b/source4/lib/cmdline/popt_common.c
@@ -52,9 +52,9 @@ static void popt_common_callback(poptContext con,
if (reason == POPT_CALLBACK_REASON_POST) {
if (!lp_loaded()) {
if (getenv("SMB_CONF_PATH"))
- lp_load(getenv("SMB_CONF_PATH"));
+ lp_load(getenv("SMB_CONF_PATH"), NULL);
else
- lp_load(dyn_CONFIGFILE);
+ lp_load(dyn_CONFIGFILE, NULL);
}
/* Hook any 'every Samba program must do this, after
* the smb.conf is setup' functions here */
@@ -101,7 +101,7 @@ static void popt_common_callback(poptContext con,
case 's':
if (arg) {
- lp_load(arg);
+ lp_load(arg, NULL);
}
break;
diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c
index be5464c8e6..9065a48113 100644
--- a/source4/param/loadparm.c
+++ b/source4/param/loadparm.c
@@ -2407,7 +2407,7 @@ bool loadparm_init(struct loadparm_context *lp_ctx)
_PUBLIC_ _DEPRECATED_ bool lp_load_default(void)
{
- return lp_load(dyn_CONFIGFILE);
+ return lp_load(dyn_CONFIGFILE, NULL);
}
/***************************************************************************
@@ -2415,13 +2415,16 @@ _PUBLIC_ _DEPRECATED_ bool lp_load_default(void)
False on failure.
***************************************************************************/
-bool lp_load(const char *filename)
+bool lp_load(const char *filename, struct loadparm_context **ret_lp)
{
char *n2;
bool bRetval;
struct param_opt *data;
struct loadparm_context *lp_ctx = &loadparm;
+ if (ret_lp != NULL)
+ *ret_lp = NULL;
+
filename = talloc_strdup(talloc_autofree_context(), filename);
global_loadparm = lp_ctx;
@@ -2470,6 +2473,9 @@ bool lp_load(const char *filename)
close_iconv();
+ if (ret_lp != NULL)
+ *ret_lp = lp_ctx;
+
return bRetval;
}
diff --git a/source4/scripting/ejs/smbcalls_config.c b/source4/scripting/ejs/smbcalls_config.c
index 1c76757659..122d78ac20 100644
--- a/source4/scripting/ejs/smbcalls_config.c
+++ b/source4/scripting/ejs/smbcalls_config.c
@@ -187,7 +187,9 @@ static int ejs_lpSet(MprVarHandle eid, int argc, char **argv)
*/
static int ejs_lpReload(MprVarHandle eid, int argc, char **argv)
{
- bool ret = lp_load(lp_configfile(global_loadparm));
+ bool ret;
+
+ ret = lp_load(lp_configfile(global_loadparm), NULL);
if (ret) {
unload_interfaces();
}
diff --git a/source4/scripting/ejs/smbscript.c b/source4/scripting/ejs/smbscript.c
index db6e0eeb10..2bb67135ea 100644
--- a/source4/scripting/ejs/smbscript.c
+++ b/source4/scripting/ejs/smbscript.c
@@ -49,18 +49,19 @@ int main(int argc, const char **argv)
const char *fname;
struct MprVar *return_var;
int exit_status, i;
+ struct loadparm_context *lp_ctx;
fault_setup(argv[0]);
if (getenv("SMB_CONF_PATH")) {
- lp_load(getenv("SMB_CONF_PATH"));
+ lp_load(getenv("SMB_CONF_PATH"), &lp_ctx);
} else {
- lp_load(dyn_CONFIGFILE);
+ lp_load(dyn_CONFIGFILE, &lp_ctx);
}
ldb_global_init();
- gensec_init(global_loadparm);
+ gensec_init(lp_ctx);
mprSetCtx(mem_ctx);
diff --git a/source4/torture/gentest.c b/source4/torture/gentest.c
index fa352a3e9e..edc1b0754a 100644
--- a/source4/torture/gentest.c
+++ b/source4/torture/gentest.c
@@ -2172,6 +2172,7 @@ static bool split_unc_name(const char *unc, char **server, char **share)
int opt;
int i, username_count=0;
bool ret;
+ struct loadparm_context *lp_ctx;
setlinebuf(stdout);
@@ -2196,12 +2197,12 @@ static bool split_unc_name(const char *unc, char **server, char **share)
argc -= NSERVERS;
argv += NSERVERS;
- lp_load(dyn_CONFIGFILE);
+ lp_load(dyn_CONFIGFILE, &lp_ctx);
servers[0].credentials = cli_credentials_init(talloc_autofree_context());
servers[1].credentials = cli_credentials_init(talloc_autofree_context());
- cli_credentials_guess(servers[0].credentials, global_loadparm);
- cli_credentials_guess(servers[1].credentials, global_loadparm);
+ cli_credentials_guess(servers[0].credentials, lp_ctx);
+ cli_credentials_guess(servers[1].credentials, lp_ctx);
options.seed = time(NULL);
options.numops = 1000;
@@ -2265,7 +2266,7 @@ static bool split_unc_name(const char *unc, char **server, char **share)
}
}
- gensec_init(global_loadparm);
+ gensec_init(lp_ctx);
if (username_count == 0) {
usage();
diff --git a/source4/torture/locktest.c b/source4/torture/locktest.c
index 381abaebc6..2aa074c6c3 100644
--- a/source4/torture/locktest.c
+++ b/source4/torture/locktest.c
@@ -543,6 +543,7 @@ static void usage(void)
int opt;
int seed, server;
int username_count=0;
+ struct loadparm_context *lp_ctx;
setlinebuf(stdout);
@@ -563,12 +564,12 @@ static void usage(void)
argc -= NSERVERS;
argv += NSERVERS;
- lp_load(dyn_CONFIGFILE);
+ lp_load(dyn_CONFIGFILE, &lp_ctx);
servers[0] = cli_credentials_init(talloc_autofree_context());
servers[1] = cli_credentials_init(talloc_autofree_context());
- cli_credentials_guess(servers[0], global_loadparm);
- cli_credentials_guess(servers[1], global_loadparm);
+ cli_credentials_guess(servers[0], lp_ctx);
+ cli_credentials_guess(servers[1], lp_ctx);
seed = time(NULL);
@@ -617,10 +618,10 @@ static void usage(void)
exact_error_codes = true;
break;
case 'l':
- lp_set_cmdline(global_loadparm, "torture:unclist", optarg);
+ lp_set_cmdline(lp_ctx, "torture:unclist", optarg);
break;
case 'W':
- lp_set_cmdline(global_loadparm, "workgroup", optarg);
+ lp_set_cmdline(lp_ctx, "workgroup", optarg);
break;
case 'h':
usage();
@@ -639,7 +640,7 @@ static void usage(void)
servers[1] = servers[0];
}
- gensec_init(global_loadparm);
+ gensec_init(lp_ctx);
argc -= optind;
argv += optind;
diff --git a/source4/torture/locktest2.c b/source4/torture/locktest2.c
index 55edd4aa17..1798e485ea 100644
--- a/source4/torture/locktest2.c
+++ b/source4/torture/locktest2.c
@@ -460,6 +460,7 @@ static void usage(void)
int opt;
char *p;
int seed;
+ struct loadparm_context *lp_ctx;
setlinebuf(stdout);
@@ -483,7 +484,7 @@ static void usage(void)
argc -= 4;
argv += 4;
- lp_load(dyn_CONFIGFILE);
+ lp_load(dyn_CONFIGFILE, &lp_ctx);
if (getenv("USER")) {
fstrcpy(username,getenv("USER"));
diff --git a/source4/torture/masktest.c b/source4/torture/masktest.c
index 2b3c92db0c..2455361e10 100644
--- a/source4/torture/masktest.c
+++ b/source4/torture/masktest.c
@@ -281,6 +281,7 @@ static void usage(void)
struct smbcli_state *cli;
int opt;
int seed;
+ struct loadparm_context *lp_ctx;
setlinebuf(stdout);
@@ -302,10 +303,10 @@ static void usage(void)
argc -= 1;
argv += 1;
- lp_load(dyn_CONFIGFILE);
+ lp_load(dyn_CONFIGFILE, &lp_ctx);
credentials = cli_credentials_init(talloc_autofree_context());
- cli_credentials_guess(credentials, global_loadparm);
+ cli_credentials_guess(credentials, lp_ctx);
seed = time(NULL);
@@ -326,7 +327,7 @@ static void usage(void)
verbose++;
break;
case 'M':
- lp_set_cmdline(global_loadparm, "max protocol", optarg);
+ lp_set_cmdline(lp_ctx, "max protocol", optarg);
break;
case 'U':
cli_credentials_parse_string(credentials, optarg, CRED_SPECIFIED);
@@ -358,7 +359,7 @@ static void usage(void)
}
}
- gensec_init(global_loadparm);
+ gensec_init(lp_ctx);
argc -= optind;
argv += optind;
diff --git a/source4/utils/testparm.c b/source4/utils/testparm.c
index 665c649e73..b9e6bc0595 100644
--- a/source4/utils/testparm.c
+++ b/source4/utils/testparm.c
@@ -184,6 +184,7 @@ static int do_share_checks(struct loadparm_context *lp_ctx, const char *cname, c
static const char *cname;
static const char *caddr;
static bool show_defaults = false;
+ struct loadparm_context *lp_ctx;
struct poptOption long_options[] = {
POPT_AUTOHELP
@@ -238,15 +239,15 @@ static int do_share_checks(struct loadparm_context *lp_ctx, const char *cname, c
fprintf(stderr, "Loaded smb config files from %s\n", lp_configfile(global_loadparm));
- if (!lp_load(lp_configfile(global_loadparm))) {
+ if (!lp_load(lp_configfile(global_loadparm), &lp_ctx)) {
fprintf(stderr,"Error loading services.\n");
return(1);
}
fprintf(stderr,"Loaded services file OK.\n");
- ret = do_global_checks(global_loadparm);
- ret |= do_share_checks(global_loadparm, cname, caddr, silent_mode, show_defaults, section_name, parameter_name);
+ ret = do_global_checks(lp_ctx);
+ ret |= do_share_checks(lp_ctx, cname, caddr, silent_mode, show_defaults, section_name, parameter_name);
return(ret);
}
-------------------------------- Portions of this software may have been derived from OpenBSD or other sources, and are covered by the appropriate copyright disclaimers included herein. ------------------------------------------- ####BSDCOPYRIGHTEND#### ========================================================================== #####DESCRIPTIONBEGIN#### Author(s): gthomas Contributors: gthomas, jskov, rsandifo Date: 2001-06-13 Purpose: Description: FIXME: Will fail if pinged with large packets (1520 bytes) Add promisc config Add SNMP ####DESCRIPTIONEND#### ========================================================================== */ #include <common.h> #include <command.h> #include <net.h> #include <malloc.h> #include <linux/compiler.h> /* forward definition of function used for the uboot interface */ void uboot_push_packet_len(int len); void uboot_push_tx_done(int key, int val); /* NE2000 base header file */ #include "ne2000_base.h" #if defined(CONFIG_DRIVER_AX88796L) /* AX88796L support */ #include "ax88796.h" #else /* Basic NE2000 chip support */ #include "ne2000.h" #endif static dp83902a_priv_data_t nic; /* just one instance of the card supported */ /** * This function reads the MAC address from the serial EEPROM, * used if PROM read fails. Does nothing for ax88796 chips (sh boards) */ static bool dp83902a_init(unsigned char *enetaddr) { dp83902a_priv_data_t *dp = &nic; u8* base; #if defined(NE2000_BASIC_INIT) int i; #endif DEBUG_FUNCTION(); base = dp->base; if (!base) return false; /* No device found */ DEBUG_LINE(); #if defined(NE2000_BASIC_INIT) /* AX88796L doesn't need */ /* Prepare ESA */ DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1); /* Select page 1 */ /* Use the address from the serial EEPROM */ for (i = 0; i < 6; i++) DP_IN(base, DP_P1_PAR0+i, dp->esa[i]); DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0); /* Select page 0 */ printf("NE2000 - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n", "eeprom", dp->esa[0], dp->esa[1], dp->esa[2], dp->esa[3], dp->esa[4], dp->esa[5] ); memcpy(enetaddr, dp->esa, 6); /* Use MAC from serial EEPROM */ #endif /* NE2000_BASIC_INIT */ return true; } static void dp83902a_stop(void) { dp83902a_priv_data_t *dp = &nic; u8 *base = dp->base; DEBUG_FUNCTION(); DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */ DP_OUT(base, DP_ISR, 0xFF); /* Clear any pending interrupts */ DP_OUT(base, DP_IMR, 0x00); /* Disable all interrupts */ dp->running = false; } /* * This function is called to "start up" the interface. It may be called * multiple times, even when the hardware is already running. It will be * called whenever something "hardware oriented" changes and should leave * the hardware ready to send/receive packets. */ static void dp83902a_start(u8 * enaddr) { dp83902a_priv_data_t *dp = &nic; u8 *base = dp->base; int i; debug("The MAC is %pM\n", enaddr); DEBUG_FUNCTION(); DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */ DP_OUT(base, DP_DCR, DP_DCR_INIT); DP_OUT(base, DP_RBCH, 0); /* Remote byte count */ DP_OUT(base, DP_RBCL, 0); DP_OUT(base, DP_RCR, DP_RCR_MON); /* Accept no packets */ DP_OUT(base, DP_TCR, DP_TCR_LOCAL); /* Transmitter [virtually] off */ DP_OUT(base, DP_TPSR, dp->tx_buf1); /* Transmitter start page */ dp->tx1 = dp->tx2 = 0; dp->tx_next = dp->tx_buf1; dp->tx_started = false; dp->running = true; DP_OUT(base, DP_PSTART, dp->rx_buf_start); /* Receive ring start page */ DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); /* Receive ring boundary */ DP_OUT(base, DP_PSTOP, dp->rx_buf_end); /* Receive ring end page */ dp->rx_next = dp->rx_buf_start - 1; dp->running = true; DP_OUT(base, DP_ISR, 0xFF); /* Clear any pending interrupts */ DP_OUT(base, DP_IMR, DP_IMR_All); /* Enable all interrupts */ DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1 | DP_CR_STOP); /* Select page 1 */ DP_OUT(base, DP_P1_CURP, dp->rx_buf_start); /* Current page - next free page for Rx */ dp->running = true; for (i = 0; i < ETHER_ADDR_LEN; i++) { /* FIXME */ /*((vu_short*)( base + ((DP_P1_PAR0 + i) * 2) + * 0x1400)) = enaddr[i];*/ DP_OUT(base, DP_P1_PAR0+i, enaddr[i]); } /* Enable and start device */ DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); DP_OUT(base, DP_TCR, DP_TCR_NORMAL); /* Normal transmit operations */ DP_OUT(base, DP_RCR, DP_RCR_AB); /* Accept broadcast, no errors, no multicast */ dp->running = true; } /* * This routine is called to start the transmitter. It is split out from the * data handling routine so it may be called either when data becomes first * available or when an Tx interrupt occurs */ static void dp83902a_start_xmit(int start_page, int len) { dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *) &nic; u8 *base = dp->base; DEBUG_FUNCTION(); #if DEBUG & 1 printf("Tx pkt %d len %d\n", start_page, len); if (dp->tx_started) printf("TX already started?!?\n"); #endif DP_OUT(base, DP_ISR, (DP_ISR_TxP | DP_ISR_TxE)); DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); DP_OUT(base, DP_TBCL, len & 0xFF); DP_OUT(base, DP_TBCH, len >> 8); DP_OUT(base, DP_TPSR, start_page); DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START); dp->tx_started = true; } /* * This routine is called to send data to the hardware. It is known a-priori * that there is free buffer space (dp->tx_next). */ static void dp83902a_send(u8 *data, int total_len, u32 key) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; u8 *base = dp->base; int len, start_page, pkt_len, i, isr; #if DEBUG & 4 int dx; #endif DEBUG_FUNCTION(); len = pkt_len = total_len; if (pkt_len < IEEE_8023_MIN_FRAME) pkt_len = IEEE_8023_MIN_FRAME; start_page = dp->tx_next; if (dp->tx_next == dp->tx_buf1) { dp->tx1 = start_page; dp->tx1_len = pkt_len; dp->tx1_key = key; dp->tx_next = dp->tx_buf2; } else { dp->tx2 = start_page; dp->tx2_len = pkt_len; dp->tx2_key = key; dp->tx_next = dp->tx_buf1; } #if DEBUG & 5 printf("TX prep page %d len %d\n", start_page, pkt_len); #endif DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */ { /* * Dummy read. The manual sez something slightly different, * but the code is extended a bit to do what Hitachi's monitor * does (i.e., also read data). */ __maybe_unused u16 tmp; int len = 1; DP_OUT(base, DP_RSAL, 0x100 - len); DP_OUT(base, DP_RSAH, (start_page - 1) & 0xff); DP_OUT(base, DP_RBCL, len); DP_OUT(base, DP_RBCH, 0); DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_RDMA | DP_CR_START); DP_IN_DATA(dp->data, tmp); } #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA /* * Stall for a bit before continuing to work around random data * corruption problems on some platforms. */ CYGACC_CALL_IF_DELAY_US(1); #endif /* Send data to device buffer(s) */ DP_OUT(base, DP_RSAL, 0); DP_OUT(base, DP_RSAH, start_page); DP_OUT(base, DP_RBCL, pkt_len & 0xFF); DP_OUT(base, DP_RBCH, pkt_len >> 8); DP_OUT(base, DP_CR, DP_CR_WDMA | DP_CR_START); /* Put data into buffer */ #if DEBUG & 4 printf(" sg buf %08lx len %08x\n ", (u32)data, len); dx = 0; #endif while (len > 0) { #if DEBUG & 4 printf(" %02x", *data); if (0 == (++dx % 16)) printf("\n "); #endif DP_OUT_DATA(dp->data, *data++); len--; } #if DEBUG & 4 printf("\n"); #endif if (total_len < pkt_len) { #if DEBUG & 4 printf(" + %d bytes of padding\n", pkt_len - total_len); #endif /* Padding to 802.3 length was required */ for (i = total_len; i < pkt_len;) { i++; DP_OUT_DATA(dp->data, 0); } } #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA /* * After last data write, delay for a bit before accessing the * device again, or we may get random data corruption in the last * datum (on some platforms). */ CYGACC_CALL_IF_DELAY_US(1); #endif /* Wait for DMA to complete */ do { DP_IN(base, DP_ISR, isr); } while ((isr & DP_ISR_RDC) == 0); /* Then disable DMA */ DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); /* Start transmit if not already going */ if (!dp->tx_started) { if (start_page == dp->tx1) { dp->tx_int = 1; /* Expecting interrupt from BUF1 */ } else { dp->tx_int = 2; /* Expecting interrupt from BUF2 */ } dp83902a_start_xmit(start_page, pkt_len); } } /* * This function is called when a packet has been received. It's job is * to prepare to unload the packet from the hardware. Once the length of * the packet is known, the upper layer of the driver can be told. When * the upper layer is ready to unload the packet, the internal function * 'dp83902a_recv' will be called to actually fetch it from the hardware. */ static void dp83902a_RxEvent(void) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; u8 *base = dp->base; __maybe_unused u8 rsr; u8 rcv_hdr[4]; int i, len, pkt, cur; DEBUG_FUNCTION(); DP_IN(base, DP_RSR, rsr); while (true) { /* Read incoming packet header */ DP_OUT(base, DP_CR, DP_CR_PAGE1 | DP_CR_NODMA | DP_CR_START); DP_IN(base, DP_P1_CURP, cur); DP_OUT(base, DP_P1_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); DP_IN(base, DP_BNDRY, pkt); pkt += 1; if (pkt == dp->rx_buf_end) pkt = dp->rx_buf_start; if (pkt == cur) { break; } DP_OUT(base, DP_RBCL, sizeof(rcv_hdr)); DP_OUT(base, DP_RBCH, 0); DP_OUT(base, DP_RSAL, 0); DP_OUT(base, DP_RSAH, pkt); if (dp->rx_next == pkt) { if (cur == dp->rx_buf_start) DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); else DP_OUT(base, DP_BNDRY, cur - 1); /* Update pointer */ return; } dp->rx_next = pkt; DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */ DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START); #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA CYGACC_CALL_IF_DELAY_US(10); #endif /* read header (get data size)*/ for (i = 0; i < sizeof(rcv_hdr);) { DP_IN_DATA(dp->data, rcv_hdr[i++]); } #if DEBUG & 5 printf("rx hdr %02x %02x %02x %02x\n", rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]); #endif len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr); /* data read */ uboot_push_packet_len(len); if (rcv_hdr[1] == dp->rx_buf_start) DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); else DP_OUT(base, DP_BNDRY, rcv_hdr[1] - 1); /* Update pointer */ } } /* * This function is called as a result of the "eth_drv_recv()" call above. * It's job is to actually fetch data for a packet from the hardware once * memory buffers have been allocated for the packet. Note that the buffers * may come in pieces, using a scatter-gather list. This allows for more * efficient processing in the upper layers of the stack. */ static void dp83902a_recv(u8 *data, int len) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; u8 *base = dp->base; int i, mlen; u8 saved_char = 0; bool saved; #if DEBUG & 4 int dx; #endif DEBUG_FUNCTION(); #if DEBUG & 5 printf("Rx packet %d length %d\n", dp->rx_next, len); #endif /* Read incoming packet data */ DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); DP_OUT(base, DP_RBCL, len & 0xFF); DP_OUT(base, DP_RBCH, len >> 8); DP_OUT(base, DP_RSAL, 4); /* Past header */ DP_OUT(base, DP_RSAH, dp->rx_next); DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */ DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START); #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA CYGACC_CALL_IF_DELAY_US(10); #endif saved = false; for (i = 0; i < 1; i++) { if (data) { mlen = len; #if DEBUG & 4 printf(" sg buf %08lx len %08x \n", (u32) data, mlen); dx = 0; #endif while (0 < mlen) { /* Saved byte from previous loop? */ if (saved) { *data++ = saved_char; mlen--; saved = false; continue; } { u8 tmp; DP_IN_DATA(dp->data, tmp); #if DEBUG & 4 printf(" %02x", tmp); if (0 == (++dx % 16)) printf("\n "); #endif *data++ = tmp;; mlen--; } } #if DEBUG & 4 printf("\n"); #endif } } } static void dp83902a_TxEvent(void) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; u8 *base = dp->base; __maybe_unused u8 tsr; u32 key; DEBUG_FUNCTION(); DP_IN(base, DP_TSR, tsr); if (dp->tx_int == 1) { key = dp->tx1_key; dp->tx1 = 0; } else { key = dp->tx2_key; dp->tx2 = 0; } /* Start next packet if one is ready */ dp->tx_started = false; if (dp->tx1) { dp83902a_start_xmit(dp->tx1, dp->tx1_len); dp->tx_int = 1; } else if (dp->tx2) { dp83902a_start_xmit(dp->tx2, dp->tx2_len); dp->tx_int = 2; } else { dp->tx_int = 0; } /* Tell higher level we sent this packet */ uboot_push_tx_done(key, 0); } /* * Read the tally counters to clear them. Called in response to a CNT * interrupt. */ static void dp83902a_ClearCounters(void) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; u8 *base = dp->base; __maybe_unused u8 cnt1, cnt2, cnt3; DP_IN(base, DP_FER, cnt1); DP_IN(base, DP_CER, cnt2); DP_IN(base, DP_MISSED, cnt3); DP_OUT(base, DP_ISR, DP_ISR_CNT); } /* * Deal with an overflow condition. This code follows the procedure set * out in section 7.0 of the datasheet. */ static void dp83902a_Overflow(void) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)&nic; u8 *base = dp->base; u8 isr; /* Issue a stop command and wait 1.6ms for it to complete. */ DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA); CYGACC_CALL_IF_DELAY_US(1600); /* Clear the remote byte counter registers. */ DP_OUT(base, DP_RBCL, 0); DP_OUT(base, DP_RBCH, 0); /* Enter loopback mode while we clear the buffer. */ DP_OUT(base, DP_TCR, DP_TCR_LOCAL); DP_OUT(base, DP_CR, DP_CR_START | DP_CR_NODMA); /* * Read in as many packets as we can and acknowledge any and receive * interrupts. Since the buffer has overflowed, a receive event of * some kind will have occured. */ dp83902a_RxEvent(); DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE); /* Clear the overflow condition and leave loopback mode. */ DP_OUT(base, DP_ISR, DP_ISR_OFLW); DP_OUT(base, DP_TCR, DP_TCR_NORMAL); /* * If a transmit command was issued, but no transmit event has occured, * restart it here. */ DP_IN(base, DP_ISR, isr); if (dp->tx_started && !(isr & (DP_ISR_TxP|DP_ISR_TxE))) { DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START); } } static void dp83902a_poll(void) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; u8 *base = dp->base; u8 isr; DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0 | DP_CR_START); DP_IN(base, DP_ISR, isr); while (0 != isr) { /* * The CNT interrupt triggers when the MSB of one of the error * counters is set. We don't much care about these counters, but * we should read their values to reset them. */ if (isr & DP_ISR_CNT) { dp83902a_ClearCounters(); } /* * Check for overflow. It's a special case, since there's a * particular procedure that must be followed to get back into * a running state.a */ if (isr & DP_ISR_OFLW) { dp83902a_Overflow(); } else { /* * Other kinds of interrupts can be acknowledged simply by * clearing the relevant bits of the ISR. Do that now, then * handle the interrupts we care about. */ DP_OUT(base, DP_ISR, isr); /* Clear set bits */ if (!dp->running) break; /* Is this necessary? */ /* * Check for tx_started on TX event since these may happen * spuriously it seems. */ if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) { dp83902a_TxEvent(); } if (isr & (DP_ISR_RxP|DP_ISR_RxE)) { dp83902a_RxEvent(); } } DP_IN(base, DP_ISR, isr); } } /* U-Boot specific routines */ static u8 *pbuf = NULL; static int pkey = -1; static int initialized = 0; void uboot_push_packet_len(int len) { PRINTK("pushed len = %d\n", len); if (len >= 2000) { printf("NE2000: packet too big\n"); return; } dp83902a_recv(&pbuf[0], len); /*Just pass it to the upper layer*/ net_process_received_packet(&pbuf[0], len); } void uboot_push_tx_done(int key, int val) { PRINTK("pushed key = %d\n", key); pkey = key; } /** * Setup the driver and init MAC address according to doc/README.enetaddr * Called by ne2k_register() before registering the driver @eth layer * * @param struct ethdevice of this instance of the driver for dev->enetaddr * @return 0 on success, -1 on error (causing caller to print error msg) */ static int ne2k_setup_driver(struct eth_device *dev) { PRINTK("### ne2k_setup_driver\n"); if (!pbuf) { pbuf = malloc(2000); if (!pbuf) { printf("Cannot allocate rx buffer\n"); return -1; } } #ifdef CONFIG_DRIVER_NE2000_CCR { vu_char *p = (vu_char *) CONFIG_DRIVER_NE2000_CCR; PRINTK("CCR before is %x\n", *p); *p = CONFIG_DRIVER_NE2000_VAL; PRINTK("CCR after is %x\n", *p); } #endif nic.base = (u8 *) CONFIG_DRIVER_NE2000_BASE; nic.data = nic.base + DP_DATA; nic.tx_buf1 = START_PG; nic.tx_buf2 = START_PG2; nic.rx_buf_start = RX_START; nic.rx_buf_end = RX_END; /* * According to doc/README.enetaddr, drivers shall give priority * to the MAC address value in the environment, so we do not read * it from the prom or eeprom if it is specified in the environment. */ if (!eth_getenv_enetaddr("ethaddr", dev->enetaddr)) { /* If the MAC address is not in the environment, get it: */ if (!get_prom(dev->enetaddr, nic.base)) /* get MAC from prom */ dp83902a_init(dev->enetaddr); /* fallback: seeprom */ /* And write it into the environment otherwise eth_write_hwaddr * returns -1 due to eth_getenv_enetaddr_by_index() failing, * and this causes "Warning: failed to set MAC address", and * cmd_bdinfo has no ethaddr value which it can show: */ eth_setenv_enetaddr("ethaddr", dev->enetaddr); } return 0; } static int ne2k_init(struct eth_device *dev, bd_t *bd) { dp83902a_start(dev->enetaddr); initialized = 1; return 0; } static void ne2k_halt(struct eth_device *dev) { debug("### ne2k_halt\n"); if(initialized) dp83902a_stop(); initialized = 0; } static int ne2k_recv(struct eth_device *dev) { dp83902a_poll(); return 1; } static int ne2k_send(struct eth_device *dev, void *packet, int length) { int tmo; debug("### ne2k_send\n"); pkey = -1; dp83902a_send((u8 *) packet, length, 666); tmo = get_timer (0) + TOUT * CONFIG_SYS_HZ; while(1) { dp83902a_poll(); if (pkey != -1) { PRINTK("Packet sucesfully sent\n"); return 0; } if (get_timer (0) >= tmo) { printf("transmission error (timoeut)\n"); return 0; } } return 0; } /** * Setup the driver for use and register it with the eth layer * @return 0 on success, -1 on error (causing caller to print error msg) */ int ne2k_register(void) { struct eth_device *dev; dev = calloc(sizeof(*dev), 1); if (dev == NULL) return -1; if (ne2k_setup_driver(dev)) return -1; dev->init = ne2k_init; dev->halt = ne2k_halt; dev->send = ne2k_send; dev->recv = ne2k_recv; strcpy(dev->name, "NE2000"); return eth_register(dev); }