@@ -42,6 +42,7 @@ struct boot_fspec_t {
char* siaddr; /* Server address */
char* file; /* File path */
char* ciaddr; /* Client address */
+ char* yiaddr; /* Client address filled in by server*/
char* giaddr; /* Gateway address */
char* bootp_retries; /* Bootp retries */
char* tftp_retries; /* TFTP retries */
@@ -81,5 +82,6 @@ extern int
parse_device_path(char *imagepath, char *defdevice, int defpart,
char *deffile, struct boot_fspec_t *result);
+int bootp_to_fspec(struct bootp_packet *,struct boot_fspec_t *);
#endif
@@ -61,6 +61,40 @@ scopy(char **dest, char **source)
return ret;
}
+#define IPLEN 16
+/*Return ip in xxx.xxx.xxx.xxx string format*/
+
+static char * ipv4_to_str( u32 ip)
+{
+ char * buf = malloc(IPLEN);
+ sprintf(buf,"%u.%u.%u.%u",
+ (ip & 0xff000000) >> 24,
+ (ip & 0x00ff0000) >> 16,
+ (ip & 0x0000ff00) >> 8,
+ (ip & 0x000000ff));
+ return buf;
+}
+
+/*Puts the IP information on boot_packet struct in boot_fspec_t struct
+ * return 1 in success and 0 on fail*/
+int bootp_to_fspec(struct bootp_packet *packet,struct boot_fspec_t *fspec){
+
+ if (packet == NULL || fspec == NULL)
+ return 0;
+
+ fspec->siaddr=ipv4_to_str(packet->siaddr);
+ fspec->ciaddr=ipv4_to_str(packet->ciaddr);
+ fspec->giaddr=ipv4_to_str(packet->giaddr);
+ fspec->yiaddr=ipv4_to_str(packet->yiaddr);
+ DEBUG_F("siaddr = <%s>\n",fspec->siaddr);
+ DEBUG_F("ciaddr = <%s>\n",fspec->ciaddr);
+ DEBUG_F("giaddr = <%s>\n",fspec->giaddr);
+ DEBUG_F("yiaddr = <%s>\n",fspec->yiaddr);
+
+ return 1;
+}
+
+
/*
* Extract all the ipv4 arguments from the bootpath provided and fill result
* Returns 1 on success, 0 on failure.
@@ -46,7 +46,7 @@
#define LOAD_BUFFER_POS 0x00000000
#define LOAD_BUFFER_SIZE 0x01000000
-
+extern int net_type;
static int of_open(struct boot_file_t* file,
struct partition_t* part, struct boot_fspec_t* fspec);
static int of_read(struct boot_file_t* file, unsigned int size, void* buffer);
@@ -137,38 +137,58 @@ of_net_open(struct boot_file_t* file,
static char buffer[1024];
char *filename = NULL;
char *p;
-
+ struct bootp_packet *packet;
DEBUG_ENTER;
DEBUG_OPEN;
+/*Newer IBM firmware needs the server ip, client ip and the desired file to be
+ * set in the buffer, thus broken previus Yaboot network boot.
+ *
+ * The format is <device>:<interfaceoption,interfaceoption,>tftpserver,filename,client,gateway,bootp-retry,tftp-retry,netmask,tftp-blocksize
+ */
+
+ if (net_type){//Use new firmware network interface
+ packet = prom_get_netinfo();
+ if(packet)
+ bootp_to_fspec(packet,fspec);
+ }else
+ strcpy(fspec->yiaddr,fspec->ciaddr);
+
if (fspec->file && strlen(fspec->file)) {
filename = strdup(fspec->file);
for (p = filename; *p; p++)
if (*p == '/')
*p = '\\';
}
-
+
DEBUG_F("siaddr <%s>; filename <%s>; ciaddr <%s>; giaddr <%s>; ipv6 <%d>\n",
fspec->siaddr, filename, fspec->ciaddr, fspec->giaddr, fspec->is_ipv6);
- strncpy(buffer, fspec->dev, 768);
- if (fspec->is_ipv6)
- strcat(buffer, TOK_IPV6 ",");
- strcat(buffer, fspec->siaddr);
- strcat(buffer, ",");
- if (fspec->is_ipv6 && (strstr(filename, "filename=") == NULL))
- strcat(buffer, "filename=");
- strcat(buffer, filename);
- strcat(buffer, ",");
- strcat(buffer, fspec->ciaddr);
- strcat(buffer, ",");
- strcat(buffer, fspec->giaddr);
- strcat(buffer, ",");
- strcat(buffer, fspec->bootp_retries);
- strcat(buffer, ",");
- strcat(buffer, fspec->tftp_retries);
- strcat(buffer, ",");
- strcat(buffer, fspec->addl_params);
-
+ if(net_type){
+ strncpy(buffer, fspec->dev, 768);
+ if (fspec->is_ipv6)
+ strcat(buffer, TOK_IPV6 ",");
+ strcat(buffer, fspec->siaddr);
+ strcat(buffer, ",");
+ if (fspec->is_ipv6 && (strstr(filename, "filename=") == NULL))
+ strcat(buffer, "filename=");
+ strcat(buffer, filename);
+ strcat(buffer, ",");
+ strcat(buffer, fspec->yiaddr);
+ strcat(buffer, ",");
+ strcat(buffer, fspec->giaddr);
+ strcat(buffer, ",");
+ strcat(buffer, fspec->bootp_retries);
+ strcat(buffer, ",");
+ strcat(buffer, fspec->tftp_retries);
+ strcat(buffer, ",");
+ strcat(buffer, fspec->addl_params);
+ }
+ else{
+
+ strncpy(buffer, fspec->dev, (int)strchr(fspec->dev,':'));
+ strcat(buffer, ",");
+ strcat(buffer, filename);
+ }
DEBUG_F("Opening: \"%s\"\n", buffer);
file->of_device = prom_open(buffer);
@@ -121,7 +121,7 @@ char *password = NULL;
struct boot_fspec_t boot;
int _machine = _MACH_Pmac;
int flat_vmlinux;
-
+int net_type = 0;//type of net interface
#ifdef CONFIG_COLOR_TEXT
/* Color values for text ui */
@@ -183,7 +183,7 @@ yaboot_start (unsigned long r3, unsigned
void* malloc_base = NULL;
unsigned long addr;
prom_handle root;
-
+ ihandle promnet;
/* OF seems to do it, but I'm not very confident */
memset(&__bss_start, 0, &_end - &__bss_start);
@@ -237,6 +237,11 @@ yaboot_start (unsigned long r3, unsigned
!strncmp(model, "IBM", 3))
_machine = _MACH_chrp;
}
+
+ if (prom_getprop(root, "ibm,fw-net-compatibility",&promnet, sizeof(ihandle)) > 0)
+ net_type = 1;
+
+
}
DEBUG_F("Running on _machine = %d\n", _machine);
@@ -469,7 +474,8 @@ static int load_my_config_file(struct bo
char *cfgpath = (_machine == _MACH_chrp || _machine == _MACH_bplan) ? "/etc/" : "";
int flen;
int minlen;
-
+ char *macaddress;
+
packet = prom_get_netinfo();
if (!packet)
return rc;
@@ -483,10 +489,16 @@ static int load_my_config_file(struct bo
fspec.file = malloc(packet->hlen * 3 + 2 + 6);
if (!fspec.file)
goto out;
-
- sprintf(fspec.file, "%s%02x-", cfgpath, packet->htype);
- strcat(fspec.file, prom_get_mac(packet));
-
+
+ if (net_type){
+ macaddress = prom_get_mac(packet);
+ fspec.file = malloc(strlen(CONFIG_FILE_NAME) + strlen(macaddress) + 1 );
+ sprintf(fspec.file,"%s-%s" ,CONFIG_FILE_NAME,macaddress);// bootp_to_fspec(packet,fspec);
+ }
+ else{
+ sprintf(fspec.file, "%s%02x-", cfgpath, packet->htype);
+ strcat(fspec.file, prom_get_mac(packet));
+ }
rc = load_config_file(&fspec);
if (rc)
goto out;