Data Structures | |
| struct | s_PXENV_UNDI_TBD |
| A transmit buffer descriptor, as pointed to by s_PXENV_UNDI_TRANSMIT::TBD. More... | |
| struct | s_PXENV_UNDI_TRANSMIT |
| Parameter block for pxenv_undi_transmit(). More... | |
Defines | |
| #define | PXENV_UNDI_TRANSMIT 0x0008 |
| PXE API function code for pxenv_undi_transmit(). | |
| #define | P_UNKNOWN 0 |
| Media header already filled in. | |
| #define | P_IP 1 |
| IP protocol. | |
| #define | P_ARP 2 |
| ARP protocol. | |
| #define | P_RARP 3 |
| RARP protocol. | |
| #define | P_OTHER 4 |
| Other protocol. | |
| #define | XMT_DESTADDR 0x0000 |
| Unicast packet. | |
| #define | XMT_BROADCAST 0x0001 |
| Broadcast packet. | |
| #define | MAX_DATA_BLKS 8 |
| Maximum number of data blocks in a transmit buffer descriptor. | |
Typedefs | |
| typedef struct s_PXENV_UNDI_TBD | PXENV_UNDI_TBD_t |
| typedef struct s_PXENV_UNDI_TRANSMIT | PXENV_UNDI_TRANSMIT_t |
Functions | |
| PXENV_EXIT_t | pxenv_undi_transmit (struct s_PXENV_UNDI_TRANSMIT *undi_transmit) |
| #define PXENV_UNDI_TRANSMIT 0x0008 |
PXE API function code for pxenv_undi_transmit().
Definition at line 1060 of file pxe_api.h.
Referenced by pxe_api_call(), pxeparent_function_name(), and undinet_transmit().
| #define P_UNKNOWN 0 |
Media header already filled in.
Definition at line 1062 of file pxe_api.h.
Referenced by pxenv_undi_isr(), and pxenv_undi_transmit().
| #define P_IP 1 |
IP protocol.
Definition at line 1063 of file pxe_api.h.
Referenced by pxenv_undi_isr(), and pxenv_undi_transmit().
| #define P_ARP 2 |
ARP protocol.
Definition at line 1064 of file pxe_api.h.
Referenced by pxenv_undi_isr(), and pxenv_undi_transmit().
| #define P_RARP 3 |
RARP protocol.
Definition at line 1065 of file pxe_api.h.
Referenced by pxenv_undi_isr(), and pxenv_undi_transmit().
| #define XMT_DESTADDR 0x0000 |
Unicast packet.
Definition at line 1068 of file pxe_api.h.
Referenced by pxenv_undi_isr(), and pxenv_undi_transmit().
| #define MAX_DATA_BLKS 8 |
| typedef struct s_PXENV_UNDI_TBD PXENV_UNDI_TBD_t |
| typedef struct s_PXENV_UNDI_TRANSMIT PXENV_UNDI_TRANSMIT_t |
| PXENV_EXIT_t pxenv_undi_transmit | ( | struct s_PXENV_UNDI_TRANSMIT * | undi_transmit | ) |
Definition at line 222 of file pxe_undi.c.
References alloc_iob(), arp_protocol, copy_from_real, s_PXENV_UNDI_TBD::DataBlkCount, s_PXENV_UNDI_TBD::DataBlock, DBG2, s_PXENV_UNDI_TRANSMIT::DestAddr, free_iob(), s_PXENV_UNDI_TBD::ImmedLength, iob_put, iob_reserve, ipv4_protocol, net_device::ll_addr, ll_protocol::ll_addr_len, net_device::ll_broadcast, ll_protocol::ll_header_len, net_device::ll_protocol, MAX_LL_ADDR_LEN, net_protocol::name, net_protocol::net_proto, netdev_irq(), netdev_tx(), ll_protocol::ntoa, NULL, s_SEGOFF16::offset, P_ARP, P_IP, P_RARP, P_UNKNOWN, s_PXENV_UNDI_TRANSMIT::Protocol, ll_protocol::push, PXENV_EXIT_FAILURE, PXENV_EXIT_SUCCESS, PXENV_STATUS, PXENV_STATUS_OUT_OF_RESOURCES, PXENV_STATUS_SUCCESS, PXENV_STATUS_UNDI_INVALID_PARAMETER, rarp_protocol, s_SEGOFF16::segment, s_PXENV_UNDI_TRANSMIT::Status, strerror(), s_PXENV_UNDI_TRANSMIT::TBD, s_PXENV_UNDI_TBD::DataBlk::TDDataLen, undi_tx_count, s_PXENV_UNDI_TBD::Xmit, s_PXENV_UNDI_TRANSMIT::XmitFlag, and XMT_DESTADDR.
Referenced by pxe_api_call().
00223 { 00224 struct s_PXENV_UNDI_TBD tbd; 00225 struct DataBlk *datablk; 00226 struct io_buffer *iobuf; 00227 struct net_protocol *net_protocol; 00228 struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol; 00229 char destaddr[MAX_LL_ADDR_LEN]; 00230 const void *ll_dest; 00231 size_t ll_hlen = ll_protocol->ll_header_len; 00232 size_t len; 00233 unsigned int i; 00234 int rc; 00235 00236 DBG2 ( "PXENV_UNDI_TRANSMIT" ); 00237 00238 /* Forcibly enable interrupts at this point, to work around 00239 * callers that never call PXENV_UNDI_OPEN before attempting 00240 * to use the UNDI API. 00241 */ 00242 netdev_irq ( pxe_netdev, 1 ); 00243 00244 /* Identify network-layer protocol */ 00245 switch ( undi_transmit->Protocol ) { 00246 case P_IP: net_protocol = &ipv4_protocol; break; 00247 case P_ARP: net_protocol = &arp_protocol; break; 00248 case P_RARP: net_protocol = &rarp_protocol; break; 00249 case P_UNKNOWN: 00250 net_protocol = NULL; 00251 ll_hlen = 0; 00252 break; 00253 default: 00254 DBG2 ( " %02x invalid protocol\n", undi_transmit->Protocol ); 00255 undi_transmit->Status = PXENV_STATUS_UNDI_INVALID_PARAMETER; 00256 return PXENV_EXIT_FAILURE; 00257 } 00258 DBG2 ( " %s", ( net_protocol ? net_protocol->name : "RAW" ) ); 00259 00260 /* Calculate total packet length */ 00261 copy_from_real ( &tbd, undi_transmit->TBD.segment, 00262 undi_transmit->TBD.offset, sizeof ( tbd ) ); 00263 len = tbd.ImmedLength; 00264 DBG2 ( " %04x:%04x+%x", tbd.Xmit.segment, tbd.Xmit.offset, 00265 tbd.ImmedLength ); 00266 for ( i = 0 ; i < tbd.DataBlkCount ; i++ ) { 00267 datablk = &tbd.DataBlock[i]; 00268 len += datablk->TDDataLen; 00269 DBG2 ( " %04x:%04x+%x", datablk->TDDataPtr.segment, 00270 datablk->TDDataPtr.offset, datablk->TDDataLen ); 00271 } 00272 00273 /* Allocate and fill I/O buffer */ 00274 iobuf = alloc_iob ( ll_hlen + len ); 00275 if ( ! iobuf ) { 00276 DBG2 ( " could not allocate iobuf\n" ); 00277 undi_transmit->Status = PXENV_STATUS_OUT_OF_RESOURCES; 00278 return PXENV_EXIT_FAILURE; 00279 } 00280 iob_reserve ( iobuf, ll_hlen ); 00281 copy_from_real ( iob_put ( iobuf, tbd.ImmedLength ), tbd.Xmit.segment, 00282 tbd.Xmit.offset, tbd.ImmedLength ); 00283 for ( i = 0 ; i < tbd.DataBlkCount ; i++ ) { 00284 datablk = &tbd.DataBlock[i]; 00285 copy_from_real ( iob_put ( iobuf, datablk->TDDataLen ), 00286 datablk->TDDataPtr.segment, 00287 datablk->TDDataPtr.offset, 00288 datablk->TDDataLen ); 00289 } 00290 00291 /* Add link-layer header, if required to do so */ 00292 if ( net_protocol != NULL ) { 00293 00294 /* Calculate destination address */ 00295 if ( undi_transmit->XmitFlag == XMT_DESTADDR ) { 00296 copy_from_real ( destaddr, 00297 undi_transmit->DestAddr.segment, 00298 undi_transmit->DestAddr.offset, 00299 ll_protocol->ll_addr_len ); 00300 ll_dest = destaddr; 00301 DBG2 ( " DEST %s", ll_protocol->ntoa ( ll_dest ) ); 00302 } else { 00303 ll_dest = pxe_netdev->ll_broadcast; 00304 DBG2 ( " BCAST" ); 00305 } 00306 00307 /* Add link-layer header */ 00308 if ( ( rc = ll_protocol->push ( pxe_netdev, iobuf, ll_dest, 00309 pxe_netdev->ll_addr, 00310 net_protocol->net_proto ))!=0){ 00311 DBG2 ( " could not add link-layer header: %s\n", 00312 strerror ( rc ) ); 00313 free_iob ( iobuf ); 00314 undi_transmit->Status = PXENV_STATUS ( rc ); 00315 return PXENV_EXIT_FAILURE; 00316 } 00317 } 00318 00319 /* Flag transmission as in-progress. Do this before starting 00320 * to transmit the packet, because the ISR may trigger before 00321 * we return from netdev_tx(). 00322 */ 00323 undi_tx_count++; 00324 00325 /* Transmit packet */ 00326 DBG2 ( "\n" ); 00327 if ( ( rc = netdev_tx ( pxe_netdev, iobuf ) ) != 0 ) { 00328 DBG2 ( "PXENV_UNDI_TRANSMIT could not transmit: %s\n", 00329 strerror ( rc ) ); 00330 undi_tx_count--; 00331 undi_transmit->Status = PXENV_STATUS ( rc ); 00332 return PXENV_EXIT_FAILURE; 00333 } 00334 00335 undi_transmit->Status = PXENV_STATUS_SUCCESS; 00336 return PXENV_EXIT_SUCCESS; 00337 }
1.5.7.1